diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 469d15e421434..c5155d93e579f 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -8,7 +8,7 @@ use crate::def_collector::collect_definitions; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; -use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; +use crate::Namespace::{MacroNS, TypeNS, ValueNS}; use crate::{errors, BindingKey, MacroData, NameBindingData}; use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError}; @@ -63,19 +63,6 @@ impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, Span, } impl<'a, 'tcx> Resolver<'a, 'tcx> { - /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; - /// otherwise, reports an error. - pub(crate) fn define(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) - where - T: ToNameBinding<'a>, - { - let binding = def.to_name_binding(self.arenas); - let key = self.new_disambiguated_key(ident, ns); - if let Err(old_binding) = self.try_define(parent, key, binding, false) { - self.report_conflict(parent, ident, ns, old_binding, binding); - } - } - /// Walks up the tree of definitions starting at `def_id`, /// stopping at the first encountered module. /// Parent block modules for arbitrary def-ids are not recorded for the local crate, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 30fb35238c3c7..140c33b24647d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -8,17 +8,17 @@ use crate::errors::{ ItemsInTraitsAreNotImportable, }; use crate::Determinacy::{self, *}; -use crate::Namespace::*; use crate::{module_to_string, names_to_string, ImportSuggestion}; use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet}; use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult}; +use crate::{Namespace::*, ToNameBinding}; use rustc_ast::NodeId; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan}; -use rustc_hir::def::{self, DefKind, PartialRes}; +use rustc_hir::def::{self, DefKind, Namespace, PartialRes}; use rustc_middle::metadata::ModChild; use rustc_middle::metadata::Reexport; use rustc_middle::span_bug; @@ -295,6 +295,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }) } + /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; + /// otherwise, reports an error. + pub(crate) fn define(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) + where + T: ToNameBinding<'a>, + { + let binding = def.to_name_binding(self.arenas); + let key = self.new_disambiguated_key(ident, ns); + if let Err(old_binding) = self.try_define(parent, key, binding, false) { + self.update_resolution(parent, key, false, |this, resolution| { + if let NameBindingKind::Res(_) = binding.kind { + resolution.binding = Some(this.arenas.alloc_name_binding(NameBindingData { + kind: NameBindingKind::Res(Res::Err), + ..(*binding).clone() + })); + } + }); + self.report_conflict(parent, ident, ns, old_binding, binding); + } + } + /// Define the name or return the existing binding if there is a collision. /// `update` indicates if the definition is a redefinition of an existing binding. pub(crate) fn try_define( diff --git a/tests/ui/issues/issue-28472.stderr b/tests/ui/issues/issue-28472.stderr index 051ed25b6c9d9..aec25227b1cf8 100644 --- a/tests/ui/issues/issue-28472.stderr +++ b/tests/ui/issues/issue-28472.stderr @@ -13,9 +13,10 @@ LL | | fn foo(); error[E0428]: the name `foo` is defined multiple times --> $DIR/issue-28472.rs:9:3 | -LL | fn foo(); - | --------- previous definition of the value `foo` here -... +LL | / pub +LL | | fn foo(); + | |___________- previous definition of the value `foo` here +LL | LL | / pub LL | | static mut foo: u32; | |______________________^ `foo` redefined here diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs new file mode 100644 index 0000000000000..609f5372c4c9a --- /dev/null +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -0,0 +1,13 @@ +//! This test used to ICE because the `repr(packed)` attributes +//! ended up on the `Dealigned` struct's attribute list, but the +//! derive didn't see that. + +#[repr(packed)] +struct Dealigned(u8, T); + +#[derive(PartialEq)] +#[repr(C)] +struct Dealigned(u8, T); +//~^ ERROR: `Dealigned` is defined multiple times + +fn main() {} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr new file mode 100644 index 0000000000000..c34f1b3d513ab --- /dev/null +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `Dealigned` is defined multiple times + --> $DIR/multiple_definitions_attribute_merging.rs:10:1 + | +LL | struct Dealigned(u8, T); + | --------------------------- previous definition of the type `Dealigned` here +... +LL | struct Dealigned(u8, T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here + | + = note: `Dealigned` must be defined only once in the type namespace of this module + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index d38d3c3b28653..5a958949df595 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,5 +1,4 @@ -#[derive(Clone)] //~ trait objects must include the `dyn` keyword -//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known +#[derive(Clone)] struct Foo; trait Foo {} //~ the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index aadadc45f21cb..db37d02ece1f6 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:4:1 + --> $DIR/issue-106072.rs:3:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -8,26 +8,6 @@ LL | trait Foo {} | = note: `Foo` must be defined only once in the type namespace of this module -error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time - --> $DIR/issue-106072.rs:1:10 - | -LL | #[derive(Clone)] - | ^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` -note: required by a bound in `Clone` - --> $SRC_DIR/core/src/clone.rs:LL:COL - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/issue-106072.rs:1:10 - | -LL | #[derive(Clone)] - | ^^^^^ - | - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0428, E0782. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0428`.