Skip to content

Commit 69f0cee

Browse files
committed
Bonus fix for #35280. Part of #35233. Fixes #36057. Adding expanded notes/context for what trait a parameter shadows as part of E0194 error messages.
1 parent 4473130 commit 69f0cee

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

src/librustc_typeck/check/wfcheck.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use middle::region::{CodeExtent};
1616
use rustc::infer::TypeOrigin;
1717
use rustc::traits;
1818
use rustc::ty::{self, Ty, TyCtxt};
19-
use rustc::util::nodemap::FnvHashSet;
19+
use rustc::util::nodemap::{FnvHashSet, FnvHashMap};
2020

2121
use syntax::ast;
2222
use syntax_pos::Span;
@@ -519,11 +519,26 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
519519

520520
fn 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
}

src/test/compile-fail/E0194.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
trait Foo<T> {
11+
trait Foo<T> { //~ NOTE first `T` declared here
1212
fn do_something(&self) -> T;
1313
fn do_something_else<T: Clone>(&self, bar: T);
1414
//~^ ERROR E0194
15-
//~| NOTE `T` shadows another type parameter
15+
//~| NOTE shadows another type parameter
1616
}
1717

1818
fn main() {

0 commit comments

Comments
 (0)