@@ -24,6 +24,7 @@ use syntax::ast;
2424use syntax:: ast_util:: { local_def} ;
2525use syntax:: attr;
2626use syntax:: codemap:: Span ;
27+ use syntax:: parse:: token;
2728use syntax:: visit;
2829use syntax:: visit:: Visitor ;
2930
@@ -281,12 +282,45 @@ fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
281282 }
282283}
283284
285+ fn reject_shadowing_type_parameters < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
286+ span : Span ,
287+ generics : & ty:: Generics < ' tcx > ) {
288+ let impl_params = generics. types . get_slice ( subst:: TypeSpace ) . iter ( )
289+ . map ( |tp| tp. name ) . collect :: < HashSet < _ > > ( ) ;
290+
291+ for method_param in generics. types . get_slice ( subst:: FnSpace ) . iter ( ) {
292+ if impl_params. contains ( & method_param. name ) {
293+ tcx. sess . span_err (
294+ span,
295+ & * format ! ( "type parameter `{}` shadows another type parameter of the same name" ,
296+ token:: get_name( method_param. name) ) ) ;
297+ }
298+ }
299+ }
300+
284301impl < ' ccx , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' ccx , ' tcx > {
285302 fn visit_item ( & mut self , i : & ast:: Item ) {
286303 self . check_item_well_formed ( i) ;
287304 visit:: walk_item ( self , i) ;
288305 }
289306
307+ fn visit_fn ( & mut self ,
308+ fk : visit:: FnKind < ' v > , fd : & ' v ast:: FnDecl ,
309+ b : & ' v ast:: Block , span : Span , id : ast:: NodeId ) {
310+ match fk {
311+ visit:: FkFnBlock | visit:: FkItemFn ( ..) => { }
312+ visit:: FkMethod ( ..) => {
313+ match ty:: impl_or_trait_item ( self . ccx . tcx , local_def ( id) ) {
314+ ty:: ImplOrTraitItem :: MethodTraitItem ( ty_method) => {
315+ reject_shadowing_type_parameters ( self . ccx . tcx , span, & ty_method. generics )
316+ }
317+ _ => { }
318+ }
319+ }
320+ }
321+ visit:: walk_fn ( self , fk, fd, b, span)
322+ }
323+
290324 fn visit_trait_item ( & mut self , t : & ' v ast:: TraitItem ) {
291325 match t {
292326 & ast:: TraitItem :: ProvidedMethod ( _) |
@@ -297,12 +331,18 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
297331 reject_non_type_param_bounds (
298332 self . ccx . tcx ,
299333 method. span ,
300- & ty_method. generics )
334+ & ty_method. generics ) ;
335+ reject_shadowing_type_parameters (
336+ self . ccx . tcx ,
337+ method. span ,
338+ & ty_method. generics ) ;
301339 }
302340 _ => { }
303341 }
304342 }
305343 }
344+
345+ visit:: walk_trait_item ( self , t)
306346 }
307347}
308348
0 commit comments