Skip to content

Commit 359b1b3

Browse files
committed
Taint resolution if there were multiple items of the same name
1 parent 6a4222b commit 359b1b3

7 files changed

+59
-53
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use crate::def_collector::collect_definitions;
99
use crate::imports::{ImportData, ImportKind};
1010
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
11-
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
11+
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
1212
use crate::{errors, BindingKey, MacroData, NameBindingData};
1313
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
1414
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
@@ -63,19 +63,6 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span,
6363
}
6464

6565
impl<'a, 'tcx> Resolver<'a, 'tcx> {
66-
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
67-
/// otherwise, reports an error.
68-
pub(crate) fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
69-
where
70-
T: ToNameBinding<'a>,
71-
{
72-
let binding = def.to_name_binding(self.arenas);
73-
let key = self.new_disambiguated_key(ident, ns);
74-
if let Err(old_binding) = self.try_define(parent, key, binding, false) {
75-
self.report_conflict(parent, ident, ns, old_binding, binding);
76-
}
77-
}
78-
7966
/// Walks up the tree of definitions starting at `def_id`,
8067
/// stopping at the first encountered module.
8168
/// Parent block modules for arbitrary def-ids are not recorded for the local crate,

compiler/rustc_resolve/src/imports.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ use crate::errors::{
88
ItemsInTraitsAreNotImportable,
99
};
1010
use crate::Determinacy::{self, *};
11-
use crate::Namespace::*;
1211
use crate::{module_to_string, names_to_string, ImportSuggestion};
1312
use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
1413
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
1514
use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
15+
use crate::{Namespace::*, ToNameBinding};
1616

1717
use rustc_ast::NodeId;
1818
use rustc_data_structures::fx::FxHashSet;
1919
use rustc_data_structures::intern::Interned;
2020
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
21-
use rustc_hir::def::{self, DefKind, PartialRes};
21+
use rustc_hir::def::{self, DefKind, Namespace, PartialRes};
2222
use rustc_middle::metadata::ModChild;
2323
use rustc_middle::metadata::Reexport;
2424
use rustc_middle::span_bug;
@@ -295,6 +295,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
295295
})
296296
}
297297

298+
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
299+
/// otherwise, reports an error.
300+
pub(crate) fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
301+
where
302+
T: ToNameBinding<'a>,
303+
{
304+
let binding = def.to_name_binding(self.arenas);
305+
let key = self.new_disambiguated_key(ident, ns);
306+
if let Err(old_binding) = self.try_define(parent, key, binding, false) {
307+
self.update_resolution(parent, key, false, |this, resolution| {
308+
if let NameBindingKind::Res(_) = binding.kind {
309+
resolution.binding = Some(this.arenas.alloc_name_binding(NameBindingData {
310+
kind: NameBindingKind::Res(Res::Err),
311+
..(*binding).clone()
312+
}));
313+
}
314+
});
315+
self.report_conflict(parent, ident, ns, old_binding, binding);
316+
}
317+
}
318+
298319
/// Define the name or return the existing binding if there is a collision.
299320
/// `update` indicates if the definition is a redefinition of an existing binding.
300321
pub(crate) fn try_define(

tests/ui/issues/issue-28472.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ LL | | fn foo();
1313
error[E0428]: the name `foo` is defined multiple times
1414
--> $DIR/issue-28472.rs:9:3
1515
|
16-
LL | fn foo();
17-
| --------- previous definition of the value `foo` here
18-
...
16+
LL | / pub
17+
LL | | fn foo();
18+
| |___________- previous definition of the value `foo` here
19+
LL |
1920
LL | / pub
2021
LL | | static mut foo: u32;
2122
| |______________________^ `foo` redefined here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! This test used to ICE because the `repr(packed)` attributes
2+
//! ended up on the `Dealigned` struct's attribute list, but the
3+
//! derive didn't see that.
4+
5+
#[repr(packed)]
6+
struct Dealigned<T>(u8, T);
7+
8+
#[derive(PartialEq)]
9+
#[repr(C)]
10+
struct Dealigned<T>(u8, T);
11+
//~^ ERROR: `Dealigned` is defined multiple times
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0428]: the name `Dealigned` is defined multiple times
2+
--> $DIR/multiple_definitions_attribute_merging.rs:10:1
3+
|
4+
LL | struct Dealigned<T>(u8, T);
5+
| --------------------------- previous definition of the type `Dealigned` here
6+
...
7+
LL | struct Dealigned<T>(u8, T);
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here
9+
|
10+
= note: `Dealigned` must be defined only once in the type namespace of this module
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0428`.

tests/ui/traits/issue-106072.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
#[derive(Clone)] //~ trait objects must include the `dyn` keyword
2-
//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known
3-
//~| ERROR: return type cannot have an unboxed trait object
1+
#[derive(Clone)]
42
struct Foo;
53
trait Foo {} //~ the name `Foo` is defined multiple times
64
fn main() {}

tests/ui/traits/issue-106072.stderr

+3-31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0428]: the name `Foo` is defined multiple times
2-
--> $DIR/issue-106072.rs:5:1
2+
--> $DIR/issue-106072.rs:3:1
33
|
44
LL | struct Foo;
55
| ----------- previous definition of the type `Foo` here
@@ -8,34 +8,6 @@ LL | trait Foo {}
88
|
99
= note: `Foo` must be defined only once in the type namespace of this module
1010

11-
error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time
12-
--> $DIR/issue-106072.rs:1:10
13-
|
14-
LL | #[derive(Clone)]
15-
| ^^^^^ doesn't have a size known at compile-time
16-
|
17-
= help: the trait `Sized` is not implemented for `(dyn Foo + 'static)`
18-
note: required by a bound in `Clone`
19-
--> $SRC_DIR/core/src/clone.rs:LL:COL
20-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
21-
22-
error[E0746]: return type cannot have an unboxed trait object
23-
--> $DIR/issue-106072.rs:1:10
24-
|
25-
LL | #[derive(Clone)]
26-
| ^^^^^ doesn't have a size known at compile-time
27-
|
28-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
29-
30-
error[E0782]: trait objects must include the `dyn` keyword
31-
--> $DIR/issue-106072.rs:1:10
32-
|
33-
LL | #[derive(Clone)]
34-
| ^^^^^
35-
|
36-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
37-
38-
error: aborting due to 4 previous errors
11+
error: aborting due to 1 previous error
3912

40-
Some errors have detailed explanations: E0277, E0428, E0746, E0782.
41-
For more information about an error, try `rustc --explain E0277`.
13+
For more information about this error, try `rustc --explain E0428`.

0 commit comments

Comments
 (0)