Separate resolver creation from expansion.

This commit is contained in:
Camille GILLOT 2021-05-24 18:45:21 +02:00
parent 5f98e5ee56
commit 18c10fb1a6
2 changed files with 38 additions and 57 deletions

View file

@ -110,12 +110,9 @@ mod boxed_resolver {
} }
impl BoxedResolver { impl BoxedResolver {
pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Result<(ast::Crate, Self)> pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Self
where where
F: for<'a> FnOnce( F: for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>,
&'a Session,
&'a ResolverArenas<'a>,
) -> Result<(ast::Crate, Resolver<'a>)>,
{ {
let mut boxed_resolver = Box::new(BoxedResolverInner { let mut boxed_resolver = Box::new(BoxedResolverInner {
session, session,
@ -127,14 +124,14 @@ mod boxed_resolver {
// returns a resolver with the same lifetime as the arena. We ensure that the arena // returns a resolver with the same lifetime as the arena. We ensure that the arena
// outlives the resolver in the drop impl and elsewhere so these transmutes are sound. // outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
unsafe { unsafe {
let (crate_, resolver) = make_resolver( let resolver = make_resolver(
std::mem::transmute::<&Session, &Session>(&boxed_resolver.session), std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>( std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
boxed_resolver.resolver_arenas.as_ref().unwrap(), boxed_resolver.resolver_arenas.as_ref().unwrap(),
), ),
)?; );
boxed_resolver.resolver = Some(resolver); boxed_resolver.resolver = Some(resolver);
Ok((crate_, BoxedResolver(Pin::new_unchecked(boxed_resolver)))) BoxedResolver(Pin::new_unchecked(boxed_resolver))
} }
} }
@ -165,35 +162,20 @@ mod boxed_resolver {
} }
} }
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins, pub fn create_resolver(
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
/// harness if one is to be provided, injection of a dependency on the
/// standard library and prelude, and name resolution.
///
/// Returns [`None`] if we're aborting after handling -W help.
pub fn configure_and_expand(
sess: Lrc<Session>, sess: Lrc<Session>,
lint_store: Lrc<LintStore>,
metadata_loader: Box<MetadataLoaderDyn>, metadata_loader: Box<MetadataLoaderDyn>,
krate: ast::Crate, krate: &ast::Crate,
crate_name: &str, crate_name: &str,
) -> Result<(ast::Crate, BoxedResolver)> { ) -> BoxedResolver {
tracing::trace!("configure_and_expand"); tracing::trace!("create_resolver");
// Currently, we ignore the name resolution data structures for the purposes of dependency // Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each // tracking. Instead we will run name resolution and include its output in the hash of each
// item, much like we do for macro expansion. In other words, the hash reflects not just // item, much like we do for macro expansion. In other words, the hash reflects not just
// its contents but the results of name resolution on those contents. Hopefully we'll push // its contents but the results of name resolution on those contents. Hopefully we'll push
// this back at some point. // this back at some point.
let crate_name = crate_name.to_string();
BoxedResolver::new(sess, move |sess, resolver_arenas| { BoxedResolver::new(sess, move |sess, resolver_arenas| {
configure_and_expand_inner( Resolver::new(sess, &krate, &crate_name, metadata_loader, &resolver_arenas)
sess,
&lint_store,
krate,
&crate_name,
&resolver_arenas,
metadata_loader,
)
}) })
} }
@ -278,28 +260,26 @@ fn pre_expansion_lint(
}); });
} }
fn configure_and_expand_inner<'a>( /// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
sess: &'a Session, /// syntax expansion, secondary `cfg` expansion, synthesis of a test
/// harness if one is to be provided, injection of a dependency on the
/// standard library and prelude, and name resolution.
///
/// Returns [`None`] if we're aborting after handling -W help.
pub fn configure_and_expand(
sess: &Session,
lint_store: &LintStore, lint_store: &LintStore,
mut krate: ast::Crate, mut krate: ast::Crate,
crate_name: &str, crate_name: &str,
resolver_arenas: &'a ResolverArenas<'a>, resolver: &mut Resolver<'_>,
metadata_loader: Box<MetadataLoaderDyn>, ) -> Result<ast::Crate> {
) -> Result<(ast::Crate, Resolver<'a>)> { tracing::trace!("configure_and_expand");
tracing::trace!("configure_and_expand_inner");
pre_expansion_lint(sess, lint_store, &krate, crate_name); pre_expansion_lint(sess, lint_store, &krate, crate_name);
rustc_builtin_macros::register_builtin_macros(resolver);
let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas);
rustc_builtin_macros::register_builtin_macros(&mut resolver);
krate = sess.time("crate_injection", || { krate = sess.time("crate_injection", || {
let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s)); let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s));
rustc_builtin_macros::standard_library_imports::inject( rustc_builtin_macros::standard_library_imports::inject(krate, resolver, &sess, alt_std_name)
krate,
&mut resolver,
&sess,
alt_std_name,
)
}); });
util::check_attr_crate_type(&sess, &krate.attrs, &mut resolver.lint_buffer()); util::check_attr_crate_type(&sess, &krate.attrs, &mut resolver.lint_buffer());
@ -354,7 +334,7 @@ fn configure_and_expand_inner<'a>(
pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str()); pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str());
(krate.attrs, krate.items) (krate.attrs, krate.items)
}; };
let mut ecx = ExtCtxt::new(&sess, cfg, &mut resolver, Some(&extern_mod_loaded)); let mut ecx = ExtCtxt::new(&sess, cfg, resolver, Some(&extern_mod_loaded));
// Expand macros now! // Expand macros now!
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate)); let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
@ -396,16 +376,16 @@ fn configure_and_expand_inner<'a>(
})?; })?;
sess.time("maybe_building_test_harness", || { sess.time("maybe_building_test_harness", || {
rustc_builtin_macros::test_harness::inject(&sess, &mut resolver, &mut krate) rustc_builtin_macros::test_harness::inject(&sess, resolver, &mut krate)
}); });
if let Some(PpMode::Source(PpSourceMode::EveryBodyLoops)) = sess.opts.pretty { if let Some(PpMode::Source(PpSourceMode::EveryBodyLoops)) = sess.opts.pretty {
tracing::debug!("replacing bodies with loop {{}}"); tracing::debug!("replacing bodies with loop {{}}");
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate); util::ReplaceBodyWithLoop::new(resolver).visit_crate(&mut krate);
} }
let has_proc_macro_decls = sess.time("AST_validation", || { let has_proc_macro_decls = sess.time("AST_validation", || {
rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer()) rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
}); });
let crate_types = sess.crate_types(); let crate_types = sess.crate_types();
@ -431,7 +411,7 @@ fn configure_and_expand_inner<'a>(
let is_test_crate = sess.opts.test; let is_test_crate = sess.opts.test;
rustc_builtin_macros::proc_macro_harness::inject( rustc_builtin_macros::proc_macro_harness::inject(
&sess, &sess,
&mut resolver, resolver,
krate, krate,
is_proc_macro_crate, is_proc_macro_crate,
has_proc_macro_decls, has_proc_macro_decls,
@ -471,7 +451,7 @@ fn configure_and_expand_inner<'a>(
} }
}); });
Ok((krate, resolver)) Ok(krate)
} }
pub fn lower_to_hir<'res, 'tcx>( pub fn lower_to_hir<'res, 'tcx>(

View file

@ -177,16 +177,17 @@ impl<'tcx> Queries<'tcx> {
let crate_name = self.crate_name()?.peek().clone(); let crate_name = self.crate_name()?.peek().clone();
let (krate, lint_store) = self.register_plugins()?.take(); let (krate, lint_store) = self.register_plugins()?.take();
let _timer = self.session().timer("configure_and_expand"); let _timer = self.session().timer("configure_and_expand");
passes::configure_and_expand( let sess = self.session();
self.session().clone(), let mut resolver = passes::create_resolver(
lint_store.clone(), sess.clone(),
self.codegen_backend().metadata_loader(), self.codegen_backend().metadata_loader(),
krate, &krate,
&crate_name, &crate_name,
) );
.map(|(krate, resolver)| { let krate = resolver.access(|resolver| {
(krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store) passes::configure_and_expand(&sess, &lint_store, krate, &crate_name, resolver)
}) })?;
Ok((krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store))
}) })
} }