@@ -1131,213 +1131,3 @@ pub trait FnPtr: Copy + Clone {
1131
1131
#[ lang = "fn_ptr_addr" ]
1132
1132
fn addr ( self ) -> * const ( ) ;
1133
1133
}
1134
-
1135
- /// Derive macro that makes a smart pointer usable with trait objects.
1136
- ///
1137
- /// # What this macro does
1138
- ///
1139
- /// This macro is intended to be used with user-defined pointer types, and makes it possible to
1140
- /// perform coercions on the pointee of the user-defined pointer. There are two aspects to this:
1141
- ///
1142
- /// ## Unsizing coercions of the pointee
1143
- ///
1144
- /// By using the macro, the following example will compile:
1145
- /// ```
1146
- /// #![feature(derive_coerce_pointee)]
1147
- /// use std::marker::CoercePointee;
1148
- /// use std::ops::Deref;
1149
- ///
1150
- /// #[derive(CoercePointee)]
1151
- /// #[repr(transparent)]
1152
- /// struct MySmartPointer<T: ?Sized>(Box<T>);
1153
- ///
1154
- /// impl<T: ?Sized> Deref for MySmartPointer<T> {
1155
- /// type Target = T;
1156
- /// fn deref(&self) -> &T {
1157
- /// &self.0
1158
- /// }
1159
- /// }
1160
- ///
1161
- /// trait MyTrait {}
1162
- ///
1163
- /// impl MyTrait for i32 {}
1164
- ///
1165
- /// fn main() {
1166
- /// let ptr: MySmartPointer<i32> = MySmartPointer(Box::new(4));
1167
- ///
1168
- /// // This coercion would be an error without the derive.
1169
- /// let ptr: MySmartPointer<dyn MyTrait> = ptr;
1170
- /// }
1171
- /// ```
1172
- /// Without the `#[derive(CoercePointee)]` macro, this example would fail with the following error:
1173
- /// ```text
1174
- /// error[E0308]: mismatched types
1175
- /// --> src/main.rs:11:44
1176
- /// |
1177
- /// 11 | let ptr: MySmartPointer<dyn MyTrait> = ptr;
1178
- /// | --------------------------- ^^^ expected `MySmartPointer<dyn MyTrait>`, found `MySmartPointer<i32>`
1179
- /// | |
1180
- /// | expected due to this
1181
- /// |
1182
- /// = note: expected struct `MySmartPointer<dyn MyTrait>`
1183
- /// found struct `MySmartPointer<i32>`
1184
- /// = help: `i32` implements `MyTrait` so you could box the found value and coerce it to the trait object `Box<dyn MyTrait>`, you will have to change the expected type as well
1185
- /// ```
1186
- ///
1187
- /// ## Dyn compatibility
1188
- ///
1189
- /// This macro allows you to dispatch on the user-defined pointer type. That is, traits using the
1190
- /// type as a receiver are dyn-compatible. For example, this compiles:
1191
- ///
1192
- /// ```
1193
- /// #![feature(arbitrary_self_types, derive_coerce_pointee)]
1194
- /// use std::marker::CoercePointee;
1195
- /// use std::ops::Deref;
1196
- ///
1197
- /// #[derive(CoercePointee)]
1198
- /// #[repr(transparent)]
1199
- /// struct MySmartPointer<T: ?Sized>(Box<T>);
1200
- ///
1201
- /// impl<T: ?Sized> Deref for MySmartPointer<T> {
1202
- /// type Target = T;
1203
- /// fn deref(&self) -> &T {
1204
- /// &self.0
1205
- /// }
1206
- /// }
1207
- ///
1208
- /// // You can always define this trait. (as long as you have #![feature(arbitrary_self_types)])
1209
- /// trait MyTrait {
1210
- /// fn func(self: MySmartPointer<Self>);
1211
- /// }
1212
- ///
1213
- /// // But using `dyn MyTrait` requires #[derive(CoercePointee)].
1214
- /// fn call_func(value: MySmartPointer<dyn MyTrait>) {
1215
- /// value.func();
1216
- /// }
1217
- /// ```
1218
- /// If you remove the `#[derive(CoercePointee)]` annotation from the struct, then the above example
1219
- /// will fail with this error message:
1220
- /// ```text
1221
- /// error[E0038]: the trait `MyTrait` is not dyn compatible
1222
- /// --> src/lib.rs:21:36
1223
- /// |
1224
- /// 17 | fn func(self: MySmartPointer<Self>);
1225
- /// | -------------------- help: consider changing method `func`'s `self` parameter to be `&self`: `&Self`
1226
- /// ...
1227
- /// 21 | fn call_func(value: MySmartPointer<dyn MyTrait>) {
1228
- /// | ^^^^^^^^^^^ `MyTrait` is not dyn compatible
1229
- /// |
1230
- /// note: for a trait to be dyn compatible it needs to allow building a vtable
1231
- /// for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
1232
- /// --> src/lib.rs:17:19
1233
- /// |
1234
- /// 16 | trait MyTrait {
1235
- /// | ------- this trait is not dyn compatible...
1236
- /// 17 | fn func(self: MySmartPointer<Self>);
1237
- /// | ^^^^^^^^^^^^^^^^^^^^ ...because method `func`'s `self` parameter cannot be dispatched on
1238
- /// ```
1239
- ///
1240
- /// # Requirements for using the macro
1241
- ///
1242
- /// This macro can only be used if:
1243
- /// * The type is a `#[repr(transparent)]` struct.
1244
- /// * The type of its non-zero-sized field must either be a standard library pointer type
1245
- /// (reference, raw pointer, `NonNull`, `Box`, `Rc`, `Arc`, etc.) or another user-defined type
1246
- /// also using the `#[derive(CoercePointee)]` macro.
1247
- /// * Zero-sized fields must not mention any generic parameters unless the zero-sized field has
1248
- /// type [`PhantomData`].
1249
- ///
1250
- /// ## Multiple type parameters
1251
- ///
1252
- /// If the type has multiple type parameters, then you must explicitly specify which one should be
1253
- /// used for dynamic dispatch. For example:
1254
- /// ```
1255
- /// # #![feature(derive_coerce_pointee)]
1256
- /// # use std::marker::{CoercePointee, PhantomData};
1257
- /// #[derive(CoercePointee)]
1258
- /// #[repr(transparent)]
1259
- /// struct MySmartPointer<#[pointee] T: ?Sized, U> {
1260
- /// ptr: Box<T>,
1261
- /// _phantom: PhantomData<U>,
1262
- /// }
1263
- /// ```
1264
- /// Specifying `#[pointee]` when the struct has only one type parameter is allowed, but not required.
1265
- ///
1266
- /// # Examples
1267
- ///
1268
- /// A custom implementation of the `Rc` type:
1269
- /// ```
1270
- /// #![feature(derive_coerce_pointee)]
1271
- /// use std::marker::CoercePointee;
1272
- /// use std::ops::Deref;
1273
- /// use std::ptr::NonNull;
1274
- ///
1275
- /// #[derive(CoercePointee)]
1276
- /// #[repr(transparent)]
1277
- /// pub struct Rc<T: ?Sized> {
1278
- /// inner: NonNull<RcInner<T>>,
1279
- /// }
1280
- ///
1281
- /// struct RcInner<T: ?Sized> {
1282
- /// refcount: usize,
1283
- /// value: T,
1284
- /// }
1285
- ///
1286
- /// impl<T: ?Sized> Deref for Rc<T> {
1287
- /// type Target = T;
1288
- /// fn deref(&self) -> &T {
1289
- /// let ptr = self.inner.as_ptr();
1290
- /// unsafe { &(*ptr).value }
1291
- /// }
1292
- /// }
1293
- ///
1294
- /// impl<T> Rc<T> {
1295
- /// pub fn new(value: T) -> Self {
1296
- /// let inner = Box::new(RcInner {
1297
- /// refcount: 1,
1298
- /// value,
1299
- /// });
1300
- /// Self {
1301
- /// inner: NonNull::from(Box::leak(inner)),
1302
- /// }
1303
- /// }
1304
- /// }
1305
- ///
1306
- /// impl<T: ?Sized> Clone for Rc<T> {
1307
- /// fn clone(&self) -> Self {
1308
- /// // A real implementation would handle overflow here.
1309
- /// unsafe { (*self.inner.as_ptr()).refcount += 1 };
1310
- /// Self { inner: self.inner }
1311
- /// }
1312
- /// }
1313
- ///
1314
- /// impl<T: ?Sized> Drop for Rc<T> {
1315
- /// fn drop(&mut self) {
1316
- /// let ptr = self.inner.as_ptr();
1317
- /// unsafe { (*ptr).refcount -= 1 };
1318
- /// if unsafe { (*ptr).refcount } == 0 {
1319
- /// drop(unsafe { Box::from_raw(ptr) });
1320
- /// }
1321
- /// }
1322
- /// }
1323
- /// ```
1324
- #[ rustc_builtin_macro( CoercePointee , attributes( pointee) ) ]
1325
- #[ allow_internal_unstable( dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated) ]
1326
- #[ rustc_diagnostic_item = "CoercePointee" ]
1327
- #[ unstable( feature = "derive_coerce_pointee" , issue = "123430" ) ]
1328
- pub macro CoercePointee ( $item: item) {
1329
- /* compiler built-in */
1330
- }
1331
-
1332
- /// A trait that is implemented for ADTs with `derive(CoercePointee)` so that
1333
- /// the compiler can enforce the derive impls are valid post-expansion, since
1334
- /// the derive has stricter requirements than if the impls were written by hand.
1335
- ///
1336
- /// This trait is not intended to be implemented by users or used other than
1337
- /// validation, so it should never be stabilized.
1338
- #[ lang = "coerce_pointee_validated" ]
1339
- #[ unstable( feature = "coerce_pointee_validated" , issue = "none" ) ]
1340
- #[ doc( hidden) ]
1341
- pub trait CoercePointeeValidated {
1342
- /* compiler built-in */
1343
- }
0 commit comments