@@ -16,7 +16,7 @@ use middle::region::{CodeExtent};
16
16
use rustc:: infer:: TypeOrigin ;
17
17
use rustc:: traits;
18
18
use rustc:: ty:: { self , Ty , TyCtxt } ;
19
- use rustc:: util:: nodemap:: FnvHashSet ;
19
+ use rustc:: util:: nodemap:: { FnvHashSet , FnvHashMap } ;
20
20
21
21
use syntax:: ast;
22
22
use syntax_pos:: Span ;
@@ -519,11 +519,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
519
519
520
520
fn reject_shadowing_type_parameters ( tcx : TyCtxt , span : Span , generics : & ty:: Generics ) {
521
521
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 . iter ( ) . map ( |tp| ( tp. name , tp . def_id ) ) . collect ( ) ;
523
523
524
524
for method_param in & generics. types {
525
- if impl_params. contains ( & method_param. name ) {
526
- error_194 ( tcx, span, method_param. name ) ;
525
+ if impl_params. contains_key ( & method_param. name ) {
526
+ // Tighten up the span to focus on only the shadowing type
527
+ let shadow_node_id = tcx. map . as_local_node_id ( method_param. def_id ) . unwrap ( ) ;
528
+ let type_span = match tcx. map . opt_span ( shadow_node_id) {
529
+ Some ( osp) => osp,
530
+ None => span
531
+ } ;
532
+
533
+ // The expectation here is that the original trait declaration is
534
+ // local so it should be okay to just unwrap everything.
535
+ let trait_def_id = impl_params. get ( & method_param. name ) . unwrap ( ) ;
536
+ let trait_node_id = tcx. map . as_local_node_id ( * trait_def_id) . unwrap ( ) ;
537
+ let trait_decl_span = tcx. map . opt_span ( trait_node_id) . unwrap ( ) ;
538
+ error_194 ( tcx, type_span, trait_decl_span, method_param. name ) ;
527
539
}
528
540
}
529
541
}
@@ -630,10 +642,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
630
642
err
631
643
}
632
644
633
- fn error_194 ( tcx : TyCtxt , span : Span , name : ast:: Name ) {
645
+ fn error_194 ( tcx : TyCtxt , span : Span , trait_decl_span : Span , name : ast:: Name ) {
634
646
struct_span_err ! ( tcx. sess, span, E0194 ,
635
647
"type parameter `{}` shadows another type parameter of the same name" ,
636
648
name)
637
- . span_label ( span, & format ! ( "`{}` shadows another type parameter" , name) )
649
+ . span_label ( span, & format ! ( "shadows another type parameter" ) )
650
+ . span_label ( trait_decl_span, & format ! ( "first `{}` declared here" , name) )
638
651
. emit ( ) ;
639
652
}
0 commit comments