1
Fork 0

Generate crate loaders on the fly

This commit is contained in:
Oli Scherer 2022-12-07 13:37:47 +00:00
parent 4b08fbaea8
commit 2cd36f2c89
7 changed files with 67 additions and 54 deletions

View file

@ -68,11 +68,12 @@ impl std::fmt::Debug for CStore {
pub struct CrateLoader<'a> { pub struct CrateLoader<'a> {
// Immutable configuration. // Immutable configuration.
sess: &'a Session, sess: &'a Session,
metadata_loader: Box<MetadataLoaderDyn>, metadata_loader: &'a MetadataLoaderDyn,
definitions: &'a Definitions,
local_crate_name: Symbol, local_crate_name: Symbol,
// Mutable output. // Mutable output.
cstore: CStore, cstore: &'a mut CStore,
used_extern_options: FxHashSet<Symbol>, used_extern_options: &'a mut FxHashSet<Symbol>,
} }
pub enum LoadedMacro { pub enum LoadedMacro {
@ -239,47 +240,49 @@ impl CStore {
); );
} }
} }
pub fn new(sess: &Session) -> CStore {
let mut stable_crate_ids = FxHashMap::default();
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
CStore {
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
// order to make array indices in `metas` match with the
// corresponding `CrateNum`. This first entry will always remain
// `None`.
metas: IndexVec::from_elem_n(None, 1),
injected_panic_runtime: None,
allocator_kind: None,
alloc_error_handler_kind: None,
has_global_allocator: false,
has_alloc_error_handler: false,
stable_crate_ids,
unused_externs: Vec::new(),
}
}
} }
impl<'a> CrateLoader<'a> { impl<'a> CrateLoader<'a> {
pub fn new( pub fn new(
sess: &'a Session, sess: &'a Session,
metadata_loader: Box<MetadataLoaderDyn>, metadata_loader: &'a MetadataLoaderDyn,
local_crate_name: Symbol, local_crate_name: Symbol,
cstore: &'a mut CStore,
definitions: &'a Definitions,
used_extern_options: &'a mut FxHashSet<Symbol>,
) -> Self { ) -> Self {
let mut stable_crate_ids = FxHashMap::default();
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
CrateLoader { CrateLoader {
sess, sess,
metadata_loader, metadata_loader,
local_crate_name, local_crate_name,
cstore: CStore { cstore,
// We add an empty entry for LOCAL_CRATE (which maps to zero) in used_extern_options,
// order to make array indices in `metas` match with the definitions,
// corresponding `CrateNum`. This first entry will always remain
// `None`.
metas: IndexVec::from_elem_n(None, 1),
injected_panic_runtime: None,
allocator_kind: None,
alloc_error_handler_kind: None,
has_global_allocator: false,
has_alloc_error_handler: false,
stable_crate_ids,
unused_externs: Vec::new(),
},
used_extern_options: Default::default(),
} }
} }
pub fn cstore(&self) -> &CStore { pub fn cstore(&self) -> &CStore {
&self.cstore &self.cstore
} }
pub fn into_cstore(self) -> CStore {
self.cstore
}
fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> { fn existing_match(&self, name: Symbol, hash: Option<Svh>, kind: PathKind) -> Option<CrateNum> {
for (cnum, data) in self.cstore.iter_crate_data() { for (cnum, data) in self.cstore.iter_crate_data() {
if data.name() != name { if data.name() != name {
@ -989,7 +992,6 @@ impl<'a> CrateLoader<'a> {
pub fn process_extern_crate( pub fn process_extern_crate(
&mut self, &mut self,
item: &ast::Item, item: &ast::Item,
definitions: &Definitions,
def_id: LocalDefId, def_id: LocalDefId,
) -> Option<CrateNum> { ) -> Option<CrateNum> {
match item.kind { match item.kind {
@ -1013,7 +1015,7 @@ impl<'a> CrateLoader<'a> {
let cnum = self.resolve_crate(name, item.span, dep_kind)?; let cnum = self.resolve_crate(name, item.span, dep_kind)?;
let path_len = definitions.def_path(def_id).data.len(); let path_len = self.definitions.def_path(def_id).data.len();
self.update_extern_crate( self.update_extern_crate(
cnum, cnum,
ExternCrate { ExternCrate {

View file

@ -836,12 +836,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
} else if orig_name == Some(kw::SelfLower) { } else if orig_name == Some(kw::SelfLower) {
Some(self.r.graph_root) Some(self.r.graph_root)
} else { } else {
self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id).map( self.r.crate_loader().process_extern_crate(item, local_def_id).map(|crate_id| {
|crate_id| { self.r.extern_crate_map.insert(local_def_id, crate_id);
self.r.extern_crate_map.insert(local_def_id, crate_id); self.r.expect_module(crate_id.as_def_id())
self.r.expect_module(crate_id.as_def_id()) })
},
)
} }
.map(|module| { .map(|module| {
let used = self.process_macro_use_imports(item, module); let used = self.process_macro_use_imports(item, module);

View file

@ -1298,7 +1298,7 @@ impl<'a> Resolver<'a> {
// otherwise cause duplicate suggestions. // otherwise cause duplicate suggestions.
continue; continue;
} }
if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name) { if let Some(crate_id) = self.crate_loader().maybe_process_path_extern(ident.name) {
let crate_root = self.expect_module(crate_id.as_def_id()); let crate_root = self.expect_module(crate_id.as_def_id());
suggestions.extend(self.lookup_import_candidates_from_module( suggestions.extend(self.lookup_import_candidates_from_module(
lookup_ident, lookup_ident,

View file

@ -107,7 +107,7 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
r.effective_visibilities.update_eff_vis( r.effective_visibilities.update_eff_vis(
r.local_def_id(node_id), r.local_def_id(node_id),
eff_vis, eff_vis,
ResolverTree(&r.definitions, r.crate_loader.cstore()), ResolverTree(&r.definitions, &r.cstore),
) )
} }
} }

View file

@ -1663,8 +1663,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
if !module.no_implicit_prelude { if !module.no_implicit_prelude {
let extern_prelude = self.r.extern_prelude.clone(); let extern_prelude = self.r.extern_prelude.clone();
names.extend(extern_prelude.iter().flat_map(|(ident, _)| { names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
self.r.crate_loader.maybe_process_path_extern(ident.name).and_then( self.r
|crate_id| { .crate_loader()
.maybe_process_path_extern(ident.name)
.and_then(|crate_id| {
let crate_mod = let crate_mod =
Res::Def(DefKind::Mod, crate_id.as_def_id()); Res::Def(DefKind::Mod, crate_id.as_def_id());
@ -1673,8 +1675,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
} else { } else {
None None
} }
}, })
)
})); }));
if let Some(prelude) = self.r.prelude { if let Some(prelude) = self.r.prelude {

View file

@ -954,7 +954,10 @@ pub struct Resolver<'a> {
arenas: &'a ResolverArenas<'a>, arenas: &'a ResolverArenas<'a>,
dummy_binding: &'a NameBinding<'a>, dummy_binding: &'a NameBinding<'a>,
crate_loader: CrateLoader<'a>, local_crate_name: Symbol,
metadata_loader: Box<MetadataLoaderDyn>,
cstore: CStore,
used_extern_options: FxHashSet<Symbol>,
macro_names: FxHashSet<Ident>, macro_names: FxHashSet<Ident>,
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
/// A small map keeping true kinds of built-in macros that appear to be fn-like on /// A small map keeping true kinds of built-in macros that appear to be fn-like on
@ -1129,7 +1132,7 @@ impl DefIdTree for ResolverTree<'_> {
impl<'a, 'b> DefIdTree for &'a Resolver<'b> { impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
#[inline] #[inline]
fn opt_parent(self, id: DefId) -> Option<DefId> { fn opt_parent(self, id: DefId) -> Option<DefId> {
ResolverTree(&self.definitions, self.cstore()).opt_parent(id) ResolverTree(&self.definitions, &self.cstore).opt_parent(id)
} }
} }
@ -1311,7 +1314,10 @@ impl<'a> Resolver<'a> {
vis: ty::Visibility::Public, vis: ty::Visibility::Public,
}), }),
crate_loader: CrateLoader::new(session, metadata_loader, crate_name), metadata_loader,
local_crate_name: crate_name,
used_extern_options: Default::default(),
cstore: CStore::new(session),
macro_names: FxHashSet::default(), macro_names: FxHashSet::default(),
builtin_macros: Default::default(), builtin_macros: Default::default(),
builtin_macro_kinds: Default::default(), builtin_macro_kinds: Default::default(),
@ -1403,7 +1409,7 @@ impl<'a> Resolver<'a> {
pub fn into_outputs(self) -> ResolverOutputs { pub fn into_outputs(self) -> ResolverOutputs {
let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
let definitions = self.definitions; let definitions = self.definitions;
let cstore = Box::new(self.crate_loader.into_cstore()); let cstore = Box::new(self.cstore);
let source_span = self.source_span; let source_span = self.source_span;
let expn_that_defined = self.expn_that_defined; let expn_that_defined = self.expn_that_defined;
let visibilities = self.visibilities; let visibilities = self.visibilities;
@ -1501,16 +1507,22 @@ impl<'a> Resolver<'a> {
} }
fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
StableHashingContext::new( StableHashingContext::new(self.session, &self.definitions, &self.cstore, &self.source_span)
self.session, }
pub fn crate_loader(&mut self) -> CrateLoader<'_> {
CrateLoader::new(
&self.session,
&*self.metadata_loader,
self.local_crate_name,
&mut self.cstore,
&self.definitions, &self.definitions,
self.crate_loader.cstore(), &mut self.used_extern_options,
&self.source_span,
) )
} }
pub fn cstore(&self) -> &CStore { pub fn cstore(&self) -> &CStore {
self.crate_loader.cstore() &self.cstore
} }
fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> { fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> {
@ -1553,7 +1565,7 @@ impl<'a> Resolver<'a> {
self.session.time("resolve_main", || self.resolve_main()); self.session.time("resolve_main", || self.resolve_main());
self.session.time("resolve_check_unused", || self.check_unused(krate)); self.session.time("resolve_check_unused", || self.check_unused(krate));
self.session.time("resolve_report_errors", || self.report_errors(krate)); self.session.time("resolve_report_errors", || self.report_errors(krate));
self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate)); self.session.time("resolve_postprocess", || self.crate_loader().postprocess(krate));
}); });
} }
@ -1871,10 +1883,10 @@ impl<'a> Resolver<'a> {
} else { } else {
let crate_id = if finalize { let crate_id = if finalize {
let Some(crate_id) = let Some(crate_id) =
self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); }; self.crate_loader().process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); };
crate_id crate_id
} else { } else {
self.crate_loader.maybe_process_path_extern(ident.name)? self.crate_loader().maybe_process_path_extern(ident.name)?
}; };
let crate_root = self.expect_module(crate_id.as_def_id()); let crate_root = self.expect_module(crate_id.as_def_id());
let vis = ty::Visibility::<LocalDefId>::Public; let vis = ty::Visibility::<LocalDefId>::Public;

View file

@ -455,7 +455,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
} }
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
self.crate_loader.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session) self.cstore.get_proc_macro_quoted_span_untracked(krate, id, self.session)
} }
fn declare_proc_macro(&mut self, id: NodeId) { fn declare_proc_macro(&mut self, id: NodeId) {