Skip to content

Commit

Permalink
Bonus fix for rust-lang#35280. Part of rust-lang#35233. Fixes rust-la…
Browse files Browse the repository at this point in the history
…ng#36057. Adding expanded notes/context for what trait a parameter shadows as part of E0194 error messages.
  • Loading branch information
leikahing committed Aug 30, 2016
1 parent 4473130 commit fb38911
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
25 changes: 19 additions & 6 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use middle::region::{CodeExtent};
use rustc::infer::TypeOrigin;
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FnvHashSet;
use rustc::util::nodemap::{FnvHashSet, FnvHashMap};

use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -519,11 +519,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {

fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
let parent = tcx.lookup_generics(generics.parent.unwrap());
let impl_params: FnvHashSet<_> = parent.types.iter().map(|tp| tp.name).collect();
let impl_params: FnvHashMap<_, _> = parent.types.iter().map(|tp| (tp.name, tp.def_id)).collect();

for method_param in &generics.types {
if impl_params.contains(&method_param.name) {
error_194(tcx, span, method_param.name);
if impl_params.contains_key(&method_param.name) {
// Tighten up the span to focus on only the shadowing type
let shadow_node_id = tcx.map.as_local_node_id(method_param.def_id).unwrap();
let type_span = match tcx.map.opt_span(shadow_node_id) {
Some(osp) => osp,
None => span
};

// The expectation here is that the original trait declaration is
// local so it should be okay to just unwrap everything.
let trait_def_id = impl_params.get(&method_param.name).unwrap();
let trait_node_id = tcx.map.as_local_node_id(*trait_def_id).unwrap();
let trait_decl_span = tcx.map.opt_span(trait_node_id).unwrap();
error_194(tcx, type_span, trait_decl_span, method_param.name);
}
}
}
Expand Down Expand Up @@ -630,10 +642,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
err
}

fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) {
fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
struct_span_err!(tcx.sess, span, E0194,
"type parameter `{}` shadows another type parameter of the same name",
name)
.span_label(span, &format!("`{}` shadows another type parameter", name))
.span_label(span, &format!("shadows another type parameter"))
.span_label(trait_decl_span, &format!("first `{}` declared here", name))
.emit();
}
4 changes: 2 additions & 2 deletions src/test/compile-fail/E0194.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

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

fn main() {
Expand Down

0 comments on commit fb38911

Please sign in to comment.