Skip to content

Commit acf43ba

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

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
1818
use rustc::traits;
1919
use rustc::ty::{self, Ty, TyCtxt};
2020

21-
use std::collections::HashSet;
21+
use std::collections::{HashSet, HashMap};
2222
use syntax::ast;
2323
use syntax::parse::token::keywords;
2424
use syntax_pos::Span;
@@ -548,11 +548,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
548548

549549
fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
550550
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<_, _>>();
552552

553553
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);
556568
}
557569
}
558570
}
@@ -657,8 +669,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
657669
"parameter `{}` is never used", param_name)
658670
}
659671

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,
662674
"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();
664679
}

src/test/compile-fail/E0194.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +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;
13-
fn do_something_else<T: Clone>(&self, bar: T); //~ ERROR E0194
13+
fn do_something_else<T: Clone>(&self, bar: T);
14+
//~^ ERROR E0194
15+
//~| NOTE shadows another type parameter
1416
}
1517

1618
fn main() {

0 commit comments

Comments
 (0)