Skip to content

Commit

Permalink
resolve: Unload speculatively resolved crates before freezing cstore
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jan 4, 2024
1 parent 4c5ce1f commit ada8cf9
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 16 deletions.
7 changes: 6 additions & 1 deletion compiler/rustc_data_structures/src/sync/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ impl<I: Idx, T: Copy> AppendOnlyIndexVec<I, T> {
}
}

#[derive(Default)]
pub struct AppendOnlyVec<T: Copy> {
vec: parking_lot::RwLock<Vec<T>>,
}
Expand Down Expand Up @@ -80,6 +79,12 @@ impl<T: Copy + PartialEq> AppendOnlyVec<T> {
}
}

impl<T: Copy> Default for AppendOnlyVec<T> {
fn default() -> Self {
AppendOnlyVec { vec: Default::default() }
}
}

impl<A: Copy> FromIterator<A> for AppendOnlyVec<A> {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
let this = Self::new();
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ impl CStore {
CrateMetadataRef { cdata, cstore: self }
}

pub(crate) fn get_crate_data_mut(&mut self, cnum: CrateNum) -> &mut CrateMetadata {
self.metas[cnum].as_mut().unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}"))
}

fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
self.metas[cnum] = Some(Box::new(data));
Expand Down Expand Up @@ -524,7 +528,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
) -> Option<CrateNum> {
self.used_extern_options.insert(name);
match self.maybe_resolve_crate(name, dep_kind, None) {
Ok(cnum) => Some(cnum),
Ok(cnum) => {
self.cstore.set_used_recursively(cnum);
Some(cnum)
}
Err(err) => {
let missing_core =
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
Expand Down Expand Up @@ -1066,6 +1073,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
}

pub fn unload_unused_crates(&mut self) {
for opt_cdata in &mut self.cstore.metas {
if let Some(cdata) = opt_cdata
&& !cdata.used
{
*opt_cdata = None;
}
}
}
}

fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ pub(crate) struct CrateMetadata {
private_dep: AtomicBool,
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
host_hash: Option<Svh>,
/// The crate was used non-speculatively.
pub used: bool,

/// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
/// and `ExpnId`).
Expand Down Expand Up @@ -1822,6 +1824,7 @@ impl CrateMetadata {
source: Lrc::new(source),
private_dep: AtomicBool::new(private_dep),
host_hash,
used: false,
extern_crate: Lock::new(None),
hygiene_context: Default::default(),
def_key_cache: Default::default(),
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;

use std::any::Any;
use std::mem;

use super::{Decodable, DecodeContext, DecodeIterator};

Expand Down Expand Up @@ -581,6 +582,18 @@ impl CStore {
) -> Span {
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
}

pub fn set_used_recursively(&mut self, cnum: CrateNum) {
let cdata = self.get_crate_data_mut(cnum);
if !cdata.used {
cdata.used = true;
let dependencies = mem::take(&mut cdata.dependencies);
for dep_cnum in dependencies.iter() {
self.set_used_recursively(dep_cnum);
}
self.get_crate_data_mut(cnum).dependencies = dependencies;
}
}
}

impl CrateStore for CStore {
Expand Down
21 changes: 14 additions & 7 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
use rustc_metadata::creader::CStore;
use rustc_middle::middle::resolve_bound_vars::Set1;
use rustc_middle::{bug, span_bug};
use rustc_session::config::{CrateType, ResolveDocLinks};
Expand Down Expand Up @@ -4455,14 +4456,20 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
if let Some(res) = res
&& let Some(def_id) = res.opt_def_id()
&& !def_id.is_local()
&& self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!(
self.r.tcx.sess.opts.resolve_doc_links,
ResolveDocLinks::ExportedMetadata
)
{
// Encoding foreign def ids in proc macro crate metadata will ICE.
return None;
if self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
&& matches!(
self.r.tcx.sess.opts.resolve_doc_links,
ResolveDocLinks::ExportedMetadata
)
{
// Encoding foreign def ids in proc macro crate metadata will ICE.
return None;
}
// Doc paths should be resolved speculatively and should not produce any
// diagnostics, but if they are indeed resolved, then we need to keep the
// corresponding crate alive.
CStore::from_tcx_mut(self.r.tcx).set_used_recursively(def_id.krate);
}
res
});
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.tcx
.sess
.time("resolve_postprocess", || self.crate_loader(|c| c.postprocess(krate)));
self.crate_loader(|c| c.unload_unused_crates());
});

// Make sure we don't mutate the cstore from here on.
Expand Down
9 changes: 2 additions & 7 deletions tests/ui/extern-flag/empty-extern-arg.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
error: extern location for std does not exist:

error: `#[panic_handler]` function required, but not found
error: requires `sized` lang_item

error: language item required, but not found: `eh_personality`
|
= note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
= help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

0 comments on commit ada8cf9

Please sign in to comment.