@@ -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
@@ -262,11 +263,64 @@ fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
262263 }
263264}
264265
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+
265282impl < ' ccx , ' tcx , ' v > Visitor < ' v > for CheckTypeWellFormedVisitor < ' ccx , ' tcx > {
266283 fn visit_item ( & mut self , i : & ast:: Item ) {
267284 self . check_item_well_formed ( i) ;
268285 visit:: walk_item ( self , i) ;
269286 }
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+ }
270324}
271325
272326pub struct BoundsChecker < ' cx , ' tcx : ' cx > {
0 commit comments