|
| 1 | +use crate::field::Projection; |
| 2 | + |
| 3 | +/// Marks a type as containing a place. |
| 4 | +/// |
| 5 | +/// This is the new trait for the dereference operator `*`; implementing it will allow writing `*x` |
| 6 | +/// for `x: Self`, but not enable any operations on `*x`. For those, one of the other place |
| 7 | +/// operation traits has to be implemented: |
| 8 | +/// |
| 9 | +/// - [`PlaceRead`] |
| 10 | +/// - [`PlaceWrite`] |
| 11 | +/// - [`PlaceDrop`] |
| 12 | +/// - [`PlaceMove`] |
| 13 | +/// - [`PlaceBorrow`] |
| 14 | +/// - [`PlaceDeref`] |
| 15 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 16 | +#[lang = "has_place"] |
| 17 | +pub trait HasPlace { |
| 18 | + /// The type of the contained place. |
| 19 | + #[lang = "has_place_target"] |
| 20 | + type Target: ?Sized; |
| 21 | +} |
| 22 | + |
| 23 | +/// Reading a place `let val = *x;`. |
| 24 | +/// |
| 25 | +/// When `x: Self`, then `let val = *x;` will be desugared into [`PlaceRead::read`]. |
| 26 | +/// |
| 27 | +/// # Safety |
| 28 | +/// |
| 29 | +/// FIXME |
| 30 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 31 | +#[lang = "place_read"] |
| 32 | +pub unsafe trait PlaceRead<P>: HasPlace |
| 33 | +where |
| 34 | + P: Projection<Source = Self::Target>, |
| 35 | +{ |
| 36 | + /// Whether the read operation is safe when used through the operator. |
| 37 | + /// |
| 38 | + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other |
| 39 | + /// operation is conflicting with this one. |
| 40 | + #[lang = "place_read_safety"] |
| 41 | + const SAFETY: bool; |
| 42 | + |
| 43 | + /// Read the `proj` subplace of the place pointed to by `this`. |
| 44 | + /// |
| 45 | + /// # Safety |
| 46 | + /// |
| 47 | + /// FIXME |
| 48 | + #[lang = "place_read_read"] |
| 49 | + unsafe fn read(this: *const Self, proj: P) -> P::Target; |
| 50 | +} |
| 51 | + |
| 52 | +/// Writing a place `*x = val;`. |
| 53 | +/// |
| 54 | +/// When `x: Self`, then `*x = val;` will be desugared into [`PlaceWrite::write`]. |
| 55 | +/// |
| 56 | +/// # Safety |
| 57 | +/// |
| 58 | +/// FIXME |
| 59 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 60 | +#[lang = "place_write"] |
| 61 | +pub unsafe trait PlaceWrite<P>: HasPlace |
| 62 | +where |
| 63 | + P: Projection<Source = Self::Target>, |
| 64 | +{ |
| 65 | + /// Whether the write operation is safe when used through the operator. |
| 66 | + /// |
| 67 | + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other |
| 68 | + /// operation is conflicting with this one. |
| 69 | + #[lang = "place_write_safety"] |
| 70 | + const SAFETY: bool; |
| 71 | + |
| 72 | + /// Write to the `proj` subplace of the place pointed to by `this`. |
| 73 | + /// |
| 74 | + /// # Safety |
| 75 | + /// |
| 76 | + /// FIXME |
| 77 | + #[lang = "place_write_write"] |
| 78 | + unsafe fn write(this: *const Self, proj: P, value: P::Target); |
| 79 | +} |
| 80 | + |
| 81 | +/// Moving out of a place. |
| 82 | +/// |
| 83 | +/// When `x: Self` and one performs a [`PlaceRead::read`] where the target value is not [`Copy`], |
| 84 | +/// then the compiler checks if this trait is implemented and if so, moves the value out by reading |
| 85 | +/// it and adjusting the borrow checker state of the place. |
| 86 | +/// |
| 87 | +/// # Safety |
| 88 | +/// |
| 89 | +/// FIXME |
| 90 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 91 | +#[lang = "place_move"] |
| 92 | +pub unsafe trait PlaceMove<P>: PlaceRead<P> |
| 93 | +where |
| 94 | + P: Projection<Source = Self::Target>, |
| 95 | +{ |
| 96 | +} |
| 97 | + |
| 98 | +/// Dropping a place. |
| 99 | +/// |
| 100 | +/// Emitted by the compiler when a place has been partially moved out and the pointer with ownership |
| 101 | +/// is being dropped. |
| 102 | +/// |
| 103 | +/// # Safety |
| 104 | +/// |
| 105 | +/// FIXME |
| 106 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 107 | +#[lang = "place_drop"] |
| 108 | +pub unsafe trait PlaceDrop<P>: HasPlace |
| 109 | +where |
| 110 | + P: Projection<Source = Self::Target>, |
| 111 | +{ |
| 112 | + /// Drop the `proj` subplace of the place pointed to by `this`. |
| 113 | + /// |
| 114 | + /// # Safety |
| 115 | + /// |
| 116 | + /// FIXME |
| 117 | + #[lang = "place_drop_drop"] |
| 118 | + unsafe fn drop(this: *const Self, proj: P); |
| 119 | +} |
| 120 | + |
| 121 | +/// Dropping a pointer that points at a fully moved-out place. |
| 122 | +/// |
| 123 | +/// This operation is emitted by the compiler when a pointer is being dropped that had some fields |
| 124 | +/// moved out. |
| 125 | +/// |
| 126 | +/// # Safety |
| 127 | +/// |
| 128 | +/// FIXME |
| 129 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 130 | +#[lang = "drop_husk"] |
| 131 | +pub unsafe trait DropHusk: HasPlace { |
| 132 | + /// Drops the |
| 133 | + /// |
| 134 | + /// # Safety |
| 135 | + /// |
| 136 | + /// FIXME |
| 137 | + #[lang = "drop_husk_drop_husk"] |
| 138 | + unsafe fn drop_husk(this: *const Self); |
| 139 | +} |
| 140 | + |
| 141 | +/// Borrowing a place with `X`. |
| 142 | +/// |
| 143 | +/// When `y: Self`, then `let x = @<X> *y;` will be desugared into [`PlaceBorrow::borrow`]. |
| 144 | +/// |
| 145 | +/// # Safety |
| 146 | +/// |
| 147 | +/// FIXME |
| 148 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 149 | +#[lang = "place_borrow"] |
| 150 | +pub unsafe trait PlaceBorrow<P, X>: HasPlace |
| 151 | +where |
| 152 | + P: Projection<Source = Self::Target>, |
| 153 | + X: HasPlace<Target = P::Target>, |
| 154 | +{ |
| 155 | + /// Whether the borrow operation is safe when used through the operator. |
| 156 | + /// |
| 157 | + /// When the compiler emits the call to `read`, the borrow checker guarantees that no other |
| 158 | + /// operation is conflicting with this one. |
| 159 | + #[lang = "place_borrow_safety"] |
| 160 | + const SAFETY: bool; |
| 161 | + |
| 162 | + /// Borrow the `proj` subplace of the place pointed to by `this` with `X`. |
| 163 | + /// |
| 164 | + /// # Safety |
| 165 | + /// |
| 166 | + /// FIXME |
| 167 | + #[lang = "place_borrow_borrow"] |
| 168 | + unsafe fn borrow(this: *const Self, proj: P) -> X; |
| 169 | +} |
| 170 | + |
| 171 | +/// Accessing a nested pointer. |
| 172 | +/// |
| 173 | +/// When `x: Self`, then nested dereferences `let _ = **x;` is desugared into a combination of the |
| 174 | +/// corresponding operation and a [`PlaceDeref::deref`]. |
| 175 | +/// |
| 176 | +/// # Safety |
| 177 | +/// |
| 178 | +/// FIXME |
| 179 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 180 | +#[lang = "place_deref"] |
| 181 | +pub unsafe trait PlaceDeref<P>: HasPlace |
| 182 | +where |
| 183 | + P: Projection<Source = Self::Target>, |
| 184 | + P::Target: HasPlace, |
| 185 | +{ |
| 186 | + /// Obtain a raw pointer to the `proj` subplace of the place pointed to by `this`. |
| 187 | + /// |
| 188 | + /// # Safety |
| 189 | + /// |
| 190 | + /// FIXME |
| 191 | + #[lang = "place_deref_deref"] |
| 192 | + unsafe fn deref(ptr: *mut Self, proj: P) -> *const P::Target; |
| 193 | +} |
| 194 | + |
| 195 | +/// Forwards the subplace `P` of the place contained by this. |
| 196 | +/// |
| 197 | +/// When `x: Self` and `Self::Target` has a subplace `P` accessible via `.proj`, then `x.proj` also |
| 198 | +/// exists, has type `<Self::WrappedProjection as Projection>::Target` and any place operation on it |
| 199 | +/// uses <code>[Self::wrap_projection]\(proj\)</code> as the subplace. |
| 200 | +/// |
| 201 | +/// # Safety |
| 202 | +/// |
| 203 | +/// FIXME |
| 204 | +#[unstable(feature = "field_projections", issue = "145383")] |
| 205 | +#[lang = "place_wrapper"] |
| 206 | +pub unsafe trait PlaceWrapper<P>: HasPlace |
| 207 | +where |
| 208 | + P: Projection<Source = Self::Target>, |
| 209 | +{ |
| 210 | + /// The projection to use instead of `P`. |
| 211 | + #[lang = "place_wrapper_wrapped_projection"] |
| 212 | + type WrappedProjection: Projection<Source = Self>; |
| 213 | + |
| 214 | + /// Turn a projection of type `P` into [`Self::WrappedProjection`]. |
| 215 | + #[lang = "place_wrapper_wrap_projection"] |
| 216 | + fn wrap_projection(proj: P) -> Self::WrappedProjection; |
| 217 | +} |
0 commit comments