@@ -16,7 +16,7 @@ use middle::region::{CodeExtent};
1616use  rustc:: infer:: TypeOrigin ; 
1717use  rustc:: traits; 
1818use  rustc:: ty:: { self ,  Ty ,  TyCtxt } ; 
19- use  rustc:: util:: nodemap:: FnvHashSet ; 
19+ use  rustc:: util:: nodemap:: { FnvHashSet ,   FnvHashMap } ; 
2020
2121use  syntax:: ast; 
2222use  syntax_pos:: Span ; 
@@ -519,11 +519,26 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
519519
520520fn  reject_shadowing_type_parameters ( tcx :  TyCtxt ,  span :  Span ,  generics :  & ty:: Generics )  { 
521521    let  parent = tcx. lookup_generics ( generics. parent . unwrap ( ) ) ; 
522-     let  impl_params:  FnvHashSet < _ >  = parent. types . iter ( ) . map ( |tp| tp. name ) . collect ( ) ; 
522+     let  impl_params:  FnvHashMap < _ ,  _ >  = parent. types 
523+                                         . iter ( ) 
524+                                         . map ( |tp| ( tp. name ,  tp. def_id ) ) 
525+                                         . collect ( ) ; 
523526
524527    for  method_param in  & generics. types  { 
525-         if  impl_params. contains ( & method_param. name )  { 
526-             error_194 ( tcx,  span,  method_param. name ) ; 
528+         if  impl_params. contains_key ( & method_param. name )  { 
529+             // Tighten up the span to focus on only the shadowing type 
530+             let  shadow_node_id = tcx. map . as_local_node_id ( method_param. def_id ) . unwrap ( ) ; 
531+             let  type_span = match  tcx. map . opt_span ( shadow_node_id)  { 
532+                 Some ( osp)  => osp, 
533+                 None  => span
534+             } ; 
535+ 
536+             // The expectation here is that the original trait declaration is 
537+             // local so it should be okay to just unwrap everything. 
538+             let  trait_def_id = impl_params. get ( & method_param. name ) . unwrap ( ) ; 
539+             let  trait_node_id = tcx. map . as_local_node_id ( * trait_def_id) . unwrap ( ) ; 
540+             let  trait_decl_span = tcx. map . opt_span ( trait_node_id) . unwrap ( ) ; 
541+             error_194 ( tcx,  type_span,  trait_decl_span,  method_param. name ) ; 
527542        } 
528543    } 
529544} 
@@ -630,10 +645,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
630645    err
631646} 
632647
633- fn  error_194 ( tcx :  TyCtxt ,  span :  Span ,  name :  ast:: Name )  { 
648+ fn  error_194 ( tcx :  TyCtxt ,  span :  Span ,  trait_decl_span :   Span ,   name :  ast:: Name )  { 
634649    struct_span_err ! ( tcx. sess,  span,  E0194 , 
635650              "type parameter `{}` shadows another type parameter of the same name" , 
636651              name) 
637-         . span_label ( span,  & format ! ( "`{}` shadows another type parameter" ,  name) ) 
652+         . span_label ( span,  & format ! ( "shadows another type parameter" ) ) 
653+         . span_label ( trait_decl_span,  & format ! ( "first `{}` declared here" ,  name) ) 
638654        . emit ( ) ; 
639655} 
0 commit comments