@@ -77,6 +77,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
7777 enum_variants ( fcx, enum_def)
7878 } ) ;
7979 }
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+ }
8088 _ => { }
8189 }
8290 }
@@ -237,21 +245,32 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
237245fn reject_non_type_param_bounds < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
238246 span : Span ,
239247 generics : & ty:: Generics < ' tcx > ) {
248+
240249 for predicate in generics. predicates . iter ( ) {
241250 match predicate {
242251 & 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) }
252260 }
253261 _ => { }
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 ( ) )
255274 }
256275
257276 fn is_ty_param ( ty : ty:: Ty ) -> bool {
@@ -267,6 +286,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
267286 self . check_item_well_formed ( i) ;
268287 visit:: walk_item ( self , i) ;
269288 }
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+ }
270307}
271308
272309pub struct BoundsChecker < ' cx , ' tcx : ' cx > {
@@ -455,7 +492,6 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
455492 let arg_tys =
456493 ty:: assert_no_late_bound_regions (
457494 fcx. tcx ( ) , & ty:: ty_fn_args ( ctor_ty) ) ;
458-
459495 AdtVariant {
460496 fields : args. iter ( ) . enumerate ( ) . map ( |( index, arg) | {
461497 let arg_ty = arg_tys[ index] ;
0 commit comments