@@ -18,7 +18,7 @@ use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
18
18
use rustc:: traits;
19
19
use rustc:: ty:: { self , Ty , TyCtxt } ;
20
20
21
- use std:: collections:: HashSet ;
21
+ use std:: collections:: { HashSet , HashMap } ;
22
22
use syntax:: ast;
23
23
use syntax:: parse:: token:: keywords;
24
24
use syntax_pos:: Span ;
@@ -548,11 +548,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
548
548
549
549
fn reject_shadowing_type_parameters ( tcx : TyCtxt , span : Span , generics : & ty:: Generics ) {
550
550
let impl_params = generics. types . get_slice ( subst:: TypeSpace ) . iter ( )
551
- . map ( |tp| tp. name ) . collect :: < HashSet < _ > > ( ) ;
551
+ . map ( |tp| ( tp. name , tp . def_id ) ) . collect :: < HashMap < _ , _ > > ( ) ;
552
552
553
553
for method_param in generics. types . get_slice ( subst:: FnSpace ) {
554
- if impl_params. contains ( & method_param. name ) {
555
- error_194 ( tcx, span, method_param. name ) ;
554
+ if impl_params. contains_key ( & method_param. name ) {
555
+ // Tighten up the span to focus on only the shadowing type
556
+ let shadow_node_id = tcx. map . as_local_node_id ( method_param. def_id ) . unwrap ( ) ;
557
+ let type_span = match tcx. map . opt_span ( shadow_node_id) {
558
+ Some ( osp) => osp,
559
+ None => span
560
+ } ;
561
+
562
+ // The expectation here is that the original trait declaration is
563
+ // local so it should be okay to just unwrap everything
564
+ let trait_def_id = impl_params. get ( & method_param. name ) . unwrap ( ) ;
565
+ let trait_node_id = tcx. map . as_local_node_id ( * trait_def_id) . unwrap ( ) ;
566
+ let trait_decl_span = tcx. map . opt_span ( trait_node_id) . unwrap ( ) ;
567
+ error_194 ( tcx, type_span, trait_decl_span, method_param. name ) ;
556
568
}
557
569
}
558
570
}
@@ -657,8 +669,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
657
669
"parameter `{}` is never used" , param_name)
658
670
}
659
671
660
- fn error_194 ( tcx : TyCtxt , span : Span , name : ast:: Name ) {
661
- span_err ! ( tcx. sess, span, E0194 ,
672
+ fn error_194 ( tcx : TyCtxt , span : Span , trait_decl_span : Span , name : ast:: Name ) {
673
+ struct_span_err ! ( tcx. sess, span, E0194 ,
662
674
"type parameter `{}` shadows another type parameter of the same name" ,
663
- name) ;
675
+ name)
676
+ . span_label ( span, & format ! ( "shadows another type parameter" ) )
677
+ . span_label ( trait_decl_span, & format ! ( "first `{}` declared here" , name) )
678
+ . emit ( ) ;
664
679
}
0 commit comments