diff options
| author | Jonathan Turner <jonathandturner@users.noreply.github.com> | 2016-08-31 06:29:11 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-08-31 06:29:11 -0700 |
| commit | 2040d19b940ead1dc3faf16552f6725e7a40a248 (patch) | |
| tree | 36c964d2dbc6b6e47e2f3f0dbda8dcdfa659551d | |
| parent | 6631d8e9c6c67253f4c52a8ee5ac29e695fc9fdf (diff) | |
| parent | 69f0cee85dab86b8a27321cfce45adcb1f549d0c (diff) | |
| download | rust-2040d19b940ead1dc3faf16552f6725e7a40a248.tar.gz rust-2040d19b940ead1dc3faf16552f6725e7a40a248.zip | |
Rollup merge of #36148 - birryree:E0194_bonus_format, r=jonathandturner
Bonus format for E0194
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.
Errors for E0194 now look like this:
```
$> ./build/x86_64-apple-darwin/stage1/bin/rustc src/test/compile-fail/E0194.rs
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> src/test/compile-fail/E0194.rs:13:26
|
11 | trait Foo<T> { //~ NOTE first `T` declared here
| - first `T` declared here
12 | fn do_something(&self) -> T;
13 | fn do_something_else<T: Clone>(&self, bar: T);
| ^ shadows another type parameter
error: aborting due to previous error
```
r? @jonathandturner
| -rw-r--r-- | src/librustc_typeck/check/wfcheck.rs | 28 | ||||
| -rw-r--r-- | src/test/compile-fail/E0194.rs | 4 |
2 files changed, 24 insertions, 8 deletions
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index a236c8baa9f..435442bd30a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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; @@ -519,11 +519,26 @@ 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); } } } @@ -630,10 +645,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(); } diff --git a/src/test/compile-fail/E0194.rs b/src/test/compile-fail/E0194.rs index fa94c88328a..6b1f718dd76 100644 --- a/src/test/compile-fail/E0194.rs +++ b/src/test/compile-fail/E0194.rs @@ -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() { |
