@@ -1091,7 +1091,195 @@ pub trait FnPtr: Copy + Clone {
10911091    fn  addr ( self )  -> * const  ( ) ; 
10921092} 
10931093
1094- /// Derive macro generating impls of traits related to smart pointers. 
1094+ /// Derive macro that makes a smart pointer usable with trait objects. 
1095+ /// 
1096+ /// # What this macro does 
1097+ /// 
1098+ /// This macro is intended to be used with user-defined pointer types, and makes it possible to 
1099+ /// perform coercions on the pointee of the user-defined pointer. There are two aspects to this: 
1100+ /// 
1101+ /// ## Unsizing coercions of the pointee 
1102+ /// 
1103+ /// By using the macro, the following example will compile: 
1104+ /// ``` 
1105+ /// #![feature(derive_coerce_pointee)] 
1106+ /// use std::marker::CoercePointee; 
1107+ /// use std::ops::Deref; 
1108+ /// 
1109+ /// #[derive(CoercePointee)] 
1110+ /// #[repr(transparent)] 
1111+ /// struct MySmartPointer<T: ?Sized>(Box<T>); 
1112+ /// 
1113+ /// impl<T: ?Sized> Deref for MySmartPointer<T> { 
1114+ ///     type Target = T; 
1115+ ///     fn deref(&self) -> &T { 
1116+ ///         &self.0 
1117+ ///     } 
1118+ /// } 
1119+ /// 
1120+ /// trait MyTrait {} 
1121+ /// 
1122+ /// impl MyTrait for i32 {} 
1123+ /// 
1124+ /// fn main() { 
1125+ ///     let ptr: MySmartPointer<i32> = MySmartPointer(Box::new(4)); 
1126+ /// 
1127+ ///     // This coercion would be an error without the derive. 
1128+ ///     let ptr: MySmartPointer<dyn MyTrait> = ptr; 
1129+ /// } 
1130+ /// ``` 
1131+ /// Without the `#[derive(CoercePointee)]` macro, this example would fail with the following error: 
1132+ /// ```text 
1133+ /// error[E0308]: mismatched types 
1134+ ///   --> src/main.rs:11:44 
1135+ ///    | 
1136+ /// 11 |     let ptr: MySmartPointer<dyn MyTrait> = ptr; 
1137+ ///    |              ---------------------------   ^^^ expected `MySmartPointer<dyn MyTrait>`, found `MySmartPointer<i32>` 
1138+ ///    |              | 
1139+ ///    |              expected due to this 
1140+ ///    | 
1141+ ///    = note: expected struct `MySmartPointer<dyn MyTrait>` 
1142+ ///               found struct `MySmartPointer<i32>` 
1143+ ///    = 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 
1144+ /// ``` 
1145+ /// 
1146+ /// ## Dyn compatibility 
1147+ /// 
1148+ /// This macro allows you to dispatch on the user-defined pointer type. That is, traits using the 
1149+ /// type as a receiver are dyn-compatible. For example, this compiles: 
1150+ /// 
1151+ /// ``` 
1152+ /// #![feature(arbitrary_self_types, derive_coerce_pointee)] 
1153+ /// use std::marker::CoercePointee; 
1154+ /// use std::ops::Deref; 
1155+ /// 
1156+ /// #[derive(CoercePointee)] 
1157+ /// #[repr(transparent)] 
1158+ /// struct MySmartPointer<T: ?Sized>(Box<T>); 
1159+ /// 
1160+ /// impl<T: ?Sized> Deref for MySmartPointer<T> { 
1161+ ///     type Target = T; 
1162+ ///     fn deref(&self) -> &T { 
1163+ ///         &self.0 
1164+ ///     } 
1165+ /// } 
1166+ /// 
1167+ /// // You can always define this trait. (as long as you have #![feature(arbitrary_self_types)]) 
1168+ /// trait MyTrait { 
1169+ ///     fn func(self: MySmartPointer<Self>); 
1170+ /// } 
1171+ /// 
1172+ /// // But using `dyn MyTrait` requires #[derive(CoercePointee)]. 
1173+ /// fn call_func(value: MySmartPointer<dyn MyTrait>) { 
1174+ ///     value.func(); 
1175+ /// } 
1176+ /// ``` 
1177+ /// If you remove the `#[derive(CoercePointee)]` annotation from the struct, then the above example 
1178+ /// will fail with this error message: 
1179+ /// ```text 
1180+ /// error[E0038]: the trait `MyTrait` is not dyn compatible 
1181+ ///   --> src/lib.rs:21:36 
1182+ ///    | 
1183+ /// 17 |     fn func(self: MySmartPointer<Self>); 
1184+ ///    |                   -------------------- help: consider changing method `func`'s `self` parameter to be `&self`: `&Self` 
1185+ /// ... 
1186+ /// 21 | fn call_func(value: MySmartPointer<dyn MyTrait>) { 
1187+ ///    |                                    ^^^^^^^^^^^ `MyTrait` is not dyn compatible 
1188+ ///    | 
1189+ /// note: for a trait to be dyn compatible it needs to allow building a vtable 
1190+ ///       for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> 
1191+ ///   --> src/lib.rs:17:19 
1192+ ///    | 
1193+ /// 16 | trait MyTrait { 
1194+ ///    |       ------- this trait is not dyn compatible... 
1195+ /// 17 |     fn func(self: MySmartPointer<Self>); 
1196+ ///    |                   ^^^^^^^^^^^^^^^^^^^^ ...because method `func`'s `self` parameter cannot be dispatched on 
1197+ /// ``` 
1198+ /// 
1199+ /// # Requirements for using the macro 
1200+ /// 
1201+ /// This macro can only be used if: 
1202+ /// * The type is a `#[repr(transparent)]` struct. 
1203+ /// * The type of its non-zero-sized field must either be a standard library pointer type 
1204+ ///   (reference, raw pointer, `NonNull`, `Box`, `Rc`, `Arc`, etc.) or another user-defined type 
1205+ ///   also using the `#[derive(CoercePointee)]` macro. 
1206+ /// * Zero-sized fields must not mention any generic parameters unless the zero-sized field has 
1207+ ///   type [`PhantomData`]. 
1208+ /// 
1209+ /// ## Multiple type parameters 
1210+ /// 
1211+ /// If the type has multiple type parameters, then you must explicitly specify which one should be 
1212+ /// used for dynamic dispatch. For example: 
1213+ /// ``` 
1214+ /// # #![feature(derive_coerce_pointee)] 
1215+ /// # use std::marker::{CoercePointee, PhantomData}; 
1216+ /// #[derive(CoercePointee)] 
1217+ /// #[repr(transparent)] 
1218+ /// struct MySmartPointer<#[pointee] T: ?Sized, U> { 
1219+ ///     ptr: Box<T>, 
1220+ ///     _phantom: PhantomData<U>, 
1221+ /// } 
1222+ /// ``` 
1223+ /// Specifying `#[pointee]` when the struct has only one type parameter is allowed, but not required. 
1224+ /// 
1225+ /// # Examples 
1226+ /// 
1227+ /// A custom implementation of the `Rc` type: 
1228+ /// ``` 
1229+ /// #![feature(derive_coerce_pointee)] 
1230+ /// use std::marker::CoercePointee; 
1231+ /// use std::ops::Deref; 
1232+ /// use std::ptr::NonNull; 
1233+ /// 
1234+ /// #[derive(CoercePointee)] 
1235+ /// #[repr(transparent)] 
1236+ /// pub struct Rc<T: ?Sized> { 
1237+ ///     inner: NonNull<RcInner<T>>, 
1238+ /// } 
1239+ /// 
1240+ /// struct RcInner<T: ?Sized> { 
1241+ ///     refcount: usize, 
1242+ ///     value: T, 
1243+ /// } 
1244+ /// 
1245+ /// impl<T: ?Sized> Deref for Rc<T> { 
1246+ ///     type Target = T; 
1247+ ///     fn deref(&self) -> &T { 
1248+ ///         let ptr = self.inner.as_ptr(); 
1249+ ///         unsafe { &(*ptr).value } 
1250+ ///     } 
1251+ /// } 
1252+ /// 
1253+ /// impl<T> Rc<T> { 
1254+ ///     pub fn new(value: T) -> Self { 
1255+ ///         let inner = Box::new(RcInner { 
1256+ ///             refcount: 1, 
1257+ ///             value, 
1258+ ///         }); 
1259+ ///         Self { 
1260+ ///             inner: NonNull::from(Box::leak(inner)), 
1261+ ///         } 
1262+ ///     } 
1263+ /// } 
1264+ /// 
1265+ /// impl<T: ?Sized> Clone for Rc<T> { 
1266+ ///     fn clone(&self) -> Self { 
1267+ ///         // A real implementation would handle overflow here. 
1268+ ///         unsafe { (*self.inner.as_ptr()).refcount += 1 }; 
1269+ ///         Self { inner: self.inner } 
1270+ ///     } 
1271+ /// } 
1272+ /// 
1273+ /// impl<T: ?Sized> Drop for Rc<T> { 
1274+ ///     fn drop(&mut self) { 
1275+ ///         let ptr = self.inner.as_ptr(); 
1276+ ///         unsafe { (*ptr).refcount -= 1 }; 
1277+ ///         if unsafe { (*ptr).refcount } == 0 { 
1278+ ///             drop(unsafe { Box::from_raw(ptr) }); 
1279+ ///         } 
1280+ ///     } 
1281+ /// } 
1282+ /// ``` 
10951283#[ rustc_builtin_macro( CoercePointee ,  attributes( pointee) ) ]  
10961284#[ allow_internal_unstable( dispatch_from_dyn,  coerce_unsized,  unsize) ]  
10971285#[ unstable( feature = "derive_coerce_pointee" ,  issue = "123430" ) ]  
0 commit comments