@@ -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