Skip to content

Commit

Permalink
Rollup merge of #36148 - birryree:E0194_bonus_format, r=jonathandturner
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Jonathan Turner authored Aug 30, 2016
2 parents a755ac4 + fb38911 commit e7c306d
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 e7c306d

Please sign in to comment.