Skip to content

Commit bb14389

Browse files
committed
Auto merge of #42076 - alex-ozdemir:master, r=nrc
Clearer Error Message for Duplicate Definition Clearer use of the error message and span labels to communicate duplication definitions/imports. fixes #42061
2 parents 4450779 + a82890e commit bb14389

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
@@ -3450,11 +3450,11 @@ impl<'a> Resolver<'a> {
34503450
parent: Module,
34513451
ident: Ident,
34523452
ns: Namespace,
3453-
binding: &NameBinding,
3453+
new_binding: &NameBinding,
34543454
old_binding: &NameBinding) {
34553455
// Error on the second of two conflicting names
3456-
if old_binding.span.lo > binding.span.lo {
3457-
return self.report_conflict(parent, ident, ns, old_binding, binding);
3456+
if old_binding.span.lo > new_binding.span.lo {
3457+
return self.report_conflict(parent, ident, ns, old_binding, new_binding);
34583458
}
34593459

34603460
let container = match parent.kind {
@@ -3464,49 +3464,65 @@ impl<'a> Resolver<'a> {
34643464
_ => "enum",
34653465
};
34663466

3467-
let (participle, noun) = match old_binding.is_import() {
3468-
true => ("imported", "import"),
3469-
false => ("defined", "definition"),
3467+
let old_noun = match old_binding.is_import() {
3468+
true => "import",
3469+
false => "definition",
34703470
};
34713471

3472-
let (name, span) = (ident.name, binding.span);
3472+
let new_participle = match new_binding.is_import() {
3473+
true => "imported",
3474+
false => "defined",
3475+
};
3476+
3477+
let (name, span) = (ident.name, new_binding.span);
34733478

34743479
if let Some(s) = self.name_already_seen.get(&name) {
34753480
if s == &span {
34763481
return;
34773482
}
34783483
}
34793484

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

3493-
let mut err = match (old_binding.is_extern_crate(), binding.is_extern_crate()) {
3500+
let msg = format!("the name `{}` is defined multiple times", name);
3501+
3502+
let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
34943503
(true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
3495-
(true, _) | (_, true) => match binding.is_import() && old_binding.is_import() {
3504+
(true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() {
34963505
true => struct_span_err!(self.session, span, E0254, "{}", msg),
34973506
false => struct_span_err!(self.session, span, E0260, "{}", msg),
34983507
},
3499-
_ => match (old_binding.is_import(), binding.is_import()) {
3508+
_ => match (old_binding.is_import(), new_binding.is_import()) {
35003509
(false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
35013510
(true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
35023511
_ => struct_span_err!(self.session, span, E0255, "{}", msg),
35033512
},
35043513
};
35053514

3506-
err.span_label(span, format!("`{}` already {}", name, participle));
3515+
err.note(&format!("`{}` must be defined only once in the {} namespace of this {}",
3516+
name,
3517+
namespace,
3518+
container));
3519+
3520+
err.span_label(span, format!("`{}` re{} here", name, new_participle));
35073521
if old_binding.span != syntax_pos::DUMMY_SP {
3508-
err.span_label(old_binding.span, format!("previous {} of `{}` here", noun, name));
3522+
err.span_label(old_binding.span, format!("previous {} of the {} `{}` here",
3523+
old_noun, old_kind, name));
35093524
}
3525+
35103526
err.emit();
35113527
self.name_already_seen.insert(name, span);
35123528
}

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)