Skip to content

Commit e7c306d

Browse files
author
Jonathan Turner
authored
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
2 parents a755ac4 + fb38911 commit e7c306d

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/librustc_typeck/check/wfcheck.rs

+19-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,23 @@ 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.iter().map(|tp| (tp.name, tp.def_id)).collect();
523523

524524
for method_param in &generics.types {
525-
if impl_params.contains(&method_param.name) {
526-
error_194(tcx, span, method_param.name);
525+
if impl_params.contains_key(&method_param.name) {
526+
// Tighten up the span to focus on only the shadowing type
527+
let shadow_node_id = tcx.map.as_local_node_id(method_param.def_id).unwrap();
528+
let type_span = match tcx.map.opt_span(shadow_node_id) {
529+
Some(osp) => osp,
530+
None => span
531+
};
532+
533+
// The expectation here is that the original trait declaration is
534+
// local so it should be okay to just unwrap everything.
535+
let trait_def_id = impl_params.get(&method_param.name).unwrap();
536+
let trait_node_id = tcx.map.as_local_node_id(*trait_def_id).unwrap();
537+
let trait_decl_span = tcx.map.opt_span(trait_node_id).unwrap();
538+
error_194(tcx, type_span, trait_decl_span, method_param.name);
527539
}
528540
}
529541
}
@@ -630,10 +642,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
630642
err
631643
}
632644

633-
fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) {
645+
fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
634646
struct_span_err!(tcx.sess, span, E0194,
635647
"type parameter `{}` shadows another type parameter of the same name",
636648
name)
637-
.span_label(span, &format!("`{}` shadows another type parameter", name))
649+
.span_label(span, &format!("shadows another type parameter"))
650+
.span_label(trait_decl_span, &format!("first `{}` declared here", name))
638651
.emit();
639652
}

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)