Skip to content

Commit

Permalink
Taint resolution if there were multiple items of the same name
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Feb 15, 2024
1 parent 6a4222b commit 359b1b3
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 53 deletions.
15 changes: 1 addition & 14 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -63,19 +63,6 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, 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<T>(&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,
Expand Down
25 changes: 23 additions & 2 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<T>(&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(
Expand Down
7 changes: 4 additions & 3 deletions tests/ui/issues/issue-28472.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/resolve/multiple_definitions_attribute_merging.rs
Original file line number Diff line number Diff line change
@@ -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<T>(u8, T);

#[derive(PartialEq)]
#[repr(C)]
struct Dealigned<T>(u8, T);
//~^ ERROR: `Dealigned` is defined multiple times

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/resolve/multiple_definitions_attribute_merging.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0428]: the name `Dealigned` is defined multiple times
--> $DIR/multiple_definitions_attribute_merging.rs:10:1
|
LL | struct Dealigned<T>(u8, T);
| --------------------------- previous definition of the type `Dealigned` here
...
LL | struct Dealigned<T>(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`.
4 changes: 1 addition & 3 deletions tests/ui/traits/issue-106072.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#[derive(Clone)] //~ trait objects must include the `dyn` keyword
//~^ ERROR: the size for values of type `(dyn Foo + 'static)` cannot be known
//~| ERROR: return type cannot have an unboxed trait object
#[derive(Clone)]
struct Foo;
trait Foo {} //~ the name `Foo` is defined multiple times
fn main() {}
34 changes: 3 additions & 31 deletions tests/ui/traits/issue-106072.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0428]: the name `Foo` is defined multiple times
--> $DIR/issue-106072.rs:5:1
--> $DIR/issue-106072.rs:3:1
|
LL | struct Foo;
| ----------- previous definition of the type `Foo` here
Expand All @@ -8,34 +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[E0746]: return type cannot have an unboxed trait object
--> $DIR/issue-106072.rs:1:10
|
LL | #[derive(Clone)]
| ^^^^^ doesn't have a size known at compile-time
|
= 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 4 previous errors
error: aborting due to 1 previous error

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

0 comments on commit 359b1b3

Please sign in to comment.