From 235dfbab9cb4965a1d23c4d2278923c6ff8e193d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 2 Sep 2025 15:03:11 +0300 Subject: [PATCH] resolve: Avoid finalizing extern prelude entries more than once --- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 12 +++++++----- tests/ui/crate-loading/invalid-rlib.rs | 3 --- tests/ui/crate-loading/invalid-rlib.stderr | 11 +---------- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 5dfc4292a3803..758bb5435e4aa 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1846,7 +1846,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let extern_prelude_ambiguity = || { self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)).is_some_and(|entry| { entry.item_binding.map(|(b, _)| b) == Some(b1) - && entry.flag_binding.as_ref().and_then(|pb| pb.get().binding()) == Some(b2) + && entry.flag_binding.as_ref().and_then(|pb| pb.get().0.binding()) == Some(b2) }) }; let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9674c0356c21f..114d3e0848608 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1031,7 +1031,7 @@ struct ExternPreludeEntry<'ra> { /// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming. item_binding: Option<(NameBinding<'ra>, /* introduced by item */ bool)>, /// Binding from an `--extern` flag, lazily populated on first use. - flag_binding: Option>>, + flag_binding: Option, /* finalized */ bool)>>, } impl ExternPreludeEntry<'_> { @@ -1042,7 +1042,7 @@ impl ExternPreludeEntry<'_> { fn flag() -> Self { ExternPreludeEntry { item_binding: None, - flag_binding: Some(Cell::new(PendingBinding::Pending)), + flag_binding: Some(Cell::new((PendingBinding::Pending, false))), } } } @@ -2245,14 +2245,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn extern_prelude_get_flag(&self, ident: Ident, finalize: bool) -> Option> { let entry = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)); entry.and_then(|entry| entry.flag_binding.as_ref()).and_then(|flag_binding| { - let binding = match flag_binding.get() { + let (pending_binding, finalized) = flag_binding.get(); + let binding = match pending_binding { PendingBinding::Ready(binding) => { - if finalize { + if finalize && !finalized { self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span); } binding } PendingBinding::Pending => { + debug_assert!(!finalized); let crate_id = if finalize { self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span) } else { @@ -2264,7 +2266,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } }; - flag_binding.set(PendingBinding::Ready(binding)); + flag_binding.set((PendingBinding::Ready(binding), finalize || finalized)); binding.or_else(|| finalize.then_some(self.dummy_binding)) }) } diff --git a/tests/ui/crate-loading/invalid-rlib.rs b/tests/ui/crate-loading/invalid-rlib.rs index 6b46352624452..24293f88b1cd5 100644 --- a/tests/ui/crate-loading/invalid-rlib.rs +++ b/tests/ui/crate-loading/invalid-rlib.rs @@ -6,6 +6,3 @@ #![no_std] use ::foo; //~ ERROR invalid metadata files for crate `foo` //~| NOTE failed to mmap file -//~^^ ERROR invalid metadata files for crate `foo` -//~| NOTE failed to mmap file -//~| NOTE duplicate diagnostic diff --git a/tests/ui/crate-loading/invalid-rlib.stderr b/tests/ui/crate-loading/invalid-rlib.stderr index 63bb1b95cbb78..ad3ab729a5d21 100644 --- a/tests/ui/crate-loading/invalid-rlib.stderr +++ b/tests/ui/crate-loading/invalid-rlib.stderr @@ -6,15 +6,6 @@ LL | use ::foo; | = note: failed to mmap file 'auxiliary/libfoo.rlib' -error[E0786]: found invalid metadata files for crate `foo` - --> $DIR/invalid-rlib.rs:7:7 - | -LL | use ::foo; - | ^^^ - | - = note: failed to mmap file 'auxiliary/libfoo.rlib' - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0786`.