@@ -86,13 +86,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
86
86
{
87
87
let ccx = self . ccx ;
88
88
let item_def_id = local_def ( item. id ) ;
89
- let polytype = ty:: lookup_item_type ( ccx. tcx , item_def_id) ;
89
+ let type_scheme = ty:: lookup_item_type ( ccx. tcx , item_def_id) ;
90
+ reject_non_type_param_bounds ( ccx. tcx , item. span , & type_scheme. generics ) ;
90
91
let param_env =
91
92
ty:: construct_parameter_environment ( ccx. tcx ,
92
- & polytype . generics ,
93
+ & type_scheme . generics ,
93
94
item. id ) ;
94
95
let inh = Inherited :: new ( ccx. tcx , param_env) ;
95
- let fcx = blank_fn_ctxt ( ccx, & inh, ty:: FnConverging ( polytype . ty ) , item. id ) ;
96
+ let fcx = blank_fn_ctxt ( ccx, & inh, ty:: FnConverging ( type_scheme . ty ) , item. id ) ;
96
97
f ( self , & fcx) ;
97
98
vtable:: select_all_fcx_obligations_or_error ( & fcx) ;
98
99
regionck:: regionck_item ( & fcx, item) ;
@@ -143,10 +144,12 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
143
144
item. span ,
144
145
region:: CodeExtent :: from_node_id ( item. id ) ,
145
146
Some ( & mut this. cache ) ) ;
147
+
146
148
let type_scheme = ty:: lookup_item_type ( fcx. tcx ( ) , local_def ( item. id ) ) ;
147
149
let item_ty = fcx. instantiate_type_scheme ( item. span ,
148
150
& fcx. inh . param_env . free_substs ,
149
151
& type_scheme. ty ) ;
152
+
150
153
bounds_checker. check_traits_in_ty ( item_ty) ;
151
154
} ) ;
152
155
}
@@ -178,6 +181,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
178
181
None => { return ; }
179
182
Some ( t) => { t }
180
183
} ;
184
+
181
185
let trait_ref = fcx. instantiate_type_scheme ( item. span ,
182
186
& fcx. inh . param_env . free_substs ,
183
187
& trait_ref) ;
@@ -229,6 +233,35 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
229
233
}
230
234
}
231
235
236
+ // Reject any predicates that do not involve a type parameter.
237
+ fn reject_non_type_param_bounds < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
238
+ span : Span ,
239
+ generics : & ty:: Generics < ' tcx > ) {
240
+ for predicate in generics. predicates . iter ( ) {
241
+ match predicate {
242
+ & 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
+ }
253
+ _ => { }
254
+ }
255
+ }
256
+
257
+ fn is_ty_param ( ty : ty:: Ty ) -> bool {
258
+ match & ty. sty {
259
+ & ty:: sty:: ty_param( _) => true ,
260
+ _ => false
261
+ }
262
+ }
263
+ }
264
+
232
265
impl < ' ccx , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' ccx , ' tcx > {
233
266
fn visit_item ( & mut self , i : & ast:: Item ) {
234
267
self . check_item_well_formed ( i) ;
0 commit comments