@@ -77,6 +77,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
77
77
enum_variants ( fcx, enum_def)
78
78
} ) ;
79
79
}
80
+ ast:: ItemTrait ( ..) => {
81
+ let trait_def =
82
+ ty:: lookup_trait_def ( ccx. tcx , local_def ( item. id ) ) ;
83
+ reject_non_type_param_bounds (
84
+ ccx. tcx ,
85
+ item. span ,
86
+ & trait_def. generics ) ;
87
+ }
80
88
_ => { }
81
89
}
82
90
}
@@ -237,21 +245,32 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
237
245
fn reject_non_type_param_bounds < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
238
246
span : Span ,
239
247
generics : & ty:: Generics < ' tcx > ) {
248
+
240
249
for predicate in generics. predicates . iter ( ) {
241
250
match predicate {
242
251
& ty:: Predicate :: Trait ( ty:: Binder ( ref tr) ) => {
243
- let self_ty = tr. self_ty ( ) ;
244
- if !self_ty. walk ( ) . any ( |t| is_ty_param ( t) ) {
245
- tcx. sess . span_err (
246
- span,
247
- format ! ( "cannot bound type `{}`, where clause \
248
- bounds may only be attached to types involving \
249
- type parameters",
250
- self_ty. repr( tcx) ) . as_slice ( ) )
251
- }
252
+ let found_param = tr. input_types ( ) . iter ( )
253
+ . flat_map ( |ty| ty. walk ( ) )
254
+ . any ( is_ty_param) ;
255
+ if !found_param { report_bound_error ( tcx, span, tr. self_ty ( ) ) }
256
+ }
257
+ & ty:: Predicate :: TypeOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( ty, _) ) ) => {
258
+ let found_param = ty. walk ( ) . any ( |t| is_ty_param ( t) ) ;
259
+ if !found_param { report_bound_error ( tcx, span, ty) }
252
260
}
253
261
_ => { }
254
- }
262
+ } ;
263
+ }
264
+
265
+ fn report_bound_error < ' t > ( tcx : & ty:: ctxt < ' t > ,
266
+ span : Span ,
267
+ bounded_ty : ty:: Ty < ' t > ) {
268
+ tcx. sess . span_err (
269
+ span,
270
+ format ! ( "cannot bound type `{}`, where clause \
271
+ bounds may only be attached to types involving \
272
+ type parameters",
273
+ bounded_ty. repr( tcx) ) . as_slice ( ) )
255
274
}
256
275
257
276
fn is_ty_param ( ty : ty:: Ty ) -> bool {
@@ -267,6 +286,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
267
286
self . check_item_well_formed ( i) ;
268
287
visit:: walk_item ( self , i) ;
269
288
}
289
+
290
+ fn visit_trait_item ( & mut self , t : & ' v ast:: TraitItem ) {
291
+ match t {
292
+ & ast:: TraitItem :: ProvidedMethod ( _) |
293
+ & ast:: TraitItem :: TypeTraitItem ( _) => { } ,
294
+ & ast:: TraitItem :: RequiredMethod ( ref method) => {
295
+ match ty:: impl_or_trait_item ( self . ccx . tcx , local_def ( method. id ) ) {
296
+ ty:: ImplOrTraitItem :: MethodTraitItem ( ty_method) => {
297
+ reject_non_type_param_bounds (
298
+ self . ccx . tcx ,
299
+ method. span ,
300
+ & ty_method. generics )
301
+ }
302
+ _ => { }
303
+ }
304
+ }
305
+ }
306
+ }
270
307
}
271
308
272
309
pub struct BoundsChecker < ' cx , ' tcx : ' cx > {
@@ -455,7 +492,6 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
455
492
let arg_tys =
456
493
ty:: assert_no_late_bound_regions (
457
494
fcx. tcx ( ) , & ty:: ty_fn_args ( ctor_ty) ) ;
458
-
459
495
AdtVariant {
460
496
fields : args. iter ( ) . enumerate ( ) . map ( |( index, arg) | {
461
497
let arg_ty = arg_tys[ index] ;
0 commit comments