|
57 | 57 | //! [`NonNull::dangling`] in such cases.
|
58 | 58 | //!
|
59 | 59 | //! ## Pointer to reference conversion
|
60 |
| -//! When converting a pointer to a reference `&T` using `&*`, |
| 60 | +//! |
| 61 | +//! When converting a pointer to a reference (e.g. via `&*ptr` or `&mut *ptr`), |
61 | 62 | //! there are several rules that must be followed:
|
62 | 63 | //!
|
63 | 64 | //! * The pointer must be properly aligned.
|
64 | 65 | //!
|
65 |
| -// some microprocessors may use address 0 for an interrupt vector. |
66 |
| -// users of these microprocessors must always read/write address 0 through |
67 |
| -// a raw pointer, not a reference. |
68 | 66 | //! * It must be non-null.
|
69 | 67 | //!
|
70 | 68 | //! * It must be "dereferenceable" in the sense defined above.
|
71 | 69 | //!
|
72 |
| -//! * The pointer must point to a valid value of type `T`. |
73 |
| -//! This means that the created reference can only refer to |
74 |
| -//! uninitialized memory through careful use of `MaybeUninit`, |
75 |
| -//! or if the uninitialized memory is entirely contained within |
76 |
| -//! padding bytes, since |
77 |
| -//! [padding has the same validity invariant as `MaybeUninit`][ucg-pad]. |
78 |
| -//! |
79 |
| -//! * You must enforce Rust's aliasing rules, since the lifetime of the |
80 |
| -//! created reference is arbitrarily chosen, |
81 |
| -//! and does not necessarily reflect the actual lifetime of the data. |
82 |
| -//! In particular, while this reference exists, |
83 |
| -//! the memory the pointer points to must |
84 |
| -//! not get accessed (read or written) through any raw pointer, |
85 |
| -//! except for data inside an `UnsafeCell`. |
86 |
| -//! Note that aliased writes are always UB for mutable references, |
87 |
| -//! even if they only modify `UnsafeCell` data. |
| 70 | +//! * The pointer must point to a [valid value] of type `T`. |
| 71 | +//! |
| 72 | +//! * You must enforce Rust's aliasing rules. The exact aliasing rules are not decided yet, so we |
| 73 | +//! only give a rough overview here. The rules also depend on whether a mutable or a shared |
| 74 | +//! reference is being created. |
| 75 | +//! * When creating a mutable reference, then while this reference exists, the memory it points to |
| 76 | +//! must not get accessed (read or written) through any other pointer or reference not derived |
| 77 | +//! from this reference. |
| 78 | +//! * When creating a shared reference, then while this reference exists, the memory it points to |
| 79 | +//! must not get mutated (except inside `UnsafeCell`). |
88 | 80 | //!
|
89 | 81 | //! If a pointer follows all of these rules, it is said to be
|
90 |
| -//! *convertible to a reference*. |
| 82 | +//! *convertible to a (mutable or shared) reference*. |
91 | 83 | // ^ we use this term instead of saying that the produced reference must
|
92 | 84 | // be valid, as the validity of a reference is easily confused for the
|
93 | 85 | // validity of the thing it refers to, and while the two concepts are
|
94 | 86 | // closly related, they are not identical.
|
95 | 87 | //!
|
96 |
| -//! These apply even if the result is unused! |
| 88 | +//! These rules apply even if the result is unused! |
97 | 89 | //! (The part about being initialized is not yet fully decided, but until
|
98 | 90 | //! it is, the only safe approach is to ensure that they are indeed initialized.)
|
99 | 91 | //!
|
100 | 92 | //! An example of the implications of the above rules is that an expression such
|
101 | 93 | //! as `unsafe { &*(0 as *const u8) }` is Immediate Undefined Behavior.
|
102 | 94 | //!
|
103 |
| -//! [ucgpad]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#padding |
| 95 | +//! [valid value]: ../../reference/behavior-considered-undefined.html#invalid-values |
104 | 96 | //!
|
105 | 97 | //! ## Allocated object
|
106 | 98 | //!
|
|
0 commit comments