1
- use std:: mem:: swap;
2
-
3
1
use ast:: ptr:: P ;
4
2
use ast:: HasAttrs ;
5
3
use rustc_ast:: mut_visit:: MutVisitor ;
@@ -154,13 +152,28 @@ pub fn expand_deriving_smart_ptr(
154
152
{
155
153
let pointee = & mut impl_generics. params [ pointee_param_idx] ;
156
154
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
+ }
157
172
let arg = GenericArg :: Type ( s_ty. clone ( ) ) ;
158
173
let unsize = cx. path_all ( span, true , path ! ( span, core:: marker:: Unsize ) , vec ! [ arg] ) ;
159
174
pointee. bounds . push ( cx. trait_bound ( unsize, false ) ) ;
160
- let mut attrs = thin_vec ! [ ] ;
161
- swap ( & mut pointee. attrs , & mut attrs) ;
162
175
// 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) ) ;
164
177
}
165
178
166
179
// # Rewrite generic parameter bounds
@@ -169,14 +182,14 @@ pub fn expand_deriving_smart_ptr(
169
182
// ```
170
183
// struct<
171
184
// U: Trait<T>,
172
- // #[pointee] T: Trait<T>,
185
+ // #[pointee] T: Trait<T> + ?Sized ,
173
186
// V: Trait<T>> ...
174
187
// ```
175
188
// ... generates this `impl` generic parameters
176
189
// ```
177
190
// impl<
178
191
// U: Trait<T> + Trait<__S>,
179
- // T: Trait<T> + Unsize<__S>, // (**)
192
+ // T: Trait<T> + ?Sized + Unsize<__S>, // (**)
180
193
// __S: Trait<__S> + ?Sized, // (*)
181
194
// V: Trait<T> + Trait<__S>> ...
182
195
// ```
@@ -218,23 +231,6 @@ pub fn expand_deriving_smart_ptr(
218
231
//
219
232
// We now insert `__S` with the missing bounds marked with (*) above.
220
233
// 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
- }
238
234
{
239
235
let mut substitution =
240
236
TypeSubstitution { from_name : pointee_ty_ident. name , to_ty : & s_ty, rewritten : false } ;
@@ -252,7 +248,7 @@ pub fn expand_deriving_smart_ptr(
252
248
// where
253
249
// U: Trait<V> + Trait<T>,
254
250
// Companion<T>: Trait<T>,
255
- // T: Trait<T>,
251
+ // T: Trait<T> + ?Sized ,
256
252
// { .. }
257
253
// ```
258
254
// ... will have a impl prelude like so
@@ -263,8 +259,8 @@ pub fn expand_deriving_smart_ptr(
263
259
// U: Trait<__S>,
264
260
// Companion<T>: Trait<T>,
265
261
// Companion<__S>: Trait<__S>,
266
- // T: Trait<T>,
267
- // __S: Trait<__S>,
262
+ // T: Trait<T> + ?Sized ,
263
+ // __S: Trait<__S> + ?Sized ,
268
264
// ```
269
265
//
270
266
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`
0 commit comments