Change:
I tried this code: I expected to see this happen: Compilation error. This shadows one (glob-imported) with another . As far as I know, this should be forbidden. Instead, this happened: this code successfully compiled. : c.c. c.c.
Shadowing a glob import with a specific item is allowed and will unambiguously resolve to the specific one. This is also how the prelude works. The following compiles fine as well: .
To clarify, the problem is not shadowing, but time travel. We shadow identifier which have been already used to resolve another import, so we end up with meaning two things at the same time in the same scope.
This is a change from Rust 1.44, in Rust 1.43 this is an ICE "inconsistent resolution for an import". Possibly a consequence of
I'm not sure this is a bug. When resolving we are looking at all names in scope except for the names introduced by itself. Otherwise we'd have cycles even in trivial cases like where is a name from extern prelude. If you take this detail into consideration, then all paths seem to be resolved correctly.
cc (somewhat related)
I think, the difference with is that doesn't replace one resolution with another. We already have a name in the scope that is resolved to a particular extern crate. In my example, uses name from the scope, and then rebinds this name to another item. I can complicate my example a bit. What this program prints, "111" or "222"? It'd say, it depends on imports resolution order, but looks like it always prints "111".
It'd say, it depends on imports resolution order The intent for the resolution results is to never depend on internal resolution order. (cc , order-dependence can probably happen in practice due to the current not very principled implementation, but hopefully still can be eliminated in backward-compatible-in-practice way by rewriting the main resolution/expansion loop more carefully.) but looks like it always prints "111" That's what I'd expect. resolves to in resolves to (because non-globs shadow globs) first in resolves to (which the only in scope after excluding itself)
I'd still be ok with replacing the former ICE with an error though, since that's a more conservative choice.
Actually enabling the property "name resolve to the same thing whether some items were excluded during its resolution to avoid cycles or not" may be useful for using something like "inference variables" for unresolved imports and making import resolution more like unification in type inference. That's an idea I had for quite some, but I hadn't realized that merging went against it.
Sigh, the issue already affects three stable releases - from 1.44 to 1.46. I'll try to prioritize it.
Addressed in
Assigning so this isn't lost. See the .
The fix caused some regressions -
The code in the issue produce no errors using Rust 1.67.1. Should we re-open the issue or is it not considered a bug now?
The fix was reverted due to breakage () and the current behavior is considered by design since then.
(Also it's not exactly a time travel - )

Discussion:
/// consolidate multiple unresolved import errors into a single diagnostic. fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> { let orig_vis = import.vis.replace(ty::Visibility::Invisible); <del> let orig_unusable_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => { Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get())) } _ => None, }; </del> let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( &import.module_path,

import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; <del> if let Some(orig_unusable_binding) = orig_unusable_binding { self.r.unusable_binding = orig_unusable_binding; } </del> import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics.

// Consistency checks, analogous to `finalize_macro_resolutions`. if let Some(initial_module) = import.imported_module.get() { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { <del> span_bug!(import.span, "inconsistent resolution for an import"); </del> <ins> let msg = "inconsistent resolution for an import"; self.r.session.span_err(import.span, msg); </ins> } } else { if self.r.privacy_errors.is_empty() {

} PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => { if no_ambiguity { <del> assert!(import.imported_module.get().is_none()); </del> let err = match self.make_path_suggestion( span, import.module_path.clone(),

<del> // check-pass </del> <ins> // Minimized case from #62767. </ins> mod m { pub enum Same { Same,

use m::*; <del> // The variant `Same` introduced by this import is not considered when resolving the prefix // `Same::` during import validation (issue #62767). use Same::Same; </del> <ins> // The variant `Same` introduced by this import is also considered when resolving the prefix // `Same::` during import validation to avoid effects similar to time travel (#74556). use Same::Same; //~ ERROR unresolved import `Same` // Case from #74556. mod foo { pub mod bar { pub mod bar { pub fn foobar() {} } } } use foo::*; use bar::bar; //~ ERROR unresolved import `bar::bar` //~| ERROR inconsistent resolution for an import use bar::foobar; </ins> fn main() {}

<ins> error: inconsistent resolution for an import --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ error[E0432]: unresolved import `Same` --> $DIR/issue-62767.rs:12:5 | LL | use Same::Same; |     ^^^^ `Same` is a variant, not a module error[E0432]: unresolved import `bar::bar` --> $DIR/issue-62767.rs:24:5 | LL | use bar::bar; |     ^^^^^^^^ no `bar` in `foo::bar::bar` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0432`. </ins>