33- RFC PR: [ rust-lang/rfcs #3458 ] ( https://github.com/rust-lang/rfcs/pull/3458 )
44- Rust Issue: [ rust-lang/rust #132922 ] ( https://github.com/rust-lang/rust/issues/132922 )
55
6- # Summary
6+ ## Summary
77
88This RFC proposes extending Rust's tooling support for safety hygiene to named fields that carry
99library safety invariants. Consequently, Rust programmers will be able to use the ` unsafe ` keyword
@@ -25,7 +25,7 @@ accompanying safety documentation.
2525
2626[ `missing_safety_doc` ] : https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
2727
28- # Motivation
28+ ## Motivation
2929
3030Safety hygiene is the practice of denoting and documenting where memory safety obligations arise
3131and where they are discharged. Rust provides some tooling support for this practice. For example,
@@ -142,7 +142,7 @@ consider distant safe code. (See [*The Scope of Unsafe*].)
142142For crates that practice good safety hygiene, reviewers will mostly be able to limit their review
143143of distant routines to only ` unsafe ` code.
144144
145- # Guide-level explanation
145+ ## Guide-level explanation
146146
147147A safety invariant is any boolean statement about the computer at a time * t* , which should remain
148148true or else undefined behavior may arise. Language safety invariants are imposed by Rust
@@ -344,9 +344,9 @@ field in `ManuallyDrop`; e.g.:
344344 }
345345```
346346
347- ## When * Not* To Use Unsafe Fields
347+ ### When * Not* To Use Unsafe Fields
348348
349- ### Relaxing a Language Invariant
349+ #### Relaxing a Language Invariant
350350
351351The ` unsafe ` modifier is appropriate only for denoting * library* safety invariants. It has no impact
352352on * language* safety invariants, which must * never* be violated. This, for example, is an unsound
@@ -367,7 +367,7 @@ impl<T> Zeroed<T> {
367367
368368...because ` Zeroed::<NonZeroU8>::zeroed() ` induces undefined behavior.
369369
370- ### Denoting a Correctness Invariant
370+ #### Denoting a Correctness Invariant
371371
372372A library * correctness* invariant is an invariant imposed by an API whose violation must not result
373373in undefined behavior. In the below example, unsafe code may rely on ` alignment_pow ` s invariant,
@@ -398,7 +398,7 @@ We might also imagine a variant of the above example where `alignment_pow`, like
398398carry a safety invariant. Ultimately, whether or not it makes sense for a field to be ` unsafe ` is a
399399function of programmer preference and API requirements.
400400
401- ## Complete Example
401+ ### Complete Example
402402
403403The below example demonstrates how field safety support can be applied to build a practical
404404abstraction with small safety boundaries
@@ -518,9 +518,9 @@ impl<T> DerefMut for UniqueArc<T> {
518518}
519519```
520520
521- # Reference-level explanation
521+ ## Reference-level explanation
522522
523- ## Syntax
523+ ### Syntax
524524
525525The [ ` StructField ` syntax] [ struct syntax ] , used for the named fields of structs, enums, and unions,
526526shall be updated to accommodate an optional ` unsafe ` keyword just before the field ` IDENTIFIER ` :
@@ -538,13 +538,13 @@ StructField :
538538The use of unsafe fields on unions shall remain forbidden while the [ impact of this feature on
539539unions] ( #safe-unions ) is decided.
540540
541- ## Semantics
541+ ### Semantics
542542
543543Projections of fields marked ` unsafe ` must occur within the context of ` unsafe ` .
544544
545545Clippy's [ ` missing_safety_doc ` ] lint ensures such fields have accompanying safety documentation.
546546
547- # Rationale and Alternatives
547+ ## Rationale and Alternatives
548548
549549The design of this proposal is primarily guided by three tenets:
550550
@@ -562,7 +562,7 @@ This RFC prioritizes the first two tenets before the third. We believe that the
562562broader utility, more consistent tooling, and a simplified safety hygiene story — outweigh its
563563cost, [ alarm fatigue] ( #alarm-fatigue ) . The third tenet implores us to weigh this cost.
564564
565- ## Tenet: Unsafe Fields Denote Safety Invariants
565+ ### Tenet: Unsafe Fields Denote Safety Invariants
566566
567567> A field * should* be marked ` unsafe ` if it carries library safety invariants.
568568
@@ -573,7 +573,7 @@ conditional on upholding safety invariants; for example:
573573- An ` unsafe ` trait denotes that it carries safety invariants that must be upheld by implementors.
574574- An ` unsafe ` function denotes that it carries safety invariants that must be upheld by callers.
575575
576- ## Tenet: Unsafe Usage is Always Unsafe
576+ ### Tenet: Unsafe Usage is Always Unsafe
577577
578578> Uses of ` unsafe ` fields that could violate their invariants * must* occur in the scope of an
579579> ` unsafe ` block.
@@ -584,7 +584,7 @@ imposes when applied to other declarations; for example:
584584- An ` unsafe ` trait may only be implemented with an ` unsafe impl ` .
585585- An ` unsafe ` function is only callable in the scope of an ` unsafe ` block.
586586
587- ## Tenet: Safe Usage is Usually Safe
587+ ### Tenet: Safe Usage is Usually Safe
588588
589589> Uses of ` unsafe ` fields that cannot violate their invariants * should not* require an unsafe block.
590590
@@ -593,12 +593,12 @@ experience of practicing it. We adopt this tenet as a forcing function between d
593593our first two tenets. All else being equal, we give priority to designs that minimize the needless
594594use of ` unsafe ` .
595595
596- ## Alternatives
596+ ### Alternatives
597597
598598These tenets effectively constrain the design space of tooling for field safety hygiene; the
599599alternatives we have considered conflict with one or more of these tenets.
600600
601- ### Unsafe Variants
601+ #### Unsafe Variants
602602
603603We propose that the ` unsafe ` keyword be applicable on a per-field basis. Alternatively, we can
604604imagine it being applied on a per-constructor basis; e.g.:
@@ -629,7 +629,7 @@ variants are conceptually unsafe, requiring the programmer to use `unsafe` even
629629of 'safe' fields. This violates [ * Tenet: Safe Usage is Usually
630630Safe* ] ( #tenet-safe-usage-is-usually-safe ) .
631631
632- ### Field Moving is Safe
632+ #### Field Moving is Safe
633633
634634We propose that all uses of ` unsafe ` fields require ` unsafe ` , including reading. Alternatively, we
635635might consider making reads safe. However, a field may carry an invariant that would be violated by
@@ -654,7 +654,7 @@ documents its safety conditions as they relate to `KeepAlive`), rather than in d
654654interactions with ` UnsafeCell<T> ` (whose methods necessarily provide only general guidance).
655655Consequently, we require that moving unsafe fields out of their enclosing type requires ` unsafe ` .
656656
657- ### Field Copying is Safe
657+ #### Field Copying is Safe
658658
659659We propose that all uses of unsafe fields require ` unsafe ` , including copying. Alternatively, we
660660might consider making field copies safe. However, a field may carry an invariant that could be
@@ -663,7 +663,7 @@ imposes an invariant on the value of `T`. In this alternative proposal, such a f
663663copiable out of its enclosing type, then safely mutated via the API of ` RefCell ` . Consequently, we
664664require that copying unsafe fields out of their enclosing type requires ` unsafe ` .
665665
666- ### Copy Is Safe To Implement
666+ #### Copy Is Safe To Implement
667667
668668We propose that ` Copy ` is conditionally unsafe to implement; i.e., that the ` unsafe ` modifier is
669669required to implement ` Copy ` for types that have unsafe fields. Alternatively, we can imagine
@@ -692,7 +692,7 @@ However, the `ptr` field introduces a declaration-site safety obligation that is
692692with ` unsafe ` at any use site; this violates [ ** Tenet: Unsafe Usage is Always
693693Unsafe** ] ( #tenet-unsafe-usage-is-always-unsafe ) .
694694
695- ### Nontrivial Destructors are Prohibited
695+ #### Nontrivial Destructors are Prohibited
696696
697697If a programmer applies the ` unsafe ` modifier to a field with a nontrivial destructor and relaxes
698698its invariant beyond that required by the field's destructor, Rust cannot prevent the
@@ -758,7 +758,7 @@ Unsafe Fields Denote Safety Invariants**](#tenet-unsafe-fields-denote-safety-inv
758758requiring trivially ` unsafe ` drop glue), a violation of [ ** Tenet: Safe Usage is Usually
759759Safe** ] ( #tenet-safe-usage-is-usually-safe ) .
760760
761- ### Unsafe Wrapper Type
761+ #### Unsafe Wrapper Type
762762
763763This RFC proposes extending the Rust language with first-class support for field (un)safety.
764764Alternatively, we could attempt to achieve the same effects by leveraging Rust's existing visibility
@@ -840,7 +840,7 @@ exchanging the `len`s of two instances of the aforementioned `Vec`).
840840
841841These challenges motivate first-class support for field safety tooling.
842842
843- ### More Syntactic Granularity
843+ #### More Syntactic Granularity
844844
845845This RFC proposes the rule that * a field marked ` unsafe ` is unsafe to use* . This rule is flexible
846846enough to handle arbitrary field invariants, but — in some scenarios — requires that the user write
@@ -900,7 +900,7 @@ marked `unsafe` is unsafe to use* is both pedagogically simple and failsafe; i.e
900900field is marked ` unsafe ` , it cannot be misused in such a way that its invariant is violated in safe
901901code.
902902
903- ### Mixing Syntactic Knobs with a Wrapper Type
903+ #### Mixing Syntactic Knobs with a Wrapper Type
904904
905905One alternative proposed in this RFC's discussion recommends a combination of syntactic knobs and a
906906wrapper type. In brief, a simple [ ` Unsafe ` wrapper type] ( #unsafe-wrapper-type ) would be provided,
@@ -930,9 +930,9 @@ field so that field's safety documentation may be examined.
930930Comparatively, we believe that this RFC's proposal is both pedagogically simpler and less prone to
931931misuse, and that these benefits outweigh its [ drawbacks] ( #drawbacks ) .
932932
933- # Drawbacks
933+ ## Drawbacks
934934
935- ## Trivial Safety Proofs
935+ ### Trivial Safety Proofs
936936
937937The primary drawback of this proposal is that it — in some scenarios — necessitates writing
938938'trivial' safety proofs. For example, merely reading ` Vec ` 's ` len ` field obviously cannot invalidate
@@ -956,19 +956,19 @@ but **not** *must* — denote field safety invariants with the `unsafe` keyword.
956956soundness nor security issue to continue to adhere to the current convention of using visibility to
957957enforce field safety invariants.
958958
959- # Prior art
959+ ## Prior art
960960
961961Some items in the Rust standard library have ` #[rustc_layout_scalar_valid_range_start] ` ,
962962` #[rustc_layout_scalar_valid_range_end] ` , or both. These items have identical behavior to that of
963963unsafe fields described here. It is likely (though not required by this RFC) that these items will
964964be required to use unsafe fields, which would reduce special-casing of the standard library.
965965
966- # Unresolved questions
966+ ## Unresolved questions
967967
968968- If the syntax for restrictions does not change, what is the ordering of keywords on a field that
969969 is both unsafe and mut-restricted?
970970
971- ## Terminology
971+ ### Terminology
972972
973973This RFC defines three terms of art: * safety invariant* , * library safety invariant* , and * language
974974safety invariant* . The meanings of these terms are not original to this RFC, and the question of
@@ -977,9 +977,9 @@ debated](https://github.com/rust-lang/unsafe-code-guidelines/issues/539). This R
977977prescribe its terminology. Documentation of the unsafe fields tooling should reflect broader
978978consensus, once that consensus is reached.
979979
980- # Future possibilities
980+ ## Future possibilities
981981
982- ## Partial Borrows
982+ ### Partial Borrows
983983
984984The primary drawback of this proposal is that it — in some scenarios — necessitates writing
985985'trivial' safety proofs. For example, merely reading ` Vec ` 's ` len ` field obviously cannot invalidate
@@ -990,7 +990,7 @@ maintainer can define a *safe* accessor (i.e.,
990990proof. However, in cases where multiple, partial field borrows are required, such an accessor cannot
991991be invoked. Future language extensions that permit partial borrows will resolve this drawback.
992992
993- ## Syntactic Knobs and Wrapper Types
993+ ### Syntactic Knobs and Wrapper Types
994994
995995While we are confident that this RFC has the best tradeoffs among the alternatives in the design
996996space, it is not a one-way door. Changes to the default semantics of ` unsafe ` could be realized over
@@ -1000,7 +1000,7 @@ knobs](#more-syntactic-granularity) and [wrapper types](#unsafe-wrapper-type). F
10001000addition to this RFC's ` unsafe ` modifier, additional variants in the form ` unsafe(<modifiers>) `
10011001(e.g., ` unsafe(mut) ` ) could be added to denote that some subset of uses is always safe.
10021002
1003- ## Safe Unions
1003+ ### Safe Unions
10041004
10051005Today, unions provide language support for fields with subtractive * language* invariants. Unions may
10061006be safely defined, constructed and mutated — but require unsafe to read. Consequently, it is
0 commit comments