1- use std:: mem:: swap;
2-
31use ast:: ptr:: P ;
42use ast:: HasAttrs ;
53use rustc_ast:: mut_visit:: MutVisitor ;
@@ -154,13 +152,28 @@ pub fn expand_deriving_smart_ptr(
154152 {
155153 let pointee = & mut impl_generics. params [ pointee_param_idx] ;
156154 self_bounds = pointee. bounds . clone ( ) ;
155+ if !contains_maybe_sized_bound ( & self_bounds)
156+ && !contains_maybe_sized_bound_on_pointee (
157+ & generics. where_clause . predicates ,
158+ pointee_ty_ident. name ,
159+ )
160+ {
161+ cx. dcx ( )
162+ . struct_span_err (
163+ pointee_ty_ident. span ,
164+ format ! (
165+ "`derive(SmartPointer)` requires {} to be marked `?Sized`" ,
166+ pointee_ty_ident. name
167+ ) ,
168+ )
169+ . emit ( ) ;
170+ return ;
171+ }
157172 let arg = GenericArg :: Type ( s_ty. clone ( ) ) ;
158173 let unsize = cx. path_all ( span, true , path ! ( span, core:: marker:: Unsize ) , vec ! [ arg] ) ;
159174 pointee. bounds . push ( cx. trait_bound ( unsize, false ) ) ;
160- let mut attrs = thin_vec ! [ ] ;
161- swap ( & mut pointee. attrs , & mut attrs) ;
162175 // Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)`
163- pointee. attrs = attrs . into_iter ( ) . filter ( |attr| !attr. has_name ( sym:: pointee) ) . collect ( ) ;
176+ pointee. attrs . retain ( |attr| !attr. has_name ( sym:: pointee) ) ;
164177 }
165178
166179 // # Rewrite generic parameter bounds
@@ -169,14 +182,14 @@ pub fn expand_deriving_smart_ptr(
169182 // ```
170183 // struct<
171184 // U: Trait<T>,
172- // #[pointee] T: Trait<T>,
185+ // #[pointee] T: Trait<T> + ?Sized ,
173186 // V: Trait<T>> ...
174187 // ```
175188 // ... generates this `impl` generic parameters
176189 // ```
177190 // impl<
178191 // U: Trait<T> + Trait<__S>,
179- // T: Trait<T> + Unsize<__S>, // (**)
192+ // T: Trait<T> + ?Sized + Unsize<__S>, // (**)
180193 // __S: Trait<__S> + ?Sized, // (*)
181194 // V: Trait<T> + Trait<__S>> ...
182195 // ```
@@ -218,23 +231,6 @@ pub fn expand_deriving_smart_ptr(
218231 //
219232 // We now insert `__S` with the missing bounds marked with (*) above.
220233 // We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`.
221- let sized = cx. path_global ( span, path ! ( span, core:: marker:: Sized ) ) ;
222- // For some reason, we are not allowed to write `?Sized` bound twice like `__S: ?Sized + ?Sized`.
223- if !contains_maybe_sized_bound ( & self_bounds)
224- && !contains_maybe_sized_bound_on_pointee (
225- & generics. where_clause . predicates ,
226- pointee_ty_ident. name ,
227- )
228- {
229- self_bounds. push ( GenericBound :: Trait (
230- cx. poly_trait_ref ( span, sized) ,
231- TraitBoundModifiers {
232- polarity : ast:: BoundPolarity :: Maybe ( span) ,
233- constness : ast:: BoundConstness :: Never ,
234- asyncness : ast:: BoundAsyncness :: Normal ,
235- } ,
236- ) ) ;
237- }
238234 {
239235 let mut substitution =
240236 TypeSubstitution { from_name : pointee_ty_ident. name , to_ty : & s_ty, rewritten : false } ;
@@ -252,7 +248,7 @@ pub fn expand_deriving_smart_ptr(
252248 // where
253249 // U: Trait<V> + Trait<T>,
254250 // Companion<T>: Trait<T>,
255- // T: Trait<T>,
251+ // T: Trait<T> + ?Sized ,
256252 // { .. }
257253 // ```
258254 // ... will have a impl prelude like so
@@ -263,8 +259,8 @@ pub fn expand_deriving_smart_ptr(
263259 // U: Trait<__S>,
264260 // Companion<T>: Trait<T>,
265261 // Companion<__S>: Trait<__S>,
266- // T: Trait<T>,
267- // __S: Trait<__S>,
262+ // T: Trait<T> + ?Sized ,
263+ // __S: Trait<__S> + ?Sized ,
268264 // ```
269265 //
270266 // We should also write a few new `where` bounds from `#[pointee] T` to `__S`
0 commit comments