Auto merge of #86489 - cjgillot:lower, r=petrochenkov

Simplify early compilation interface

* separate resolver creation and AST configuration.
* bundle lowering with global_ctxt creation.
This commit is contained in:
bors 2021-06-30 22:20:36 +00:00
commit e6f450bcfe
7 changed files with 106 additions and 173 deletions

View file

@ -296,7 +296,7 @@ pub fn lower_crate<'a, 'hir>(
resolver: &'a mut dyn ResolverAstLowering, resolver: &'a mut dyn ResolverAstLowering,
nt_to_tokenstream: NtToTokenstream, nt_to_tokenstream: NtToTokenstream,
arena: &'hir Arena<'hir>, arena: &'hir Arena<'hir>,
) -> hir::Crate<'hir> { ) -> &'hir hir::Crate<'hir> {
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
LoweringContext { LoweringContext {
@ -403,7 +403,7 @@ enum AnonymousLifetimeMode {
} }
impl<'a, 'hir> LoweringContext<'a, 'hir> { impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> { fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
/// Full-crate AST visitor that inserts into a fresh /// Full-crate AST visitor that inserts into a fresh
/// `LoweringContext` any information that may be /// `LoweringContext` any information that may be
/// needed from arbitrary locations in the crate, /// needed from arbitrary locations in the crate,
@ -530,7 +530,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
hir::Crate { let krate = hir::Crate {
item: module, item: module,
exported_macros: self.arena.alloc_from_iter(self.exported_macros), exported_macros: self.arena.alloc_from_iter(self.exported_macros),
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs), non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
@ -545,7 +545,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
proc_macros, proc_macros,
trait_map, trait_map,
attrs: self.attrs, attrs: self.attrs,
} };
self.arena.alloc(krate)
} }
fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId { fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {

View file

@ -46,7 +46,6 @@ use std::ffi::OsString;
use std::fs; use std::fs;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::lazy::SyncLazy; use std::lazy::SyncLazy;
use std::mem;
use std::panic::{self, catch_unwind}; use std::panic::{self, catch_unwind};
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{self, Command, Stdio}; use std::process::{self, Command, Stdio};
@ -316,12 +315,12 @@ fn run_compiler(
if let Some(ppm) = &sess.opts.pretty { if let Some(ppm) = &sess.opts.pretty {
if ppm.needs_ast_map() { if ppm.needs_ast_map() {
let expanded_crate = queries.expansion()?.peek().0.clone();
queries.global_ctxt()?.peek_mut().enter(|tcx| { queries.global_ctxt()?.peek_mut().enter(|tcx| {
let expanded_crate = queries.expansion()?.take().0;
pretty::print_after_hir_lowering( pretty::print_after_hir_lowering(
tcx, tcx,
compiler.input(), compiler.input(),
&expanded_crate, &*expanded_crate,
*ppm, *ppm,
compiler.output_file().as_ref().map(|p| &**p), compiler.output_file().as_ref().map(|p| &**p),
); );
@ -377,12 +376,6 @@ fn run_compiler(
queries.global_ctxt()?; queries.global_ctxt()?;
// Drop AST after creating GlobalCtxt to free memory
{
let _timer = sess.prof.generic_activity("drop_ast");
mem::drop(queries.expansion()?.take());
}
if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json {
return early_exit(); return early_exit();
} }

View file

@ -21,8 +21,8 @@ pub enum LoadResult<T> {
Error { message: String }, Error { message: String },
} }
impl LoadResult<(SerializedDepGraph, WorkProductMap)> { impl<T: Default> LoadResult<T> {
pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) { pub fn open(self, sess: &Session) -> T {
match self { match self {
LoadResult::Error { message } => { LoadResult::Error { message } => {
sess.warn(&message); sess.warn(&message);
@ -74,11 +74,14 @@ pub enum MaybeAsync<T> {
Sync(T), Sync(T),
Async(std::thread::JoinHandle<T>), Async(std::thread::JoinHandle<T>),
} }
impl<T> MaybeAsync<T> {
pub fn open(self) -> std::thread::Result<T> { impl<T> MaybeAsync<LoadResult<T>> {
pub fn open(self) -> LoadResult<T> {
match self { match self {
MaybeAsync::Sync(result) => Ok(result), MaybeAsync::Sync(result) => result,
MaybeAsync::Async(handle) => handle.join(), MaybeAsync::Async(handle) => handle.join().unwrap_or_else(|e| LoadResult::Error {
message: format!("could not decode incremental cache: {:?}", e),
}),
} }
} }
} }

View file

@ -7,7 +7,6 @@ use rustc_ast::{self as ast, visit};
use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_ssa::back::link::emit_metadata;
use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel; use rustc_data_structures::parallel;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal}; use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{ErrorReported, PResult}; use rustc_errors::{ErrorReported, PResult};
@ -101,7 +100,7 @@ mod boxed_resolver {
} }
// Note: Drop order is important to prevent dangling references. Resolver must be dropped first, // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
// then resolver_arenas and finally session. // then resolver_arenas and session.
impl Drop for BoxedResolverInner { impl Drop for BoxedResolverInner {
fn drop(&mut self) { fn drop(&mut self) {
self.resolver.take(); self.resolver.take();
@ -110,13 +109,10 @@ 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(
where session: Lrc<Session>,
F: for<'a> FnOnce( make_resolver: impl for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>,
&'a Session, ) -> BoxedResolver {
&'a ResolverArenas<'a>,
) -> Result<(ast::Crate, Resolver<'a>)>,
{
let mut boxed_resolver = Box::new(BoxedResolverInner { let mut boxed_resolver = Box::new(BoxedResolverInner {
session, session,
resolver_arenas: Some(Resolver::arenas()), resolver_arenas: Some(Resolver::arenas()),
@ -127,14 +123,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 +161,15 @@ 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
// 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
// its contents but the results of name resolution on those contents. Hopefully we'll push
// 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 +254,24 @@ 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.
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 +326,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 +368,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 +403,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,26 +443,20 @@ 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>(
sess: &'tcx Session, sess: &'tcx Session,
lint_store: &LintStore, lint_store: &LintStore,
resolver: &'res mut Resolver<'_>, resolver: &'res mut Resolver<'_>,
dep_graph: &'res DepGraph, krate: Rc<ast::Crate>,
krate: &'res ast::Crate,
arena: &'tcx rustc_ast_lowering::Arena<'tcx>, arena: &'tcx rustc_ast_lowering::Arena<'tcx>,
) -> Crate<'tcx> { ) -> &'tcx Crate<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
// Lower AST to HIR. // Lower AST to HIR.
let hir_crate = rustc_ast_lowering::lower_crate( let hir_crate = rustc_ast_lowering::lower_crate(
sess, sess,
&krate, &*krate,
resolver, resolver,
rustc_parse::nt_to_tokenstream, rustc_parse::nt_to_tokenstream,
arena, arena,
@ -511,6 +477,9 @@ pub fn lower_to_hir<'res, 'tcx>(
) )
}); });
// Drop AST to free memory
sess.time("drop_ast", || std::mem::drop(krate));
// Discard hygiene data, which isn't required after lowering to HIR. // Discard hygiene data, which isn't required after lowering to HIR.
if !sess.opts.debugging_opts.keep_hygiene_data { if !sess.opts.debugging_opts.keep_hygiene_data {
rustc_span::hygiene::clear_syntax_context_map(); rustc_span::hygiene::clear_syntax_context_map();
@ -603,7 +572,7 @@ fn escape_dep_env(symbol: Symbol) -> String {
fn write_out_deps( fn write_out_deps(
sess: &Session, sess: &Session,
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>, boxed_resolver: &RefCell<BoxedResolver>,
outputs: &OutputFilenames, outputs: &OutputFilenames,
out_filenames: &[PathBuf], out_filenames: &[PathBuf],
) { ) {
@ -630,7 +599,7 @@ fn write_out_deps(
} }
if sess.binary_dep_depinfo() { if sess.binary_dep_depinfo() {
boxed_resolver.borrow().borrow_mut().access(|resolver| { boxed_resolver.borrow_mut().access(|resolver| {
for cnum in resolver.cstore().crates_untracked() { for cnum in resolver.cstore().crates_untracked() {
let source = resolver.cstore().crate_source_untracked(cnum); let source = resolver.cstore().crate_source_untracked(cnum);
if let Some((path, _)) = source.dylib { if let Some((path, _)) = source.dylib {
@ -699,7 +668,7 @@ pub fn prepare_outputs(
sess: &Session, sess: &Session,
compiler: &Compiler, compiler: &Compiler,
krate: &ast::Crate, krate: &ast::Crate,
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>, boxed_resolver: &RefCell<BoxedResolver>,
crate_name: &str, crate_name: &str,
) -> Result<OutputFilenames> { ) -> Result<OutputFilenames> {
let _timer = sess.timer("prepare_outputs"); let _timer = sess.timer("prepare_outputs");
@ -803,16 +772,26 @@ impl<'tcx> QueryContext<'tcx> {
pub fn create_global_ctxt<'tcx>( pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler, compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>, lint_store: Lrc<LintStore>,
krate: &'tcx Crate<'tcx>, krate: Rc<ast::Crate>,
dep_graph: DepGraph, dep_graph: DepGraph,
resolver_outputs: ResolverOutputs, resolver: Rc<RefCell<BoxedResolver>>,
outputs: OutputFilenames, outputs: OutputFilenames,
crate_name: &str, crate_name: &str,
queries: &'tcx OnceCell<TcxQueries<'tcx>>, queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>, global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>, arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
) -> QueryContext<'tcx> { ) -> QueryContext<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
dep_graph.assert_ignored();
let sess = &compiler.session(); let sess = &compiler.session();
let krate = resolver
.borrow_mut()
.access(|resolver| lower_to_hir(sess, &lint_store, resolver, krate, hir_arena));
let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver);
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
@ -831,7 +810,7 @@ pub fn create_global_ctxt<'tcx>(
let queries = queries.get_or_init(|| TcxQueries::new(local_providers, extern_providers)); let queries = queries.get_or_init(|| TcxQueries::new(local_providers, extern_providers));
let gcx = sess.time("setup_global_ctxt", || { let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(|| { global_ctxt.get_or_init(move || {
TyCtxt::create_global_ctxt( TyCtxt::create_global_ctxt(
sess, sess,
lint_store, lint_store,

View file

@ -3,17 +3,15 @@ use crate::passes::{self, BoxedResolver, QueryContext};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::Crate;
use rustc_incremental::DepGraphFuture; use rustc_incremental::DepGraphFuture;
use rustc_lint::LintStore; use rustc_lint::LintStore;
use rustc_middle::arena::Arena; use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph; use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc_middle::ty::{GlobalCtxt, TyCtxt};
use rustc_query_impl::Queries as TcxQueries; use rustc_query_impl::Queries as TcxQueries;
use rustc_serialize::json; use rustc_serialize::json;
use rustc_session::config::{self, OutputFilenames, OutputType}; use rustc_session::config::{self, OutputFilenames, OutputType};
@ -81,9 +79,8 @@ pub struct Queries<'tcx> {
parse: Query<ast::Crate>, parse: Query<ast::Crate>,
crate_name: Query<String>, crate_name: Query<String>,
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>, register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>, expansion: Query<(Rc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>, dep_graph: Query<DepGraph>,
lower_to_hir: Query<(&'tcx Crate<'tcx>, Steal<ResolverOutputs>)>,
prepare_outputs: Query<OutputFilenames>, prepare_outputs: Query<OutputFilenames>,
global_ctxt: Query<QueryContext<'tcx>>, global_ctxt: Query<QueryContext<'tcx>>,
ongoing_codegen: Query<Box<dyn Any>>, ongoing_codegen: Query<Box<dyn Any>>,
@ -103,7 +100,6 @@ impl<'tcx> Queries<'tcx> {
register_plugins: Default::default(), register_plugins: Default::default(),
expansion: Default::default(), expansion: Default::default(),
dep_graph: Default::default(), dep_graph: Default::default(),
lower_to_hir: Default::default(),
prepare_outputs: Default::default(), prepare_outputs: Default::default(),
global_ctxt: Default::default(), global_ctxt: Default::default(),
ongoing_codegen: Default::default(), ongoing_codegen: Default::default(),
@ -117,13 +113,10 @@ impl<'tcx> Queries<'tcx> {
&self.compiler.codegen_backend() &self.compiler.codegen_backend()
} }
pub fn dep_graph_future(&self) -> Result<&Query<Option<DepGraphFuture>>> { fn dep_graph_future(&self) -> Result<&Query<Option<DepGraphFuture>>> {
self.dep_graph_future.compute(|| { self.dep_graph_future.compute(|| {
Ok(self let sess = self.session();
.session() Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess)))
.opts
.build_dep_graph()
.then(|| rustc_incremental::load_dep_graph(self.session())))
}) })
} }
@ -174,83 +167,51 @@ impl<'tcx> Queries<'tcx> {
pub fn expansion( pub fn expansion(
&self, &self,
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> { ) -> Result<&Query<(Rc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>> {
tracing::trace!("expansion"); tracing::trace!("expansion");
self.expansion.compute(|| { self.expansion.compute(|| {
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,
&crate_name,
)
.map(|(krate, resolver)| {
(krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)
})
})
}
pub fn dep_graph(&self) -> Result<&Query<DepGraph>> {
self.dep_graph.compute(|| {
Ok(match self.dep_graph_future()?.take() {
None => DepGraph::new_disabled(),
Some(future) => {
let (prev_graph, prev_work_products) =
self.session().time("blocked_on_dep_graph_loading", || {
future
.open()
.unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
message: format!("could not decode incremental cache: {:?}", e),
})
.open(self.session())
});
rustc_incremental::build_dep_graph(
self.session(),
prev_graph,
prev_work_products,
)
.unwrap_or_else(DepGraph::new_disabled)
}
})
})
}
pub fn lower_to_hir(&'tcx self) -> Result<&Query<(&'tcx Crate<'tcx>, Steal<ResolverOutputs>)>> {
self.lower_to_hir.compute(|| {
let expansion_result = self.expansion()?;
let peeked = expansion_result.peek();
let krate = &peeked.0;
let resolver = peeked.1.steal();
let lint_store = &peeked.2;
let hir = resolver.borrow_mut().access(|resolver| {
Ok(passes::lower_to_hir(
self.session(),
lint_store,
resolver,
&*self.dep_graph()?.peek(),
&krate, &krate,
&self.hir_arena, &crate_name,
)) );
let krate = resolver.access(|resolver| {
passes::configure_and_expand(&sess, &lint_store, krate, &crate_name, resolver)
})?; })?;
let hir = self.hir_arena.alloc(hir); Ok((Rc::new(krate), Rc::new(RefCell::new(resolver)), lint_store))
Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) })
}
fn dep_graph(&self) -> Result<&Query<DepGraph>> {
self.dep_graph.compute(|| {
let sess = self.session();
let future_opt = self.dep_graph_future()?.take();
let dep_graph = future_opt
.and_then(|future| {
let (prev_graph, prev_work_products) =
sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
})
.unwrap_or_else(DepGraph::new_disabled);
Ok(dep_graph)
}) })
} }
pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> { pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
self.prepare_outputs.compute(|| { self.prepare_outputs.compute(|| {
let expansion_result = self.expansion()?; let (krate, boxed_resolver, _) = &*self.expansion()?.peek();
let (krate, boxed_resolver, _) = &*expansion_result.peek();
let crate_name = self.crate_name()?.peek(); let crate_name = self.crate_name()?.peek();
passes::prepare_outputs( passes::prepare_outputs(
self.session(), self.session(),
self.compiler, self.compiler,
&krate, krate,
&boxed_resolver, &*boxed_resolver,
&crate_name, &crate_name,
) )
}) })
@ -260,22 +221,20 @@ impl<'tcx> Queries<'tcx> {
self.global_ctxt.compute(|| { self.global_ctxt.compute(|| {
let crate_name = self.crate_name()?.peek().clone(); let crate_name = self.crate_name()?.peek().clone();
let outputs = self.prepare_outputs()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone();
let lint_store = self.expansion()?.peek().2.clone();
let hir = self.lower_to_hir()?.peek();
let dep_graph = self.dep_graph()?.peek().clone(); let dep_graph = self.dep_graph()?.peek().clone();
let (ref krate, ref resolver_outputs) = &*hir; let (krate, resolver, lint_store) = self.expansion()?.take();
let _timer = self.session().timer("create_global_ctxt");
Ok(passes::create_global_ctxt( Ok(passes::create_global_ctxt(
self.compiler, self.compiler,
lint_store, lint_store,
krate, krate,
dep_graph, dep_graph,
resolver_outputs.steal(), resolver,
outputs, outputs,
&crate_name, &crate_name,
&self.queries, &self.queries,
&self.gcx, &self.gcx,
&self.arena, &self.arena,
&self.hir_arena,
)) ))
}) })
} }

View file

@ -303,9 +303,8 @@ crate fn create_resolver<'a>(
queries: &Queries<'a>, queries: &Queries<'a>,
sess: &Session, sess: &Session,
) -> Rc<RefCell<interface::BoxedResolver>> { ) -> Rc<RefCell<interface::BoxedResolver>> {
let parts = abort_on_err(queries.expansion(), sess).peek(); let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
let (krate, resolver, _) = &*parts; let resolver = resolver.clone();
let resolver = resolver.borrow().clone();
let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver); let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver);
ast::visit::walk_crate(&mut loader, krate); ast::visit::walk_crate(&mut loader, krate);

View file

@ -112,7 +112,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
let res = interface::run_compiler(config, |compiler| { let res = interface::run_compiler(config, |compiler| {
compiler.enter(|queries| { compiler.enter(|queries| {
let _lower_to_hir = queries.lower_to_hir()?;
let mut global_ctxt = queries.global_ctxt()?.take(); let mut global_ctxt = queries.global_ctxt()?.take();
let collector = global_ctxt.enter(|tcx| { let collector = global_ctxt.enter(|tcx| {