Skip to content

Commit a82890e

Browse files
committed
Clearer Error Message for Duplicate Definition
Clearer use of the error message and span labels to communicate duplicaiton defitions/imports. New error format: ``` error[E0428]: the name `Foo` is defined twice --> example.rs:2:1 | 1 | trait Foo { } | ------------- previous definition of the trait `Foo` here 2 | struct Foo { } | ^^^^^^^^^^^^^^ `Foo` redefined here = note: `Foo` must be defined only once in the type namespace of this module error: aborting due to previous error ```
1 parent 258ae6d commit a82890e

36 files changed

+176
-133
lines changed

src/librustc_resolve/lib.rs

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3454,11 +3454,11 @@ impl<'a> Resolver<'a> {
34543454
parent: Module,
34553455
ident: Ident,
34563456
ns: Namespace,
3457-
binding: &NameBinding,
3457+
new_binding: &NameBinding,
34583458
old_binding: &NameBinding) {
34593459
// Error on the second of two conflicting names
3460-
if old_binding.span.lo > binding.span.lo {
3461-
return self.report_conflict(parent, ident, ns, old_binding, binding);
3460+
if old_binding.span.lo > new_binding.span.lo {
3461+
return self.report_conflict(parent, ident, ns, old_binding, new_binding);
34623462
}
34633463

34643464
let container = match parent.kind {
@@ -3468,49 +3468,65 @@ impl<'a> Resolver<'a> {
34683468
_ => "enum",
34693469
};
34703470

3471-
let (participle, noun) = match old_binding.is_import() {
3472-
true => ("imported", "import"),
3473-
false => ("defined", "definition"),
3471+
let old_noun = match old_binding.is_import() {
3472+
true => "import",
3473+
false => "definition",
34743474
};
34753475

3476-
let (name, span) = (ident.name, binding.span);
3476+
let new_participle = match new_binding.is_import() {
3477+
true => "imported",
3478+
false => "defined",
3479+
};
3480+
3481+
let (name, span) = (ident.name, new_binding.span);
34773482

34783483
if let Some(s) = self.name_already_seen.get(&name) {
34793484
if s == &span {
34803485
return;
34813486
}
34823487
}
34833488

3484-
let msg = {
3485-
let kind = match (ns, old_binding.module()) {
3486-
(ValueNS, _) => "a value",
3487-
(MacroNS, _) => "a macro",
3488-
(TypeNS, _) if old_binding.is_extern_crate() => "an extern crate",
3489-
(TypeNS, Some(module)) if module.is_normal() => "a module",
3490-
(TypeNS, Some(module)) if module.is_trait() => "a trait",
3491-
(TypeNS, _) => "a type",
3492-
};
3493-
format!("{} named `{}` has already been {} in this {}",
3494-
kind, name, participle, container)
3489+
let old_kind = match (ns, old_binding.module()) {
3490+
(ValueNS, _) => "value",
3491+
(MacroNS, _) => "macro",
3492+
(TypeNS, _) if old_binding.is_extern_crate() => "extern crate",
3493+
(TypeNS, Some(module)) if module.is_normal() => "module",
3494+
(TypeNS, Some(module)) if module.is_trait() => "trait",
3495+
(TypeNS, _) => "type",
3496+
};
3497+
3498+
let namespace = match ns {
3499+
ValueNS => "value",
3500+
MacroNS => "macro",
3501+
TypeNS => "type",
34953502
};
34963503

3497-
let mut err = match (old_binding.is_extern_crate(), binding.is_extern_crate()) {
3504+
let msg = format!("the name `{}` is defined multiple times", name);
3505+
3506+
let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
34983507
(true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
3499-
(true, _) | (_, true) => match binding.is_import() && old_binding.is_import() {
3508+
(true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() {
35003509
true => struct_span_err!(self.session, span, E0254, "{}", msg),
35013510
false => struct_span_err!(self.session, span, E0260, "{}", msg),
35023511
},
3503-
_ => match (old_binding.is_import(), binding.is_import()) {
3512+
_ => match (old_binding.is_import(), new_binding.is_import()) {
35043513
(false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
35053514
(true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
35063515
_ => struct_span_err!(self.session, span, E0255, "{}", msg),
35073516
},
35083517
};
35093518

3510-
err.span_label(span, format!("`{}` already {}", name, participle));
3519+
err.note(&format!("`{}` must be defined only once in the {} namespace of this {}",
3520+
name,
3521+
namespace,
3522+
container));
3523+
3524+
err.span_label(span, format!("`{}` re{} here", name, new_participle));
35113525
if old_binding.span != syntax_pos::DUMMY_SP {
3512-
err.span_label(old_binding.span, format!("previous {} of `{}` here", noun, name));
3526+
err.span_label(old_binding.span, format!("previous {} of the {} `{}` here",
3527+
old_noun, old_kind, name));
35133528
}
3529+
35143530
err.emit();
35153531
self.name_already_seen.insert(name, span);
35163532
}

src/test/compile-fail-fulldeps/proc-macro/shadow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
#[macro_use]
1414
extern crate derive_a;
1515
#[macro_use]
16-
extern crate derive_a; //~ ERROR `derive_a` has already been imported
16+
extern crate derive_a; //~ ERROR the name `derive_a` is defined multiple times
1717

1818
fn main() {}

src/test/compile-fail/E0254.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![feature(alloc)]
1212

1313
extern crate alloc;
14-
//~^ NOTE previous import of `alloc` here
14+
//~^ NOTE previous import of the extern crate `alloc` here
1515

1616
mod foo {
1717
pub trait alloc {
@@ -21,6 +21,7 @@ mod foo {
2121

2222
use foo::alloc;
2323
//~^ ERROR E0254
24-
//~| NOTE already imported
24+
//~| NOTE `alloc` reimported here
25+
//~| NOTE `alloc` must be defined only once in the type namespace of this module
2526

2627
fn main() {}

src/test/compile-fail/E0259.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
#![feature(alloc, libc)]
1212

1313
extern crate alloc;
14-
//~^ NOTE previous import of `alloc` here
14+
//~^ NOTE previous import of the extern crate `alloc` here
1515

1616
extern crate libc as alloc;
1717
//~^ ERROR E0259
18-
//~| NOTE `alloc` already imported
18+
//~| NOTE `alloc` reimported here
19+
//~| NOTE `alloc` must be defined only once in the type namespace of this module
1920

2021
fn main() {}

src/test/compile-fail/E0260.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
#![feature(alloc)]
1212

1313
extern crate alloc;
14-
//~^ NOTE previous import of `alloc` here
14+
//~^ NOTE previous import of the extern crate `alloc` here
1515

1616
mod alloc {
17-
//~^ ERROR `alloc` has already been imported in this module [E0260]
18-
//~| NOTE `alloc` already imported
17+
//~^ ERROR the name `alloc` is defined multiple times [E0260]
18+
//~| NOTE `alloc` redefined here
19+
//~| NOTE `alloc` must be defined only once in the type namespace of this module
1920
pub trait MyTrait {
2021
fn do_something();
2122
}

src/test/compile-fail/E0428.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
struct Bar; //~ previous definition of `Bar` here
11+
struct Bar; //~ previous definition of the type `Bar` here
1212
struct Bar; //~ ERROR E0428
13-
//~| NOTE already defined
13+
//~| NOTE `Bar` redefined here
14+
//~| NOTE `Bar` must be defined only once in the type namespace of this module
1415

1516
fn main () {
1617
}

src/test/compile-fail/blind-item-block-item-shadow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ fn main() {
1414
{
1515
struct Bar;
1616
use foo::Bar;
17-
//~^ ERROR a type named `Bar` has already been defined in this block
17+
//~^ ERROR the name `Bar` is defined multiple times
1818
}
1919
}

src/test/compile-fail/blind-item-item-shadow.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
mod foo { pub mod foo { } } //~ NOTE previous definition of `foo` here
11+
mod foo { pub mod foo { } } //~ NOTE previous definition of the module `foo` here
1212

1313
use foo::foo;
14-
//~^ ERROR a module named `foo` has already been defined in this module
15-
//~| `foo` already defined
14+
//~^ ERROR the name `foo` is defined multiple times
15+
//~| `foo` reimported here
16+
//~| NOTE `foo` must be defined only once in the type namespace of this module
1617

1718
fn main() {}

src/test/compile-fail/double-import.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ mod sub2 {
1919
pub fn foo() {} // implementation 2
2020
}
2121

22-
use sub1::foo; //~ NOTE previous import of `foo` here
23-
use sub2::foo; //~ ERROR a value named `foo` has already been imported in this module [E0252]
24-
//~| NOTE already imported
22+
use sub1::foo; //~ NOTE previous import of the value `foo` here
23+
use sub2::foo; //~ ERROR the name `foo` is defined multiple times
24+
//~| NOTE `foo` reimported here
25+
//~| NOTE `foo` must be defined only once in the value namespace of this module
2526

2627
fn main() {}

src/test/compile-fail/double-type-import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
mod foo {
1212
pub use self::bar::X;
1313
use self::bar::X;
14-
//~^ ERROR a type named `X` has already been imported in this module
14+
//~^ ERROR the name `X` is defined multiple times
1515

1616
mod bar {
1717
pub struct X;

0 commit comments

Comments
 (0)