@@ -24,6 +24,7 @@ use syntax::ast;
24
24
use syntax:: ast_util:: { local_def} ;
25
25
use syntax:: attr;
26
26
use syntax:: codemap:: Span ;
27
+ use syntax:: parse:: token;
27
28
use syntax:: visit;
28
29
use syntax:: visit:: Visitor ;
29
30
@@ -262,11 +263,64 @@ fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
262
263
}
263
264
}
264
265
266
+ fn reject_shadowing_type_parameters < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
267
+ span : Span ,
268
+ generics : & ty:: Generics < ' tcx > ) {
269
+ let impl_params = generics. types . get_slice ( subst:: TypeSpace ) . iter ( )
270
+ . map ( |tp| tp. name ) . collect :: < HashSet < _ > > ( ) ;
271
+
272
+ for method_param in generics. types . get_slice ( subst:: FnSpace ) . iter ( ) {
273
+ if impl_params. contains ( & method_param. name ) {
274
+ tcx. sess . span_err (
275
+ span,
276
+ & * format ! ( "type parameter `{}` shadows another type parameter of the same name" ,
277
+ token:: get_name( method_param. name) ) ) ;
278
+ }
279
+ }
280
+ }
281
+
265
282
impl < ' ccx , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' ccx , ' tcx > {
266
283
fn visit_item ( & mut self , i : & ast:: Item ) {
267
284
self . check_item_well_formed ( i) ;
268
285
visit:: walk_item ( self , i) ;
269
286
}
287
+
288
+ fn visit_fn ( & mut self ,
289
+ fk : visit:: FnKind < ' v > , fd : & ' v ast:: FnDecl ,
290
+ b : & ' v ast:: Block , span : Span , id : ast:: NodeId ) {
291
+ match fk {
292
+ visit:: FkFnBlock | visit:: FkItemFn ( ..) => { }
293
+ visit:: FkMethod ( ..) => {
294
+ match ty:: impl_or_trait_item ( self . ccx . tcx , local_def ( id) ) {
295
+ ty:: ImplOrTraitItem :: MethodTraitItem ( ty_method) => {
296
+ reject_shadowing_type_parameters ( self . ccx . tcx , span, & ty_method. generics )
297
+ }
298
+ _ => { }
299
+ }
300
+ }
301
+ }
302
+ visit:: walk_fn ( self , fk, fd, b, span)
303
+ }
304
+
305
+ fn visit_trait_item ( & mut self , t : & ' v ast:: TraitItem ) {
306
+ match t {
307
+ & ast:: TraitItem :: ProvidedMethod ( _) |
308
+ & ast:: TraitItem :: TypeTraitItem ( _) => { } ,
309
+ & ast:: TraitItem :: RequiredMethod ( ref method) => {
310
+ match ty:: impl_or_trait_item ( self . ccx . tcx , local_def ( method. id ) ) {
311
+ ty:: ImplOrTraitItem :: MethodTraitItem ( ty_method) => {
312
+ reject_shadowing_type_parameters (
313
+ self . ccx . tcx ,
314
+ method. span ,
315
+ & ty_method. generics )
316
+ }
317
+ _ => { }
318
+ }
319
+ }
320
+ }
321
+
322
+ visit:: walk_trait_item ( self , t)
323
+ }
270
324
}
271
325
272
326
pub struct BoundsChecker < ' cx , ' tcx : ' cx > {
0 commit comments