@@ -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,26 @@ 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
523
+ . iter ( )
524
+ . map ( |tp| ( tp. name , tp. def_id ) )
525
+ . collect ( ) ;
523
526
524
527
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 ) ;
527
542
}
528
543
}
529
544
}
@@ -630,10 +645,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
630
645
err
631
646
}
632
647
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 ) {
634
649
struct_span_err ! ( tcx. sess, span, E0194 ,
635
650
"type parameter `{}` shadows another type parameter of the same name" ,
636
651
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) )
638
654
. emit ( ) ;
639
655
}
0 commit comments