From 5f98e5ee5613abe3d8c2439af52d399bd6e98949 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 24 May 2021 19:24:58 +0200 Subject: [PATCH 1/8] Simplify DepGraph creation. --- .../rustc_incremental/src/persist/load.rs | 15 +++++--- compiler/rustc_interface/src/queries.rs | 37 ++++++------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 8539cc6937139..ee62089b23760 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -21,8 +21,8 @@ pub enum LoadResult { Error { message: String }, } -impl LoadResult<(SerializedDepGraph, WorkProductMap)> { - pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) { +impl LoadResult { + pub fn open(self, sess: &Session) -> T { match self { LoadResult::Error { message } => { sess.warn(&message); @@ -74,11 +74,14 @@ pub enum MaybeAsync { Sync(T), Async(std::thread::JoinHandle), } -impl MaybeAsync { - pub fn open(self) -> std::thread::Result { + +impl MaybeAsync> { + pub fn open(self) -> LoadResult { match self { - MaybeAsync::Sync(result) => Ok(result), - MaybeAsync::Async(handle) => handle.join(), + MaybeAsync::Sync(result) => result, + MaybeAsync::Async(handle) => handle.join().unwrap_or_else(|e| LoadResult::Error { + message: format!("could not decode incremental cache: {:?}", e), + }), } } } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 2320f0b47d27d..e37a0347dcb98 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -119,11 +119,8 @@ impl<'tcx> Queries<'tcx> { pub fn dep_graph_future(&self) -> Result<&Query>> { self.dep_graph_future.compute(|| { - Ok(self - .session() - .opts - .build_dep_graph() - .then(|| rustc_incremental::load_dep_graph(self.session()))) + let sess = self.session(); + Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess))) }) } @@ -195,27 +192,17 @@ impl<'tcx> Queries<'tcx> { pub fn dep_graph(&self) -> Result<&Query> { self.dep_graph.compute(|| { - Ok(match self.dep_graph_future()?.take() { - None => DepGraph::new_disabled(), - Some(future) => { + 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) = - 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) - } - }) + 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) }) } From 18c10fb1a6cd9b5d233c2b45b5bc55967cfded72 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 24 May 2021 18:45:21 +0200 Subject: [PATCH 2/8] Separate resolver creation from expansion. --- compiler/rustc_interface/src/passes.rs | 78 +++++++++---------------- compiler/rustc_interface/src/queries.rs | 17 +++--- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4abc4b29b50e5..4f7b0aea8436f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -110,12 +110,9 @@ mod boxed_resolver { } impl BoxedResolver { - pub(super) fn new(session: Lrc, make_resolver: F) -> Result<(ast::Crate, Self)> + pub(super) fn new(session: Lrc, make_resolver: F) -> Self where - F: for<'a> FnOnce( - &'a Session, - &'a ResolverArenas<'a>, - ) -> Result<(ast::Crate, Resolver<'a>)>, + F: for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>, { let mut boxed_resolver = Box::new(BoxedResolverInner { session, @@ -127,14 +124,14 @@ mod boxed_resolver { // 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. unsafe { - let (crate_, resolver) = make_resolver( + let resolver = make_resolver( std::mem::transmute::<&Session, &Session>(&boxed_resolver.session), std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>( boxed_resolver.resolver_arenas.as_ref().unwrap(), ), - )?; + ); 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, -/// 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( +pub fn create_resolver( sess: Lrc, - lint_store: Lrc, metadata_loader: Box, - krate: ast::Crate, + krate: &ast::Crate, crate_name: &str, -) -> Result<(ast::Crate, BoxedResolver)> { - tracing::trace!("configure_and_expand"); +) -> BoxedResolver { + 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| { - configure_and_expand_inner( - sess, - &lint_store, - krate, - &crate_name, - &resolver_arenas, - metadata_loader, - ) + Resolver::new(sess, &krate, &crate_name, metadata_loader, &resolver_arenas) }) } @@ -278,28 +260,26 @@ fn pre_expansion_lint( }); } -fn configure_and_expand_inner<'a>( - sess: &'a Session, +/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins, +/// 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, mut krate: ast::Crate, crate_name: &str, - resolver_arenas: &'a ResolverArenas<'a>, - metadata_loader: Box, -) -> Result<(ast::Crate, Resolver<'a>)> { - tracing::trace!("configure_and_expand_inner"); + resolver: &mut Resolver<'_>, +) -> Result { + tracing::trace!("configure_and_expand"); pre_expansion_lint(sess, lint_store, &krate, crate_name); - - let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas); - rustc_builtin_macros::register_builtin_macros(&mut resolver); + rustc_builtin_macros::register_builtin_macros(resolver); krate = sess.time("crate_injection", || { let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s)); - rustc_builtin_macros::standard_library_imports::inject( - krate, - &mut resolver, - &sess, - alt_std_name, - ) + rustc_builtin_macros::standard_library_imports::inject(krate, resolver, &sess, alt_std_name) }); 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()); (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! 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", || { - 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 { 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", || { - 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(); @@ -431,7 +411,7 @@ fn configure_and_expand_inner<'a>( let is_test_crate = sess.opts.test; rustc_builtin_macros::proc_macro_harness::inject( &sess, - &mut resolver, + resolver, krate, is_proc_macro_crate, 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>( diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index e37a0347dcb98..1f0ef553e5dad 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -177,16 +177,17 @@ impl<'tcx> Queries<'tcx> { let crate_name = self.crate_name()?.peek().clone(); let (krate, lint_store) = self.register_plugins()?.take(); let _timer = self.session().timer("configure_and_expand"); - passes::configure_and_expand( - self.session().clone(), - lint_store.clone(), + let sess = self.session(); + let mut resolver = passes::create_resolver( + sess.clone(), self.codegen_backend().metadata_loader(), - krate, + &krate, &crate_name, - ) - .map(|(krate, resolver)| { - (krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store) - }) + ); + let krate = resolver.access(|resolver| { + passes::configure_and_expand(&sess, &lint_store, krate, &crate_name, resolver) + })?; + Ok((krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)) }) } From b80f720a2af0ccad54a1236063888aa9418cdf0f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 23 May 2021 21:30:03 +0200 Subject: [PATCH 3/8] Inline lower_to_hir. --- compiler/rustc_interface/src/passes.rs | 1 + compiler/rustc_interface/src/queries.rs | 51 +++++++++---------------- src/librustdoc/doctest.rs | 1 - 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4f7b0aea8436f..5ef2b11fffd39 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -793,6 +793,7 @@ pub fn create_global_ctxt<'tcx>( arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); + let _timer = sess.timer("create_global_ctxt"); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 1f0ef553e5dad..6d887cce764d4 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -8,12 +8,11 @@ use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::ErrorReported; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_hir::Crate; use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; use rustc_middle::arena::Arena; 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_serialize::json; use rustc_session::config::{self, OutputFilenames, OutputType}; @@ -83,7 +82,6 @@ pub struct Queries<'tcx> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(&'tcx Crate<'tcx>, Steal)>, prepare_outputs: Query, global_ctxt: Query>, ongoing_codegen: Query>, @@ -103,7 +101,6 @@ impl<'tcx> Queries<'tcx> { register_plugins: Default::default(), expansion: Default::default(), dep_graph: Default::default(), - lower_to_hir: Default::default(), prepare_outputs: Default::default(), global_ctxt: Default::default(), ongoing_codegen: Default::default(), @@ -117,7 +114,7 @@ impl<'tcx> Queries<'tcx> { &self.compiler.codegen_backend() } - pub fn dep_graph_future(&self) -> Result<&Query>> { + fn dep_graph_future(&self) -> Result<&Query>> { self.dep_graph_future.compute(|| { let sess = self.session(); Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess))) @@ -191,7 +188,7 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn dep_graph(&self) -> Result<&Query> { + fn dep_graph(&self) -> Result<&Query> { self.dep_graph.compute(|| { let sess = self.session(); let future_opt = self.dep_graph_future()?.take(); @@ -207,28 +204,6 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn lower_to_hir(&'tcx self) -> Result<&Query<(&'tcx Crate<'tcx>, Steal)>> { - 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, - &self.hir_arena, - )) - })?; - let hir = self.hir_arena.alloc(hir); - Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) - }) - } - pub fn prepare_outputs(&self) -> Result<&Query> { self.prepare_outputs.compute(|| { let expansion_result = self.expansion()?; @@ -248,14 +223,24 @@ impl<'tcx> Queries<'tcx> { self.global_ctxt.compute(|| { let crate_name = self.crate_name()?.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 (ref krate, ref resolver, ref lint_store) = &*self.expansion()?.peek(); + let resolver = resolver.steal(); let dep_graph = self.dep_graph()?.peek().clone(); - let (ref krate, ref resolver_outputs) = &*hir; - let _timer = self.session().timer("create_global_ctxt"); + let krate = resolver.borrow_mut().access(|resolver| { + Ok(passes::lower_to_hir( + self.session(), + lint_store, + resolver, + &dep_graph, + &krate, + &self.hir_arena, + )) + })?; + let krate = self.hir_arena.alloc(krate); + let resolver_outputs = Steal::new(BoxedResolver::to_resolver_outputs(resolver)); Ok(passes::create_global_ctxt( self.compiler, - lint_store, + lint_store.clone(), krate, dep_graph, resolver_outputs.steal(), diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 7aa54241450f7..1281f76fd0fdc 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -112,7 +112,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { let res = interface::run_compiler(config, |compiler| { compiler.enter(|queries| { - let _lower_to_hir = queries.lower_to_hir()?; let mut global_ctxt = queries.global_ctxt()?.take(); let collector = global_ctxt.enter(|tcx| { From e05cd155feaafec2b94cd11083e8425094ad8806 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 23 May 2021 21:42:16 +0200 Subject: [PATCH 4/8] Move lowering to create_global_ctxt. --- compiler/rustc_interface/src/passes.rs | 24 ++++++++++++++---------- compiler/rustc_interface/src/queries.rs | 16 ++-------------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5ef2b11fffd39..e08c8faaa52bb 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -458,15 +458,9 @@ pub fn lower_to_hir<'res, 'tcx>( sess: &'tcx Session, lint_store: &LintStore, resolver: &'res mut Resolver<'_>, - dep_graph: &'res DepGraph, krate: &'res ast::Crate, arena: &'tcx rustc_ast_lowering::Arena<'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. let hir_crate = rustc_ast_lowering::lower_crate( sess, @@ -783,17 +777,27 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, - krate: &'tcx Crate<'tcx>, + krate: &ast::Crate, dep_graph: DepGraph, - resolver_outputs: ResolverOutputs, + resolver: Rc>, outputs: OutputFilenames, crate_name: &str, queries: &'tcx OnceCell>, global_ctxt: &'tcx OnceCell>, arena: &'tcx WorkerLocal>, + hir_arena: &'tcx WorkerLocal>, ) -> 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 _timer = sess.timer("create_global_ctxt"); + let krate = resolver + .borrow_mut() + .access(|resolver| lower_to_hir(sess, &lint_store, resolver, krate, hir_arena)); + let krate = &*hir_arena.alloc(krate); + let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); @@ -812,7 +816,7 @@ pub fn create_global_ctxt<'tcx>( let queries = queries.get_or_init(|| TcxQueries::new(local_providers, extern_providers)); let gcx = sess.time("setup_global_ctxt", || { - global_ctxt.get_or_init(|| { + global_ctxt.get_or_init(move || { TyCtxt::create_global_ctxt( sess, lint_store, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 6d887cce764d4..7b284e206e2bf 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -224,31 +224,19 @@ impl<'tcx> Queries<'tcx> { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); let (ref krate, ref resolver, ref lint_store) = &*self.expansion()?.peek(); - let resolver = resolver.steal(); let dep_graph = self.dep_graph()?.peek().clone(); - let krate = resolver.borrow_mut().access(|resolver| { - Ok(passes::lower_to_hir( - self.session(), - lint_store, - resolver, - &dep_graph, - &krate, - &self.hir_arena, - )) - })?; - let krate = self.hir_arena.alloc(krate); - let resolver_outputs = Steal::new(BoxedResolver::to_resolver_outputs(resolver)); Ok(passes::create_global_ctxt( self.compiler, lint_store.clone(), krate, dep_graph, - resolver_outputs.steal(), + resolver.steal(), outputs, &crate_name, &self.queries, &self.gcx, &self.arena, + &self.hir_arena, )) }) } From c520cf225310e0d1d3ebf513034255cee3f76e30 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 11 Jun 2021 18:55:14 +0200 Subject: [PATCH 5/8] Arena-allocate Crate during lowering. --- compiler/rustc_ast_lowering/src/lib.rs | 9 +++++---- compiler/rustc_interface/src/passes.rs | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9592c1d2fabff..7a4e39376a86d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -296,7 +296,7 @@ pub fn lower_crate<'a, 'hir>( resolver: &'a mut dyn ResolverAstLowering, nt_to_tokenstream: NtToTokenstream, arena: &'hir Arena<'hir>, -) -> hir::Crate<'hir> { +) -> &'hir hir::Crate<'hir> { let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); LoweringContext { @@ -403,7 +403,7 @@ enum AnonymousLifetimeMode { } 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 /// `LoweringContext` any information that may be /// 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, exported_macros: self.arena.alloc_from_iter(self.exported_macros), 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, trait_map, attrs: self.attrs, - } + }; + self.arena.alloc(krate) } fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index e08c8faaa52bb..f5a085250a608 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -460,7 +460,7 @@ pub fn lower_to_hir<'res, 'tcx>( resolver: &'res mut Resolver<'_>, krate: &'res ast::Crate, arena: &'tcx rustc_ast_lowering::Arena<'tcx>, -) -> Crate<'tcx> { +) -> &'tcx Crate<'tcx> { // Lower AST to HIR. let hir_crate = rustc_ast_lowering::lower_crate( sess, @@ -796,7 +796,6 @@ pub fn create_global_ctxt<'tcx>( let krate = resolver .borrow_mut() .access(|resolver| lower_to_hir(sess, &lint_store, resolver, krate, hir_arena)); - let krate = &*hir_arena.alloc(krate); let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); From 2f28737ebea5a330b9fd95b67d0f5fa6a7dac7cf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 11 Jun 2021 18:55:30 +0200 Subject: [PATCH 6/8] Move AST crate. --- compiler/rustc_driver/src/lib.rs | 11 ++--------- compiler/rustc_interface/src/passes.rs | 14 ++++++++------ compiler/rustc_interface/src/queries.rs | 20 +++++++++----------- src/librustdoc/core.rs | 5 ++--- 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 35a6495946ff0..2733cd2990954 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -46,7 +46,6 @@ use std::ffi::OsString; use std::fs; use std::io::{self, Read, Write}; use std::lazy::SyncLazy; -use std::mem; use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; @@ -316,12 +315,12 @@ fn run_compiler( if let Some(ppm) = &sess.opts.pretty { if ppm.needs_ast_map() { + let expanded_crate = { &queries.expansion()?.peek().0 }; queries.global_ctxt()?.peek_mut().enter(|tcx| { - let expanded_crate = queries.expansion()?.take().0; pretty::print_after_hir_lowering( tcx, compiler.input(), - &expanded_crate, + expanded_crate, *ppm, compiler.output_file().as_ref().map(|p| &**p), ); @@ -377,12 +376,6 @@ fn run_compiler( 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 { return early_exit(); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f5a085250a608..98394bee22c42 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -7,7 +7,6 @@ use rustc_ast::{self as ast, visit}; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_ssa::traits::CodegenBackend; 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::temp_dir::MaybeTempDir; use rustc_errors::{ErrorReported, PResult}; @@ -458,7 +457,7 @@ pub fn lower_to_hir<'res, 'tcx>( sess: &'tcx Session, lint_store: &LintStore, resolver: &'res mut Resolver<'_>, - krate: &'res ast::Crate, + krate: ast::Crate, arena: &'tcx rustc_ast_lowering::Arena<'tcx>, ) -> &'tcx Crate<'tcx> { // Lower AST to HIR. @@ -485,6 +484,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. if !sess.opts.debugging_opts.keep_hygiene_data { rustc_span::hygiene::clear_syntax_context_map(); @@ -577,7 +579,7 @@ fn escape_dep_env(symbol: Symbol) -> String { fn write_out_deps( sess: &Session, - boxed_resolver: &Steal>>, + boxed_resolver: &RefCell, outputs: &OutputFilenames, out_filenames: &[PathBuf], ) { @@ -604,7 +606,7 @@ fn write_out_deps( } 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() { let source = resolver.cstore().crate_source_untracked(cnum); if let Some((path, _)) = source.dylib { @@ -673,7 +675,7 @@ pub fn prepare_outputs( sess: &Session, compiler: &Compiler, krate: &ast::Crate, - boxed_resolver: &Steal>>, + boxed_resolver: &RefCell, crate_name: &str, ) -> Result { let _timer = sess.timer("prepare_outputs"); @@ -777,7 +779,7 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, - krate: &ast::Crate, + krate: ast::Crate, dep_graph: DepGraph, resolver: Rc>, outputs: OutputFilenames, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 7b284e206e2bf..b5fe8af1fd723 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -3,7 +3,6 @@ use crate::passes::{self, BoxedResolver, QueryContext}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; use rustc_errors::ErrorReported; @@ -80,7 +79,7 @@ pub struct Queries<'tcx> { parse: Query, crate_name: Query, register_plugins: Query<(ast::Crate, Lrc)>, - expansion: Query<(ast::Crate, Steal>>, Lrc)>, + expansion: Query<(ast::Crate, Rc>, Lrc)>, dep_graph: Query, prepare_outputs: Query, global_ctxt: Query>, @@ -168,7 +167,7 @@ impl<'tcx> Queries<'tcx> { pub fn expansion( &self, - ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { + ) -> Result<&Query<(ast::Crate, Rc>, Lrc)>> { tracing::trace!("expansion"); self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); @@ -184,7 +183,7 @@ impl<'tcx> Queries<'tcx> { let krate = resolver.access(|resolver| { passes::configure_and_expand(&sess, &lint_store, krate, &crate_name, resolver) })?; - Ok((krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)) + Ok((krate, Rc::new(RefCell::new(resolver)), lint_store)) }) } @@ -206,14 +205,13 @@ impl<'tcx> Queries<'tcx> { pub fn prepare_outputs(&self) -> Result<&Query> { self.prepare_outputs.compute(|| { - let expansion_result = self.expansion()?; - let (krate, boxed_resolver, _) = &*expansion_result.peek(); + let (krate, boxed_resolver, _) = &*self.expansion()?.peek(); let crate_name = self.crate_name()?.peek(); passes::prepare_outputs( self.session(), self.compiler, - &krate, - &boxed_resolver, + krate, + &*boxed_resolver, &crate_name, ) }) @@ -223,14 +221,14 @@ impl<'tcx> Queries<'tcx> { self.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); - let (ref krate, ref resolver, ref lint_store) = &*self.expansion()?.peek(); let dep_graph = self.dep_graph()?.peek().clone(); + let (krate, resolver, lint_store) = self.expansion()?.take(); Ok(passes::create_global_ctxt( self.compiler, - lint_store.clone(), + lint_store, krate, dep_graph, - resolver.steal(), + resolver, outputs, &crate_name, &self.queries, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c3d9c4ea7f25a..71fcde8bca89f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -303,9 +303,8 @@ crate fn create_resolver<'a>( queries: &Queries<'a>, sess: &Session, ) -> Rc> { - let parts = abort_on_err(queries.expansion(), sess).peek(); - let (krate, resolver, _) = &*parts; - let resolver = resolver.borrow().clone(); + let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek(); + let resolver = resolver.clone(); let mut loader = crate::passes::collect_intra_doc_links::IntraLinkCrateLoader::new(resolver); ast::visit::walk_crate(&mut loader, krate); From aa1bc5874eb43868151b1c2f667086547af65726 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 20 Jun 2021 18:52:35 +0200 Subject: [PATCH 7/8] Fix AST pretty. --- compiler/rustc_driver/src/lib.rs | 4 ++-- compiler/rustc_interface/src/passes.rs | 6 +++--- compiler/rustc_interface/src/queries.rs | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 2733cd2990954..20f1e192a618b 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -315,12 +315,12 @@ fn run_compiler( if let Some(ppm) = &sess.opts.pretty { if ppm.needs_ast_map() { - let expanded_crate = { &queries.expansion()?.peek().0 }; + let expanded_crate = queries.expansion()?.peek().0.clone(); queries.global_ctxt()?.peek_mut().enter(|tcx| { pretty::print_after_hir_lowering( tcx, compiler.input(), - expanded_crate, + &*expanded_crate, *ppm, compiler.output_file().as_ref().map(|p| &**p), ); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 98394bee22c42..63aa3db63fff4 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -457,13 +457,13 @@ pub fn lower_to_hir<'res, 'tcx>( sess: &'tcx Session, lint_store: &LintStore, resolver: &'res mut Resolver<'_>, - krate: ast::Crate, + krate: Rc, arena: &'tcx rustc_ast_lowering::Arena<'tcx>, ) -> &'tcx Crate<'tcx> { // Lower AST to HIR. let hir_crate = rustc_ast_lowering::lower_crate( sess, - &krate, + &*krate, resolver, rustc_parse::nt_to_tokenstream, arena, @@ -779,7 +779,7 @@ impl<'tcx> QueryContext<'tcx> { pub fn create_global_ctxt<'tcx>( compiler: &'tcx Compiler, lint_store: Lrc, - krate: ast::Crate, + krate: Rc, dep_graph: DepGraph, resolver: Rc>, outputs: OutputFilenames, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index b5fe8af1fd723..8a0964e6b9f92 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -79,7 +79,7 @@ pub struct Queries<'tcx> { parse: Query, crate_name: Query, register_plugins: Query<(ast::Crate, Lrc)>, - expansion: Query<(ast::Crate, Rc>, Lrc)>, + expansion: Query<(Rc, Rc>, Lrc)>, dep_graph: Query, prepare_outputs: Query, global_ctxt: Query>, @@ -167,7 +167,7 @@ impl<'tcx> Queries<'tcx> { pub fn expansion( &self, - ) -> Result<&Query<(ast::Crate, Rc>, Lrc)>> { + ) -> Result<&Query<(Rc, Rc>, Lrc)>> { tracing::trace!("expansion"); self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); @@ -183,7 +183,7 @@ impl<'tcx> Queries<'tcx> { let krate = resolver.access(|resolver| { passes::configure_and_expand(&sess, &lint_store, krate, &crate_name, resolver) })?; - Ok((krate, Rc::new(RefCell::new(resolver)), lint_store)) + Ok((Rc::new(krate), Rc::new(RefCell::new(resolver)), lint_store)) }) } From f69877426a6a65fceccaedf9a1e82fa5f05de9d2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 30 Jun 2021 20:52:00 +0200 Subject: [PATCH 8/8] Update comments. --- compiler/rustc_interface/src/passes.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 63aa3db63fff4..9ea1f88b43f79 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -100,7 +100,7 @@ mod boxed_resolver { } // 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 { fn drop(&mut self) { self.resolver.take(); @@ -109,10 +109,10 @@ mod boxed_resolver { } impl BoxedResolver { - pub(super) fn new(session: Lrc, make_resolver: F) -> Self - where - F: for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>, - { + pub(super) fn new( + session: Lrc, + make_resolver: impl for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>, + ) -> BoxedResolver { let mut boxed_resolver = Box::new(BoxedResolverInner { session, resolver_arenas: Some(Resolver::arenas()), @@ -168,11 +168,6 @@ pub fn create_resolver( crate_name: &str, ) -> BoxedResolver { 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. BoxedResolver::new(sess, move |sess, resolver_arenas| { Resolver::new(sess, &krate, &crate_name, metadata_loader, &resolver_arenas) }) @@ -263,8 +258,6 @@ fn pre_expansion_lint( /// 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,