Auto merge of #144737 - petrochenkov:extprelcache, r=davidtwco

resolve: Avoid finalizing extern prelude entries more than once
This commit is contained in:
bors 2025-09-05 05:50:24 +00:00
commit ad85bc524b
4 changed files with 9 additions and 19 deletions

View file

@ -1986,7 +1986,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() {

View file

@ -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<Cell<PendingBinding<'ra>>>,
flag_binding: Option<Cell<(PendingBinding<'ra>, /* 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<NameBinding<'ra>> {
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))
})
}

View file

@ -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

View file

@ -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`.