From 266ede1bb34195663238d23373bcc56f1f731748 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 24 Nov 2019 15:59:22 +0100 Subject: [PATCH 01/20] Isolate compiler queries inside the Queries type. --- src/librustc_driver/lib.rs | 186 ++++++++++++++-------------- src/librustc_interface/interface.rs | 3 - src/librustc_interface/queries.rs | 117 +++++++++++------ src/librustdoc/core.rs | 54 ++++---- src/librustdoc/test.rs | 35 +++--- 5 files changed, 219 insertions(+), 176 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 13829b842fd5f..f28119fb66a3f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -283,120 +283,124 @@ pub fn run_compiler( return sess.compile_status(); } - compiler.parse()?; - - if let Some(ppm) = &sess.opts.pretty { - if ppm.needs_ast_map() { - compiler.global_ctxt()?.peek_mut().enter(|tcx| { - let expanded_crate = compiler.expansion()?.take().0; - pretty::print_after_hir_lowering( - tcx, - compiler.input(), - &expanded_crate, + compiler.enter(|queries| { + queries.parse()?; + + if let Some(ppm) = &sess.opts.pretty { + if ppm.needs_ast_map() { + queries.global_ctxt()?.peek_mut().enter(|tcx| { + let expanded_crate = queries.expansion()?.take().0; + pretty::print_after_hir_lowering( + tcx, + compiler.input(), + &expanded_crate, + *ppm, + compiler.output_file().as_ref().map(|p| &**p), + ); + Ok(()) + })?; + } else { + let krate = queries.parse()?.take(); + pretty::print_after_parsing( + sess, + &compiler.input(), + &krate, *ppm, compiler.output_file().as_ref().map(|p| &**p), ); - Ok(()) - })?; - } else { - let krate = compiler.parse()?.take(); - pretty::print_after_parsing( - sess, - &compiler.input(), - &krate, - *ppm, - compiler.output_file().as_ref().map(|p| &**p), - ); + } + return sess.compile_status(); } - return sess.compile_status(); - } - if callbacks.after_parsing(compiler) == Compilation::Stop { - return sess.compile_status(); - } + if callbacks.after_parsing(compiler) == Compilation::Stop { + return sess.compile_status(); + } - if sess.opts.debugging_opts.parse_only || - sess.opts.debugging_opts.show_span.is_some() || - sess.opts.debugging_opts.ast_json_noexpand { - return sess.compile_status(); - } + if sess.opts.debugging_opts.parse_only || + sess.opts.debugging_opts.show_span.is_some() || + sess.opts.debugging_opts.ast_json_noexpand { + return sess.compile_status(); + } + + { + let (_, lint_store) = &*queries.register_plugins()?.peek(); - { - let (_, lint_store) = &*compiler.register_plugins()?.peek(); + // Lint plugins are registered; now we can process command line flags. + if sess.opts.describe_lints { + describe_lints(&sess, &lint_store, true); + return sess.compile_status(); + } + } - // Lint plugins are registered; now we can process command line flags. - if sess.opts.describe_lints { - describe_lints(&sess, &lint_store, true); + queries.expansion()?; + if callbacks.after_expansion(compiler) == Compilation::Stop { return sess.compile_status(); } - } - compiler.expansion()?; - if callbacks.after_expansion(compiler) == Compilation::Stop { - return sess.compile_status(); - } + queries.prepare_outputs()?; + + if sess.opts.output_types.contains_key(&OutputType::DepInfo) + && sess.opts.output_types.len() == 1 + { + return sess.compile_status(); + } - compiler.prepare_outputs()?; + queries.global_ctxt()?; - if sess.opts.output_types.contains_key(&OutputType::DepInfo) - && sess.opts.output_types.len() == 1 - { - return sess.compile_status(); - } + if sess.opts.debugging_opts.no_analysis || + sess.opts.debugging_opts.ast_json { + return sess.compile_status(); + } - compiler.global_ctxt()?; + if sess.opts.debugging_opts.save_analysis { + let expanded_crate = &queries.expansion()?.peek().0; + let crate_name = queries.crate_name()?.peek().clone(); + queries.global_ctxt()?.peek_mut().enter(|tcx| { + let result = tcx.analysis(LOCAL_CRATE); + + time(sess, "save analysis", || { + save::process_crate( + tcx, + &expanded_crate, + &crate_name, + &compiler.input(), + None, + DumpHandler::new(compiler.output_dir().as_ref().map(|p| &**p), &crate_name) + ) + }); - if sess.opts.debugging_opts.no_analysis || - sess.opts.debugging_opts.ast_json { - return sess.compile_status(); - } + result + // AST will be dropped *after* the `after_analysis` callback + // (needed by the RLS) + })?; + } else { + // Drop AST after creating GlobalCtxt to free memory + mem::drop(queries.expansion()?.take()); + } - if sess.opts.debugging_opts.save_analysis { - let expanded_crate = &compiler.expansion()?.peek().0; - let crate_name = compiler.crate_name()?.peek().clone(); - compiler.global_ctxt()?.peek_mut().enter(|tcx| { - let result = tcx.analysis(LOCAL_CRATE); - - time(sess, "save analysis", || { - save::process_crate( - tcx, - &expanded_crate, - &crate_name, - &compiler.input(), - None, - DumpHandler::new(compiler.output_dir().as_ref().map(|p| &**p), &crate_name) - ) - }); - - result - // AST will be dropped *after* the `after_analysis` callback - // (needed by the RLS) - })?; - } else { - // Drop AST after creating GlobalCtxt to free memory - mem::drop(compiler.expansion()?.take()); - } + queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; - compiler.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; + if callbacks.after_analysis(compiler) == Compilation::Stop { + return sess.compile_status(); + } - if callbacks.after_analysis(compiler) == Compilation::Stop { - return sess.compile_status(); - } + if sess.opts.debugging_opts.save_analysis { + mem::drop(queries.expansion()?.take()); + } - if sess.opts.debugging_opts.save_analysis { - mem::drop(compiler.expansion()?.take()); - } + queries.ongoing_codegen()?; - compiler.ongoing_codegen()?; + // Drop GlobalCtxt after starting codegen to free memory + mem::drop(queries.global_ctxt()?.take()); - // Drop GlobalCtxt after starting codegen to free memory - mem::drop(compiler.global_ctxt()?.take()); + if sess.opts.debugging_opts.print_type_sizes { + sess.code_stats.print_type_sizes(); + } - if sess.opts.debugging_opts.print_type_sizes { - sess.code_stats.print_type_sizes(); - } + queries.link()?; - compiler.link()?; + Ok(()) + })?; if sess.opts.debugging_opts.perf_stats { sess.print_perf_stats(); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 70ed4aad7b4aa..beb2465bd4a1a 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -1,4 +1,3 @@ -use crate::queries::Queries; use crate::util; pub use crate::passes::BoxedResolver; @@ -36,7 +35,6 @@ pub struct Compiler { pub(crate) input_path: Option, pub(crate) output_dir: Option, pub(crate) output_file: Option, - pub(crate) queries: Queries, pub(crate) crate_name: Option, pub(crate) register_lints: Option>, pub(crate) override_queries: @@ -169,7 +167,6 @@ pub fn run_compiler_in_existing_thread_pool( input_path: config.input_path, output_dir: config.output_dir, output_file: config.output_file, - queries: Default::default(), crate_name: config.crate_name, register_lints: config.register_lints, override_queries: config.override_queries, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 9094f36d44e5e..85bdd341f5272 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -3,6 +3,7 @@ use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt}; use rustc_incremental::DepGraphFuture; use rustc_data_structures::sync::Lrc; +use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; @@ -44,13 +45,6 @@ impl Query { .unwrap() } - /// Returns a stolen query result. Panics if there's already a result. - pub fn give(&self, value: T) { - let mut result = self.result.borrow_mut(); - assert!(result.is_none(), "a result already exists"); - *result = Some(Ok(value)); - } - /// Borrows the query result using the RefCell. Panics if the result is stolen. pub fn peek(&self) -> Ref<'_, T> { Ref::map(self.result.borrow(), |r| { @@ -74,8 +68,9 @@ impl Default for Query { } } -#[derive(Default)] -pub(crate) struct Queries { +pub struct Queries<'comp> { + compiler: &'comp Compiler, + dep_graph_future: Query>, parse: Query, crate_name: Query, @@ -89,9 +84,33 @@ pub(crate) struct Queries { link: Query<()>, } -impl Compiler { +impl<'comp> Queries<'comp> { + pub fn new(compiler: &'comp Compiler) -> Queries<'comp> { + Queries { + compiler, + dep_graph_future: Default::default(), + parse: Default::default(), + crate_name: Default::default(), + 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(), + link: Default::default(), + } + } + + fn session(&self) -> &Lrc { + &self.compiler.sess + } + fn codegen_backend(&self) -> &Lrc> { + &self.compiler.codegen_backend() + } + pub fn dep_graph_future(&self) -> Result<&Query>> { - self.queries.dep_graph_future.compute(|| { + self.dep_graph_future.compute(|| { Ok(if self.session().opts.build_dep_graph() { Some(rustc_incremental::load_dep_graph(self.session())) } else { @@ -101,8 +120,8 @@ impl Compiler { } pub fn parse(&self) -> Result<&Query> { - self.queries.parse.compute(|| { - passes::parse(self.session(), &self.input).map_err( + self.parse.compute(|| { + passes::parse(self.session(), &self.compiler.input).map_err( |mut parse_error| { parse_error.emit(); ErrorReported @@ -112,7 +131,7 @@ impl Compiler { } pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, Lrc)>> { - self.queries.register_plugins.compute(|| { + self.register_plugins.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); @@ -120,7 +139,7 @@ impl Compiler { let result = passes::register_plugins( self.session(), &*self.codegen_backend().metadata_loader(), - self.register_lints + self.compiler.register_lints .as_ref() .map(|p| &**p) .unwrap_or_else(|| empty), @@ -140,8 +159,8 @@ impl Compiler { } pub fn crate_name(&self) -> Result<&Query> { - self.queries.crate_name.compute(|| { - Ok(match self.crate_name { + self.crate_name.compute(|| { + Ok(match self.compiler.crate_name { Some(ref crate_name) => crate_name.clone(), None => { let parse_result = self.parse()?; @@ -149,7 +168,7 @@ impl Compiler { rustc_codegen_utils::link::find_crate_name( Some(self.session()), &krate.attrs, - &self.input + &self.compiler.input ) } }) @@ -159,11 +178,11 @@ impl Compiler { pub fn expansion( &self ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { - self.queries.expansion.compute(|| { + self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let (krate, lint_store) = self.register_plugins()?.take(); passes::configure_and_expand( - self.sess.clone(), + self.session().clone(), lint_store.clone(), self.codegen_backend().metadata_loader(), krate, @@ -175,7 +194,7 @@ impl Compiler { } pub fn dep_graph(&self) -> Result<&Query> { - self.queries.dep_graph.compute(|| { + self.dep_graph.compute(|| { Ok(match self.dep_graph_future()?.take() { None => DepGraph::new_disabled(), Some(future) => { @@ -194,7 +213,7 @@ impl Compiler { pub fn lower_to_hir( &self, ) -> Result<&Query<(Steal, Steal)>> { - self.queries.lower_to_hir.compute(|| { + self.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); let krate = &peeked.0; @@ -214,17 +233,17 @@ impl Compiler { } pub fn prepare_outputs(&self) -> Result<&Query> { - self.queries.prepare_outputs.compute(|| { + self.prepare_outputs.compute(|| { let expansion_result = self.expansion()?; let (krate, boxed_resolver, _) = &*expansion_result.peek(); let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); - passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name) + passes::prepare_outputs(self.session(), self.compiler, &krate, &boxed_resolver, &crate_name) }) } pub fn global_ctxt(&self) -> Result<&Query> { - self.queries.global_ctxt.compute(|| { + 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(); @@ -232,7 +251,7 @@ impl Compiler { let hir = hir.peek(); let (hir_forest, resolver_outputs) = &*hir; Ok(passes::create_global_ctxt( - self, + self.compiler, lint_store, hir_forest.steal(), resolver_outputs.steal(), @@ -242,7 +261,7 @@ impl Compiler { } pub fn ongoing_codegen(&self) -> Result<&Query>> { - self.queries.ongoing_codegen.compute(|| { + self.ongoing_codegen.compute(|| { let outputs = self.prepare_outputs()?; self.global_ctxt()?.peek_mut().enter(|tcx| { tcx.analysis(LOCAL_CRATE).ok(); @@ -260,7 +279,7 @@ impl Compiler { } pub fn link(&self) -> Result<&Query<()>> { - self.queries.link.compute(|| { + self.link.compute(|| { let sess = self.session(); let ongoing_codegen = self.ongoing_codegen()?.take(); @@ -275,6 +294,20 @@ impl Compiler { Ok(()) }) } +} + +impl Compiler { + // This method is different to all the other methods in `Compiler` because + // it lacks a `Queries` entry. It's also not currently used. It does serve + // as an example of how `Compiler` can be used, with additional steps added + // between some passes. And see `rustc_driver::run_compiler` for a more + // complex example. + pub fn enter<'c, F, T>(&'c self, f: F) -> Result + where F: for<'q> FnOnce(&'q Queries<'c>) -> Result + { + let queries = Queries::new(&self); + f(&queries) + } // This method is different to all the other methods in `Compiler` because // it lacks a `Queries` entry. It's also not currently used. It does serve @@ -282,24 +315,26 @@ impl Compiler { // between some passes. And see `rustc_driver::run_compiler` for a more // complex example. pub fn compile(&self) -> Result<()> { - self.prepare_outputs()?; + self.enter(|queries| { + queries.prepare_outputs()?; - if self.session().opts.output_types.contains_key(&OutputType::DepInfo) - && self.session().opts.output_types.len() == 1 - { - return Ok(()) - } + if self.session().opts.output_types.contains_key(&OutputType::DepInfo) + && self.session().opts.output_types.len() == 1 + { + return Ok(()) + } - self.global_ctxt()?; + queries.global_ctxt()?; - // Drop AST after creating GlobalCtxt to free memory. - mem::drop(self.expansion()?.take()); + // Drop AST after creating GlobalCtxt to free memory. + mem::drop(queries.expansion()?.take()); - self.ongoing_codegen()?; + queries.ongoing_codegen()?; - // Drop GlobalCtxt after starting codegen to free memory. - mem::drop(self.global_ctxt()?.take()); + // Drop GlobalCtxt after starting codegen to free memory. + mem::drop(queries.global_ctxt()?.take()); - self.link().map(|_| ()) + queries.link().map(|_| ()) + }) } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 612f3c69871d7..15904814ac46d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -346,34 +346,38 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt interface::run_compiler_in_existing_thread_pool(config, |compiler| { let sess = compiler.session(); - // We need to hold on to the complete resolver, so we cause everything to be - // cloned for the analysis passes to use. Suboptimal, but necessary in the - // current architecture. - let resolver = { - let parts = abort_on_err(compiler.expansion(), sess).peek(); - let resolver = parts.1.borrow(); - - // Before we actually clone it, let's force all the extern'd crates to - // actually be loaded, just in case they're only referred to inside - // intra-doc-links - resolver.borrow_mut().access(|resolver| { - for extern_name in &extern_names { - resolver.resolve_str_path_error(DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID) - .unwrap_or_else( - |()| panic!("Unable to resolve external crate {}", extern_name) - ); - } - }); + let (resolver, mut global_ctxt) = compiler.enter(|queries| { + // We need to hold on to the complete resolver, so we cause everything to be + // cloned for the analysis passes to use. Suboptimal, but necessary in the + // current architecture. + let resolver = { + let parts = abort_on_err(queries.expansion(), sess).peek(); + let resolver = parts.1.borrow(); + + // Before we actually clone it, let's force all the extern'd crates to + // actually be loaded, just in case they're only referred to inside + // intra-doc-links + resolver.borrow_mut().access(|resolver| { + for extern_name in &extern_names { + resolver.resolve_str_path_error(DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID) + .unwrap_or_else( + |()| panic!("Unable to resolve external crate {}", extern_name) + ); + } + }); - // Now we're good to clone the resolver because everything should be loaded - resolver.clone() - }; + // Now we're good to clone the resolver because everything should be loaded + resolver.clone() + }; - if sess.has_errors() { - sess.fatal("Compilation failed, aborting rustdoc"); - } + if sess.has_errors() { + sess.fatal("Compilation failed, aborting rustdoc"); + } + + let global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - let mut global_ctxt = abort_on_err(compiler.global_ctxt(), sess).take(); + Ok((resolver, global_ctxt)) + }).unwrap(); global_ctxt.enter(|tcx| { tcx.analysis(LOCAL_CRATE).ok(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 22f209b8bada1..eca542ea6a37c 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -86,22 +86,25 @@ pub fn run(options: Options) -> i32 { let display_warnings = options.display_warnings; let tests = interface::run_compiler(config, |compiler| -> Result<_, ErrorReported> { - let lower_to_hir = compiler.lower_to_hir()?; - - let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); - opts.display_warnings |= options.display_warnings; - let enable_per_target_ignores = options.enable_per_target_ignores; - let mut collector = Collector::new( - compiler.crate_name()?.peek().to_string(), - options, - false, - opts, - Some(compiler.source_map().clone()), - None, - enable_per_target_ignores, - ); - - let mut global_ctxt = compiler.global_ctxt()?.take(); + let (mut collector, mut global_ctxt) = compiler.enter(|queries| { + let lower_to_hir = queries.lower_to_hir()?; + + let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); + opts.display_warnings |= options.display_warnings; + let enable_per_target_ignores = options.enable_per_target_ignores; + let collector = Collector::new( + queries.crate_name()?.peek().to_string(), + options, + false, + opts, + Some(compiler.source_map().clone()), + None, + enable_per_target_ignores, + ); + + let global_ctxt = queries.global_ctxt()?.take(); + Ok((collector, global_ctxt)) + })?; global_ctxt.enter(|tcx| { let krate = tcx.hir().krate(); let mut hir_collector = HirCollector { From 5098ba6a932785152285d5729708f7d58f795b62 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 24 Nov 2019 16:32:57 +0100 Subject: [PATCH 02/20] Move linking ouside the interface queries. --- src/librustc_driver/lib.rs | 35 +++++++++++------ src/librustc_interface/queries.rs | 64 +++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f28119fb66a3f..b4dab3979961b 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -283,7 +283,7 @@ pub fn run_compiler( return sess.compile_status(); } - compiler.enter(|queries| { + let linker = compiler.enter(|queries| { queries.parse()?; if let Some(ppm) = &sess.opts.pretty { @@ -309,17 +309,20 @@ pub fn run_compiler( compiler.output_file().as_ref().map(|p| &**p), ); } - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } if callbacks.after_parsing(compiler) == Compilation::Stop { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } if sess.opts.debugging_opts.parse_only || sess.opts.debugging_opts.show_span.is_some() || sess.opts.debugging_opts.ast_json_noexpand { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } { @@ -328,13 +331,15 @@ pub fn run_compiler( // Lint plugins are registered; now we can process command line flags. if sess.opts.describe_lints { describe_lints(&sess, &lint_store, true); - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } } queries.expansion()?; if callbacks.after_expansion(compiler) == Compilation::Stop { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } queries.prepare_outputs()?; @@ -342,14 +347,16 @@ pub fn run_compiler( if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } queries.global_ctxt()?; if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } if sess.opts.debugging_opts.save_analysis { @@ -381,7 +388,8 @@ pub fn run_compiler( queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; if callbacks.after_analysis(compiler) == Compilation::Stop { - return sess.compile_status(); + sess.compile_status()?; + return Ok(None); } if sess.opts.debugging_opts.save_analysis { @@ -397,11 +405,14 @@ pub fn run_compiler( sess.code_stats.print_type_sizes(); } - queries.link()?; - - Ok(()) + let linker = queries.linker()?; + Ok(Some(linker)) })?; + if let Some(linker) = linker { + linker.link()? + } + if sess.opts.debugging_opts.perf_stats { sess.print_perf_stats(); } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 85bdd341f5272..e91316ff4772c 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -81,7 +81,6 @@ pub struct Queries<'comp> { prepare_outputs: Query, global_ctxt: Query, ongoing_codegen: Query>, - link: Query<()>, } impl<'comp> Queries<'comp> { @@ -98,7 +97,6 @@ impl<'comp> Queries<'comp> { prepare_outputs: Default::default(), global_ctxt: Default::default(), ongoing_codegen: Default::default(), - link: Default::default(), } } @@ -278,24 +276,43 @@ impl<'comp> Queries<'comp> { }) } - pub fn link(&self) -> Result<&Query<()>> { - self.link.compute(|| { - let sess = self.session(); + pub fn linker(self) -> Result { + let dep_graph = self.dep_graph()?; + let prepare_outputs = self.prepare_outputs()?; + let ongoing_codegen = self.ongoing_codegen()?; - let ongoing_codegen = self.ongoing_codegen()?.take(); + let sess = self.session().clone(); + let codegen_backend = self.codegen_backend().clone(); - self.codegen_backend().join_codegen_and_link( - ongoing_codegen, - sess, - &*self.dep_graph()?.peek(), - &*self.prepare_outputs()?.peek(), - ).map_err(|_| ErrorReported)?; - - Ok(()) + Ok(Linker { + sess, + dep_graph: dep_graph.take(), + prepare_outputs: prepare_outputs.take(), + ongoing_codegen: ongoing_codegen.take(), + codegen_backend, }) } } +pub struct Linker { + sess: Lrc, + dep_graph: DepGraph, + prepare_outputs: OutputFilenames, + ongoing_codegen: Box, + codegen_backend: Lrc>, +} + +impl Linker { + pub fn link(self) -> Result<()> { + self.codegen_backend.join_codegen_and_link( + self.ongoing_codegen, + &self.sess, + &self.dep_graph, + &self.prepare_outputs, + ).map_err(|_| ErrorReported) + } +} + impl Compiler { // This method is different to all the other methods in `Compiler` because // it lacks a `Queries` entry. It's also not currently used. It does serve @@ -303,10 +320,10 @@ impl Compiler { // between some passes. And see `rustc_driver::run_compiler` for a more // complex example. pub fn enter<'c, F, T>(&'c self, f: F) -> Result - where F: for<'q> FnOnce(&'q Queries<'c>) -> Result + where F: FnOnce(Queries<'c>) -> Result { let queries = Queries::new(&self); - f(&queries) + f(queries) } // This method is different to all the other methods in `Compiler` because @@ -315,13 +332,13 @@ impl Compiler { // between some passes. And see `rustc_driver::run_compiler` for a more // complex example. pub fn compile(&self) -> Result<()> { - self.enter(|queries| { + let linker = self.enter(|queries| { queries.prepare_outputs()?; if self.session().opts.output_types.contains_key(&OutputType::DepInfo) && self.session().opts.output_types.len() == 1 { - return Ok(()) + return Ok(None) } queries.global_ctxt()?; @@ -334,7 +351,14 @@ impl Compiler { // Drop GlobalCtxt after starting codegen to free memory. mem::drop(queries.global_ctxt()?.take()); - queries.link().map(|_| ()) - }) + let linker = queries.linker()?; + Ok(Some(linker)) + })?; + + if let Some(linker) = linker { + linker.link()? + } + + Ok(()) } } From 27513a21c4bea1774c295c398af413631807cb5c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 24 Nov 2019 16:41:43 +0100 Subject: [PATCH 03/20] Tidy. --- src/librustc_driver/lib.rs | 4 +++- src/librustc_interface/queries.rs | 4 +++- src/librustdoc/core.rs | 9 +++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b4dab3979961b..2429cbe3f5e63 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -372,7 +372,9 @@ pub fn run_compiler( &crate_name, &compiler.input(), None, - DumpHandler::new(compiler.output_dir().as_ref().map(|p| &**p), &crate_name) + DumpHandler::new( + compiler.output_dir().as_ref().map(|p| &**p), &crate_name + ) ) }); diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index e91316ff4772c..013c986288a6e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -236,7 +236,9 @@ impl<'comp> Queries<'comp> { let (krate, boxed_resolver, _) = &*expansion_result.peek(); let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); - passes::prepare_outputs(self.session(), self.compiler, &krate, &boxed_resolver, &crate_name) + passes::prepare_outputs( + self.session(), self.compiler, &krate, &boxed_resolver, &crate_name + ) }) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 15904814ac46d..02045b0dec8a6 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -359,10 +359,11 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt // intra-doc-links resolver.borrow_mut().access(|resolver| { for extern_name in &extern_names { - resolver.resolve_str_path_error(DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID) - .unwrap_or_else( - |()| panic!("Unable to resolve external crate {}", extern_name) - ); + resolver.resolve_str_path_error( + DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID + ).unwrap_or_else( + |()| panic!("Unable to resolve external crate {}", extern_name) + ); } }); From becfe5c15334ecc80e22e024d0137fb9dc0f4d08 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 24 Nov 2019 21:12:38 +0100 Subject: [PATCH 04/20] Fix test. --- src/test/run-make-fulldeps/issue-19371/foo.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index f9ecff2abaa83..62a66aefd2deb 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -66,6 +66,11 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { interface::run_compiler(config, |compiler| { // This runs all the passes prior to linking, too. - compiler.link().ok(); + let linker = compiler.enter(|queries| { + queries.linker() + }); + if let Ok(linker) = linker { + linker.link(); + } }); } From 18bb9129840bc62f083f93d6518a50b4df5bb3b1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 25 Nov 2019 17:24:11 +0100 Subject: [PATCH 05/20] Remove wrong comment. --- src/librustc_interface/queries.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 013c986288a6e..1a510763d6bac 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -316,11 +316,6 @@ impl Linker { } impl Compiler { - // This method is different to all the other methods in `Compiler` because - // it lacks a `Queries` entry. It's also not currently used. It does serve - // as an example of how `Compiler` can be used, with additional steps added - // between some passes. And see `rustc_driver::run_compiler` for a more - // complex example. pub fn enter<'c, F, T>(&'c self, f: F) -> Result where F: FnOnce(Queries<'c>) -> Result { From ea1b8039ada203a50342fda342f905c932cd4eef Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 25 Nov 2019 17:25:47 +0100 Subject: [PATCH 06/20] Pass Queries by reference. --- src/librustc_interface/queries.rs | 10 +++++----- src/librustdoc/core.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 1a510763d6bac..574a24551242b 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -278,7 +278,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn linker(self) -> Result { + pub fn linker(&self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; let ongoing_codegen = self.ongoing_codegen()?; @@ -288,7 +288,7 @@ impl<'comp> Queries<'comp> { Ok(Linker { sess, - dep_graph: dep_graph.take(), + dep_graph: dep_graph.peek().clone(), prepare_outputs: prepare_outputs.take(), ongoing_codegen: ongoing_codegen.take(), codegen_backend, @@ -316,11 +316,11 @@ impl Linker { } impl Compiler { - pub fn enter<'c, F, T>(&'c self, f: F) -> Result - where F: FnOnce(Queries<'c>) -> Result + pub fn enter<'c, F, T>(&'c self, f: F) -> T + where F: for<'q> FnOnce(&'q Queries<'c>) -> T { let queries = Queries::new(&self); - f(queries) + f(&queries) } // This method is different to all the other methods in `Compiler` because diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 02045b0dec8a6..ebd100e62d46e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -377,8 +377,8 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - Ok((resolver, global_ctxt)) - }).unwrap(); + (resolver, global_ctxt) + }); global_ctxt.enter(|tcx| { tcx.analysis(LOCAL_CRATE).ok(); From 7d01b6ccf0232c8bb1de73033d05c3e5e89b463f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 25 Nov 2019 17:29:32 +0100 Subject: [PATCH 07/20] Simplify early exits. --- src/librustc_driver/lib.rs | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2429cbe3f5e63..7cafc05e39089 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -284,6 +284,7 @@ pub fn run_compiler( } let linker = compiler.enter(|queries| { + let early_exit = || sess.compile_status().map(|_| None); queries.parse()?; if let Some(ppm) = &sess.opts.pretty { @@ -309,20 +310,17 @@ pub fn run_compiler( compiler.output_file().as_ref().map(|p| &**p), ); } - sess.compile_status()?; - return Ok(None); + return early_exit(); } if callbacks.after_parsing(compiler) == Compilation::Stop { - sess.compile_status()?; - return Ok(None); + return early_exit(); } if sess.opts.debugging_opts.parse_only || sess.opts.debugging_opts.show_span.is_some() || sess.opts.debugging_opts.ast_json_noexpand { - sess.compile_status()?; - return Ok(None); + return early_exit(); } { @@ -331,15 +329,13 @@ pub fn run_compiler( // Lint plugins are registered; now we can process command line flags. if sess.opts.describe_lints { describe_lints(&sess, &lint_store, true); - sess.compile_status()?; - return Ok(None); + return early_exit(); } } queries.expansion()?; if callbacks.after_expansion(compiler) == Compilation::Stop { - sess.compile_status()?; - return Ok(None); + return early_exit(); } queries.prepare_outputs()?; @@ -347,16 +343,14 @@ pub fn run_compiler( if sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1 { - sess.compile_status()?; - return Ok(None); + return early_exit(); } queries.global_ctxt()?; if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { - sess.compile_status()?; - return Ok(None); + return early_exit(); } if sess.opts.debugging_opts.save_analysis { @@ -390,8 +384,7 @@ pub fn run_compiler( queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; if callbacks.after_analysis(compiler) == Compilation::Stop { - sess.compile_status()?; - return Ok(None); + return early_exit(); } if sess.opts.debugging_opts.save_analysis { From 8ffc9444a3275079ce24883ec57b041485c358a3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 25 Nov 2019 18:19:08 +0100 Subject: [PATCH 08/20] Don't move stuff out of Compiler::enter. --- src/librustdoc/core.rs | 206 ++++++++++++++++++++--------------------- src/librustdoc/test.rs | 36 +++---- 2 files changed, 120 insertions(+), 122 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index ebd100e62d46e..b5b331928b967 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -344,9 +344,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt }; interface::run_compiler_in_existing_thread_pool(config, |compiler| { - let sess = compiler.session(); + compiler.enter(|queries| { + let sess = compiler.session(); - let (resolver, mut global_ctxt) = compiler.enter(|queries| { // We need to hold on to the complete resolver, so we cause everything to be // cloned for the analysis passes to use. Suboptimal, but necessary in the // current architecture. @@ -375,121 +375,119 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt sess.fatal("Compilation failed, aborting rustdoc"); } - let global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - - (resolver, global_ctxt) - }); - - global_ctxt.enter(|tcx| { - tcx.analysis(LOCAL_CRATE).ok(); - - // Abort if there were any errors so far - sess.abort_if_errors(); - - let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); - // Convert from a HirId set to a DefId set since we don't always have easy access - // to the map from defid -> hirid - let access_levels = AccessLevels { - map: access_levels.map.iter() - .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) - .collect() - }; - - let mut renderinfo = RenderInfo::default(); - renderinfo.access_levels = access_levels; - - let mut ctxt = DocContext { - tcx, - resolver, - external_traits: Default::default(), - active_extern_traits: Default::default(), - renderinfo: RefCell::new(renderinfo), - ty_substs: Default::default(), - lt_substs: Default::default(), - ct_substs: Default::default(), - impl_trait_bounds: Default::default(), - fake_def_ids: Default::default(), - all_fake_def_ids: Default::default(), - generated_synthetics: Default::default(), - auto_traits: tcx.all_traits(LOCAL_CRATE).iter().cloned().filter(|trait_def_id| { - tcx.trait_is_auto(*trait_def_id) - }).collect(), - }; - debug!("crate: {:?}", tcx.hir().krate()); - - let mut krate = clean::krate(&mut ctxt); - - fn report_deprecated_attr(name: &str, diag: &errors::Handler) { - let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \ - considered deprecated", name)); - msg.warn("please see https://github.com/rust-lang/rust/issues/44136"); + let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); + + global_ctxt.enter(|tcx| { + tcx.analysis(LOCAL_CRATE).ok(); + + // Abort if there were any errors so far + sess.abort_if_errors(); + + let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); + // Convert from a HirId set to a DefId set since we don't always have easy access + // to the map from defid -> hirid + let access_levels = AccessLevels { + map: access_levels.map.iter() + .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) + .collect() + }; + + let mut renderinfo = RenderInfo::default(); + renderinfo.access_levels = access_levels; + + let mut ctxt = DocContext { + tcx, + resolver, + external_traits: Default::default(), + active_extern_traits: Default::default(), + renderinfo: RefCell::new(renderinfo), + ty_substs: Default::default(), + lt_substs: Default::default(), + ct_substs: Default::default(), + impl_trait_bounds: Default::default(), + fake_def_ids: Default::default(), + all_fake_def_ids: Default::default(), + generated_synthetics: Default::default(), + auto_traits: tcx.all_traits(LOCAL_CRATE).iter().cloned().filter(|trait_def_id| { + tcx.trait_is_auto(*trait_def_id) + }).collect(), + }; + debug!("crate: {:?}", tcx.hir().krate()); + + let mut krate = clean::krate(&mut ctxt); + + fn report_deprecated_attr(name: &str, diag: &errors::Handler) { + let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \ + considered deprecated", name)); + msg.warn("please see https://github.com/rust-lang/rust/issues/44136"); + + if name == "no_default_passes" { + msg.help("you may want to use `#![doc(document_private_items)]`"); + } - if name == "no_default_passes" { - msg.help("you may want to use `#![doc(document_private_items)]`"); + msg.emit(); } - msg.emit(); - } - - // Process all of the crate attributes, extracting plugin metadata along - // with the passes which we are supposed to run. - for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { - let diag = ctxt.sess().diagnostic(); - - let name = attr.name_or_empty(); - if attr.is_word() { - if name == sym::no_default_passes { - report_deprecated_attr("no_default_passes", diag); - if default_passes == passes::DefaultPassOption::Default { - default_passes = passes::DefaultPassOption::None; + // Process all of the crate attributes, extracting plugin metadata along + // with the passes which we are supposed to run. + for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { + let diag = ctxt.sess().diagnostic(); + + let name = attr.name_or_empty(); + if attr.is_word() { + if name == sym::no_default_passes { + report_deprecated_attr("no_default_passes", diag); + if default_passes == passes::DefaultPassOption::Default { + default_passes = passes::DefaultPassOption::None; + } + } + } else if let Some(value) = attr.value_str() { + let sink = match name { + sym::passes => { + report_deprecated_attr("passes = \"...\"", diag); + &mut manual_passes + }, + sym::plugins => { + report_deprecated_attr("plugins = \"...\"", diag); + eprintln!("WARNING: `#![doc(plugins = \"...\")]` \ + no longer functions; see CVE-2018-1000622"); + continue + }, + _ => continue, + }; + for name in value.as_str().split_whitespace() { + sink.push(name.to_string()); } } - } else if let Some(value) = attr.value_str() { - let sink = match name { - sym::passes => { - report_deprecated_attr("passes = \"...\"", diag); - &mut manual_passes - }, - sym::plugins => { - report_deprecated_attr("plugins = \"...\"", diag); - eprintln!("WARNING: `#![doc(plugins = \"...\")]` no longer functions; \ - see CVE-2018-1000622"); - continue - }, - _ => continue, - }; - for name in value.as_str().split_whitespace() { - sink.push(name.to_string()); - } - } - if attr.is_word() && name == sym::document_private_items { - if default_passes == passes::DefaultPassOption::Default { - default_passes = passes::DefaultPassOption::Private; + if attr.is_word() && name == sym::document_private_items { + if default_passes == passes::DefaultPassOption::Default { + default_passes = passes::DefaultPassOption::Private; + } } } - } - let passes = passes::defaults(default_passes).iter().chain(manual_passes.into_iter() - .flat_map(|name| { - if let Some(pass) = passes::find_pass(&name) { - Some(pass) - } else { - error!("unknown pass {}, skipping", name); - None - } - })); + let passes = passes::defaults(default_passes).iter().chain(manual_passes.into_iter() + .flat_map(|name| { + if let Some(pass) = passes::find_pass(&name) { + Some(pass) + } else { + error!("unknown pass {}, skipping", name); + None + } + })); - info!("Executing passes"); + info!("Executing passes"); - for pass in passes { - debug!("running pass {}", pass.name); - krate = (pass.pass)(krate, &ctxt); - } + for pass in passes { + debug!("running pass {}", pass.name); + krate = (pass.pass)(krate, &ctxt); + } - ctxt.sess().abort_if_errors(); + ctxt.sess().abort_if_errors(); - (krate, ctxt.renderinfo.into_inner(), render_options) + (krate, ctxt.renderinfo.into_inner(), render_options) + }) }) }) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index eca542ea6a37c..47eb993dfc31b 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -86,13 +86,13 @@ pub fn run(options: Options) -> i32 { let display_warnings = options.display_warnings; let tests = interface::run_compiler(config, |compiler| -> Result<_, ErrorReported> { - let (mut collector, mut global_ctxt) = compiler.enter(|queries| { + compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; - let collector = Collector::new( + let mut collector = Collector::new( queries.crate_name()?.peek().to_string(), options, false, @@ -102,24 +102,24 @@ pub fn run(options: Options) -> i32 { enable_per_target_ignores, ); - let global_ctxt = queries.global_ctxt()?.take(); - Ok((collector, global_ctxt)) - })?; - global_ctxt.enter(|tcx| { - let krate = tcx.hir().krate(); - let mut hir_collector = HirCollector { - sess: compiler.session(), - collector: &mut collector, - map: tcx.hir(), - codes: ErrorCodes::from(compiler.session().opts - .unstable_features.is_nightly_build()), - }; - hir_collector.visit_testable("".to_string(), &krate.attrs, |this| { - intravisit::walk_crate(this, krate); + let mut global_ctxt = queries.global_ctxt()?.take(); + + global_ctxt.enter(|tcx| { + let krate = tcx.hir().krate(); + let mut hir_collector = HirCollector { + sess: compiler.session(), + collector: &mut collector, + map: tcx.hir(), + codes: ErrorCodes::from(compiler.session().opts + .unstable_features.is_nightly_build()), + }; + hir_collector.visit_testable("".to_string(), &krate.attrs, |this| { + intravisit::walk_crate(this, krate); + }); }); - }); - Ok(collector.tests) + Ok(collector.tests) + }) }).expect("compiler aborted in rustdoc!"); test_args.insert(0, "rustdoctest".to_string()); From 9d5f721406d7ec1cb0197181a03bd266d66fd6c1 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 25 Nov 2019 18:36:18 +0100 Subject: [PATCH 09/20] Superfluous lifetime. --- src/librustc_interface/queries.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 574a24551242b..ba855ef2f8563 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -316,8 +316,8 @@ impl Linker { } impl Compiler { - pub fn enter<'c, F, T>(&'c self, f: F) -> T - where F: for<'q> FnOnce(&'q Queries<'c>) -> T + pub fn enter(&self, f: F) -> T + where F: for<'q> FnOnce(&'q Queries<'_>) -> T { let queries = Queries::new(&self); f(&queries) From 68b1ac98744b8e03bbcc5ab38f3afbd04f1ec097 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 12:16:36 +0100 Subject: [PATCH 10/20] Reduce righward drift. --- src/librustdoc/core.rs | 256 ++++++++++++++++++++--------------------- src/librustdoc/test.rs | 67 ++++++----- 2 files changed, 160 insertions(+), 163 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b5b331928b967..d9d475813b073 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -343,153 +343,151 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt registry: rustc_driver::diagnostics_registry(), }; - interface::run_compiler_in_existing_thread_pool(config, |compiler| { - compiler.enter(|queries| { - let sess = compiler.session(); - - // We need to hold on to the complete resolver, so we cause everything to be - // cloned for the analysis passes to use. Suboptimal, but necessary in the - // current architecture. - let resolver = { - let parts = abort_on_err(queries.expansion(), sess).peek(); - let resolver = parts.1.borrow(); - - // Before we actually clone it, let's force all the extern'd crates to - // actually be loaded, just in case they're only referred to inside - // intra-doc-links - resolver.borrow_mut().access(|resolver| { - for extern_name in &extern_names { - resolver.resolve_str_path_error( - DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID - ).unwrap_or_else( - |()| panic!("Unable to resolve external crate {}", extern_name) - ); - } - }); + interface::run_compiler_in_existing_thread_pool(config, |compiler| { compiler.enter(|queries| { + let sess = compiler.session(); + + // We need to hold on to the complete resolver, so we cause everything to be + // cloned for the analysis passes to use. Suboptimal, but necessary in the + // current architecture. + let resolver = { + let parts = abort_on_err(queries.expansion(), sess).peek(); + let resolver = parts.1.borrow(); + + // Before we actually clone it, let's force all the extern'd crates to + // actually be loaded, just in case they're only referred to inside + // intra-doc-links + resolver.borrow_mut().access(|resolver| { + for extern_name in &extern_names { + resolver.resolve_str_path_error( + DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID + ).unwrap_or_else( + |()| panic!("Unable to resolve external crate {}", extern_name) + ); + } + }); + + // Now we're good to clone the resolver because everything should be loaded + resolver.clone() + }; + + if sess.has_errors() { + sess.fatal("Compilation failed, aborting rustdoc"); + } + + let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - // Now we're good to clone the resolver because everything should be loaded - resolver.clone() + global_ctxt.enter(|tcx| { + tcx.analysis(LOCAL_CRATE).ok(); + + // Abort if there were any errors so far + sess.abort_if_errors(); + + let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); + // Convert from a HirId set to a DefId set since we don't always have easy access + // to the map from defid -> hirid + let access_levels = AccessLevels { + map: access_levels.map.iter() + .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) + .collect() }; - if sess.has_errors() { - sess.fatal("Compilation failed, aborting rustdoc"); - } + let mut renderinfo = RenderInfo::default(); + renderinfo.access_levels = access_levels; + + let mut ctxt = DocContext { + tcx, + resolver, + external_traits: Default::default(), + active_extern_traits: Default::default(), + renderinfo: RefCell::new(renderinfo), + ty_substs: Default::default(), + lt_substs: Default::default(), + ct_substs: Default::default(), + impl_trait_bounds: Default::default(), + fake_def_ids: Default::default(), + all_fake_def_ids: Default::default(), + generated_synthetics: Default::default(), + auto_traits: tcx.all_traits(LOCAL_CRATE).iter().cloned().filter(|trait_def_id| { + tcx.trait_is_auto(*trait_def_id) + }).collect(), + }; + debug!("crate: {:?}", tcx.hir().krate()); - let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); - - global_ctxt.enter(|tcx| { - tcx.analysis(LOCAL_CRATE).ok(); - - // Abort if there were any errors so far - sess.abort_if_errors(); - - let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); - // Convert from a HirId set to a DefId set since we don't always have easy access - // to the map from defid -> hirid - let access_levels = AccessLevels { - map: access_levels.map.iter() - .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) - .collect() - }; - - let mut renderinfo = RenderInfo::default(); - renderinfo.access_levels = access_levels; - - let mut ctxt = DocContext { - tcx, - resolver, - external_traits: Default::default(), - active_extern_traits: Default::default(), - renderinfo: RefCell::new(renderinfo), - ty_substs: Default::default(), - lt_substs: Default::default(), - ct_substs: Default::default(), - impl_trait_bounds: Default::default(), - fake_def_ids: Default::default(), - all_fake_def_ids: Default::default(), - generated_synthetics: Default::default(), - auto_traits: tcx.all_traits(LOCAL_CRATE).iter().cloned().filter(|trait_def_id| { - tcx.trait_is_auto(*trait_def_id) - }).collect(), - }; - debug!("crate: {:?}", tcx.hir().krate()); - - let mut krate = clean::krate(&mut ctxt); - - fn report_deprecated_attr(name: &str, diag: &errors::Handler) { - let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \ - considered deprecated", name)); - msg.warn("please see https://github.com/rust-lang/rust/issues/44136"); - - if name == "no_default_passes" { - msg.help("you may want to use `#![doc(document_private_items)]`"); - } + let mut krate = clean::krate(&mut ctxt); + + fn report_deprecated_attr(name: &str, diag: &errors::Handler) { + let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \ + considered deprecated", name)); + msg.warn("please see https://github.com/rust-lang/rust/issues/44136"); - msg.emit(); + if name == "no_default_passes" { + msg.help("you may want to use `#![doc(document_private_items)]`"); } - // Process all of the crate attributes, extracting plugin metadata along - // with the passes which we are supposed to run. - for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { - let diag = ctxt.sess().diagnostic(); - - let name = attr.name_or_empty(); - if attr.is_word() { - if name == sym::no_default_passes { - report_deprecated_attr("no_default_passes", diag); - if default_passes == passes::DefaultPassOption::Default { - default_passes = passes::DefaultPassOption::None; - } - } - } else if let Some(value) = attr.value_str() { - let sink = match name { - sym::passes => { - report_deprecated_attr("passes = \"...\"", diag); - &mut manual_passes - }, - sym::plugins => { - report_deprecated_attr("plugins = \"...\"", diag); - eprintln!("WARNING: `#![doc(plugins = \"...\")]` \ - no longer functions; see CVE-2018-1000622"); - continue - }, - _ => continue, - }; - for name in value.as_str().split_whitespace() { - sink.push(name.to_string()); - } - } + msg.emit(); + } + + // Process all of the crate attributes, extracting plugin metadata along + // with the passes which we are supposed to run. + for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { + let diag = ctxt.sess().diagnostic(); - if attr.is_word() && name == sym::document_private_items { + let name = attr.name_or_empty(); + if attr.is_word() { + if name == sym::no_default_passes { + report_deprecated_attr("no_default_passes", diag); if default_passes == passes::DefaultPassOption::Default { - default_passes = passes::DefaultPassOption::Private; + default_passes = passes::DefaultPassOption::None; } } + } else if let Some(value) = attr.value_str() { + let sink = match name { + sym::passes => { + report_deprecated_attr("passes = \"...\"", diag); + &mut manual_passes + }, + sym::plugins => { + report_deprecated_attr("plugins = \"...\"", diag); + eprintln!("WARNING: `#![doc(plugins = \"...\")]` \ + no longer functions; see CVE-2018-1000622"); + continue + }, + _ => continue, + }; + for name in value.as_str().split_whitespace() { + sink.push(name.to_string()); + } } - let passes = passes::defaults(default_passes).iter().chain(manual_passes.into_iter() - .flat_map(|name| { - if let Some(pass) = passes::find_pass(&name) { - Some(pass) - } else { - error!("unknown pass {}, skipping", name); - None - } - })); + if attr.is_word() && name == sym::document_private_items { + if default_passes == passes::DefaultPassOption::Default { + default_passes = passes::DefaultPassOption::Private; + } + } + } + + let passes = passes::defaults(default_passes).iter().chain(manual_passes.into_iter() + .flat_map(|name| { + if let Some(pass) = passes::find_pass(&name) { + Some(pass) + } else { + error!("unknown pass {}, skipping", name); + None + } + })); - info!("Executing passes"); + info!("Executing passes"); - for pass in passes { - debug!("running pass {}", pass.name); - krate = (pass.pass)(krate, &ctxt); - } + for pass in passes { + debug!("running pass {}", pass.name); + krate = (pass.pass)(krate, &ctxt); + } - ctxt.sess().abort_if_errors(); + ctxt.sess().abort_if_errors(); - (krate, ctxt.renderinfo.into_inner(), render_options) - }) + (krate, ctxt.renderinfo.into_inner(), render_options) }) - }) + }) }) } /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 47eb993dfc31b..4cb97ccb0bf63 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -85,42 +85,41 @@ pub fn run(options: Options) -> i32 { let mut test_args = options.test_args.clone(); let display_warnings = options.display_warnings; - let tests = interface::run_compiler(config, |compiler| -> Result<_, ErrorReported> { - compiler.enter(|queries| { - let lower_to_hir = queries.lower_to_hir()?; - - let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); - opts.display_warnings |= options.display_warnings; - let enable_per_target_ignores = options.enable_per_target_ignores; - let mut collector = Collector::new( - queries.crate_name()?.peek().to_string(), - options, - false, - opts, - Some(compiler.source_map().clone()), - None, - enable_per_target_ignores, - ); - - let mut global_ctxt = queries.global_ctxt()?.take(); - - global_ctxt.enter(|tcx| { - let krate = tcx.hir().krate(); - let mut hir_collector = HirCollector { - sess: compiler.session(), - collector: &mut collector, - map: tcx.hir(), - codes: ErrorCodes::from(compiler.session().opts - .unstable_features.is_nightly_build()), - }; - hir_collector.visit_testable("".to_string(), &krate.attrs, |this| { - intravisit::walk_crate(this, krate); - }); + let tests = interface::run_compiler(config, |compiler| { compiler.enter(|queries| { + let lower_to_hir = queries.lower_to_hir()?; + + let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); + opts.display_warnings |= options.display_warnings; + let enable_per_target_ignores = options.enable_per_target_ignores; + let mut collector = Collector::new( + queries.crate_name()?.peek().to_string(), + options, + false, + opts, + Some(compiler.source_map().clone()), + None, + enable_per_target_ignores, + ); + + let mut global_ctxt = queries.global_ctxt()?.take(); + + global_ctxt.enter(|tcx| { + let krate = tcx.hir().krate(); + let mut hir_collector = HirCollector { + sess: compiler.session(), + collector: &mut collector, + map: tcx.hir(), + codes: ErrorCodes::from(compiler.session().opts + .unstable_features.is_nightly_build()), + }; + hir_collector.visit_testable("".to_string(), &krate.attrs, |this| { + intravisit::walk_crate(this, krate); }); + }); - Ok(collector.tests) - }) - }).expect("compiler aborted in rustdoc!"); + let ret : Result<_, ErrorReported> = Ok(collector.tests); + ret + }) }).expect("compiler aborted in rustdoc!"); test_args.insert(0, "rustdoctest".to_string()); From 144d1c217151bbb6fea6a93a22e9dc9bfabae77f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 17:20:32 +0100 Subject: [PATCH 11/20] Review nits. --- src/librustc_driver/lib.rs | 3 --- src/librustc_interface/queries.rs | 5 +---- src/librustdoc/core.rs | 4 ++-- src/librustdoc/test.rs | 4 ++-- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 7cafc05e39089..c945de8f1e1dc 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -393,9 +393,6 @@ pub fn run_compiler( queries.ongoing_codegen()?; - // Drop GlobalCtxt after starting codegen to free memory - mem::drop(queries.global_ctxt()?.take()); - if sess.opts.debugging_opts.print_type_sizes { sess.code_stats.print_type_sizes(); } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index ba855ef2f8563..3b03cfc12bc11 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -317,7 +317,7 @@ impl Linker { impl Compiler { pub fn enter(&self, f: F) -> T - where F: for<'q> FnOnce(&'q Queries<'_>) -> T + where F: FnOnce(&Queries<'_>) -> T { let queries = Queries::new(&self); f(&queries) @@ -345,9 +345,6 @@ impl Compiler { queries.ongoing_codegen()?; - // Drop GlobalCtxt after starting codegen to free memory. - mem::drop(queries.global_ctxt()?.take()); - let linker = queries.linker()?; Ok(Some(linker)) })?; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index d9d475813b073..7d1f89079f808 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -343,7 +343,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt registry: rustc_driver::diagnostics_registry(), }; - interface::run_compiler_in_existing_thread_pool(config, |compiler| { compiler.enter(|queries| { + interface::run_compiler_in_existing_thread_pool(config, |compiler| compiler.enter(|queries| { let sess = compiler.session(); // We need to hold on to the complete resolver, so we cause everything to be @@ -487,7 +487,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt (krate, ctxt.renderinfo.into_inner(), render_options) }) - }) }) + })) } /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 4cb97ccb0bf63..44d3dac16606b 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -85,7 +85,7 @@ pub fn run(options: Options) -> i32 { let mut test_args = options.test_args.clone(); let display_warnings = options.display_warnings; - let tests = interface::run_compiler(config, |compiler| { compiler.enter(|queries| { + let tests = interface::run_compiler(config, |compiler| compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); @@ -119,7 +119,7 @@ pub fn run(options: Options) -> i32 { let ret : Result<_, ErrorReported> = Ok(collector.tests); ret - }) }).expect("compiler aborted in rustdoc!"); + })).expect("compiler aborted in rustdoc!"); test_args.insert(0, "rustdoctest".to_string()); From 58a9c73bbd9e115888353aa81ee59ee4862c8cf9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 22:48:41 +0100 Subject: [PATCH 12/20] Make the HIR map own the Definitions. --- src/librustc/hir/map/mod.rs | 10 +++++----- src/librustc_interface/passes.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index fc754c5e675e6..5bf5a93ad0102 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -200,7 +200,7 @@ pub struct Map<'hir> { map: HirEntryMap<'hir>, - definitions: &'hir Definitions, + definitions: Definitions, /// The reverse mapping of `node_to_hir_id`. hir_to_node_id: FxHashMap, @@ -267,8 +267,8 @@ impl<'hir> Map<'hir> { } #[inline] - pub fn definitions(&self) -> &'hir Definitions { - self.definitions + pub fn definitions(&self) -> &Definitions { + &self.definitions } pub fn def_key(&self, def_id: DefId) -> DefKey { @@ -1251,7 +1251,7 @@ impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } } pub fn map_crate<'hir>(sess: &crate::session::Session, cstore: &CrateStoreDyn, forest: &'hir Forest, - definitions: &'hir Definitions) + definitions: Definitions) -> Map<'hir> { let _prof_timer = sess.prof.generic_activity("build_hir_map"); @@ -1260,7 +1260,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session, .map(|(node_id, &hir_id)| (hir_id, node_id)).collect(); let (map, crate_hash) = { - let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore); + let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, &definitions, cstore); let mut collector = NodeCollector::root(sess, &forest.krate, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a745d63426b7a..63ea24d89ff85 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -777,7 +777,7 @@ pub fn create_global_ctxt( // Construct the HIR map. let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs) + hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, defs) }); let query_result_on_disk_cache = time(sess, "load query result cache", || { From b99513be57bfb21c546b29999fc541a402e27a10 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 22:51:02 +0100 Subject: [PATCH 13/20] Have Queries own the GlobalCtxt. The construction of the GlobalCtxt is moved from a generator's stack to the Queries struct. Since the GlobalCtxt requires the HIR Forest and the arenas to live longer, those are moved into Queries the same way. The resulting handling of objects is more brittle, because consumers of the Once objects need to be careful of their initialisation. --- src/librustc_interface/passes.rs | 56 ++++++++++++------------------- src/librustc_interface/queries.rs | 53 +++++++++++++++++++---------- src/librustdoc/test.rs | 2 +- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 63ea24d89ff85..99945ebf8c4cf 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -22,7 +22,7 @@ use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; +use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter}; use rustc_errors::PResult; use rustc_incremental; use rustc_metadata::cstore; @@ -740,44 +740,41 @@ pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { rustc_codegen_ssa::provide_extern(providers); } -declare_box_region_type!( - pub BoxedGlobalCtxt, - for('tcx), - (&'tcx GlobalCtxt<'tcx>) -> ((), ()) -); +pub struct BoxedGlobalCtxt<'tcx>(&'tcx GlobalCtxt<'tcx>); -impl BoxedGlobalCtxt { +impl<'gcx> BoxedGlobalCtxt<'gcx> { pub fn enter(&mut self, f: F) -> R where F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R, { - self.access(|gcx| ty::tls::enter_global(gcx, |tcx| f(tcx))) + ty::tls::enter_global(self.0, |tcx| f(tcx)) + } + + pub fn print_stats(&self) { + self.0.queries.print_stats() } } -pub fn create_global_ctxt( - compiler: &Compiler, +pub fn create_global_ctxt<'gcx>( + compiler: &'gcx Compiler, lint_store: Lrc, - mut hir_forest: hir::map::Forest, + hir_forest: &'gcx hir::map::Forest, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, -) -> BoxedGlobalCtxt { - let sess = compiler.session().clone(); + global_ctxt: &'gcx Once>, + arenas: &'gcx Once, +) -> BoxedGlobalCtxt<'gcx> { + let sess = &compiler.session(); let codegen_backend = compiler.codegen_backend().clone(); - let crate_name = crate_name.to_string(); let defs = mem::take(&mut resolver_outputs.definitions); let override_queries = compiler.override_queries; - let ((), result) = BoxedGlobalCtxt::new(static move || { - let sess = &*sess; - - let global_ctxt: Option>; - let arenas = AllArenas::new(); + let arenas = arenas.init_locking(|| AllArenas::new()); // Construct the HIR map. let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, defs) + hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) }); let query_result_on_disk_cache = time(sess, "load query result cache", || { @@ -796,7 +793,7 @@ pub fn create_global_ctxt( callback(sess, &mut local_providers, &mut extern_providers); } - let gcx = TyCtxt::create_global_ctxt( + let gcx = global_ctxt.init_locking(move || TyCtxt::create_global_ctxt( sess, lint_store, local_providers, @@ -807,26 +804,15 @@ pub fn create_global_ctxt( query_result_on_disk_cache, &crate_name, &outputs - ); + )); - global_ctxt = Some(gcx); - let gcx = global_ctxt.as_ref().unwrap(); - - ty::tls::enter_global(gcx, |tcx| { + ty::tls::enter_global(&gcx, |tcx| { // Do some initialization of the DepGraph that can only be done with the // tcx available. time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); }); - yield BoxedGlobalCtxt::initial_yield(()); - box_region_allow_access!(for('tcx), (&'tcx GlobalCtxt<'tcx>), (gcx)); - - if sess.opts.debugging_opts.query_stats { - gcx.queries.print_stats(); - } - }); - - result + BoxedGlobalCtxt(gcx) } /// Runs the resolution, type-checking, region checking and other diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 3b03cfc12bc11..a90483f8c7104 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,7 +2,7 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt}; use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Once}; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; @@ -12,7 +12,7 @@ use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; -use rustc::ty::ResolverOutputs; +use rustc::ty::{AllArenas, ResolverOutputs, GlobalCtxt}; use rustc::dep_graph::DepGraph; use std::cell::{Ref, RefMut, RefCell}; use std::rc::Rc; @@ -70,6 +70,9 @@ impl Default for Query { pub struct Queries<'comp> { compiler: &'comp Compiler, + gcx: Once>, + arenas: Once, + forest: Once, dep_graph_future: Query>, parse: Query, @@ -77,9 +80,9 @@ pub struct Queries<'comp> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(Steal, Steal)>, + lower_to_hir: Query<(&'comp hir::map::Forest, Steal)>, prepare_outputs: Query, - global_ctxt: Query, + global_ctxt: Query>, ongoing_codegen: Query>, } @@ -87,6 +90,9 @@ impl<'comp> Queries<'comp> { pub fn new(compiler: &'comp Compiler) -> Queries<'comp> { Queries { compiler, + gcx: Once::new(), + arenas: Once::new(), + forest: Once::new(), dep_graph_future: Default::default(), parse: Default::default(), crate_name: Default::default(), @@ -209,15 +215,15 @@ impl<'comp> Queries<'comp> { } pub fn lower_to_hir( - &self, - ) -> Result<&Query<(Steal, Steal)>> { + &'comp self, + ) -> Result<&Query<(&'comp hir::map::Forest, 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 = Steal::new(resolver.borrow_mut().access(|resolver| { + let hir = resolver.borrow_mut().access(|resolver| { passes::lower_to_hir( self.session(), lint_store, @@ -225,7 +231,8 @@ impl<'comp> Queries<'comp> { &*self.dep_graph()?.peek(), &krate ) - })?); + })?; + let hir = self.forest.init_locking(|| hir); Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) }) } @@ -242,25 +249,27 @@ impl<'comp> Queries<'comp> { }) } - pub fn global_ctxt(&self) -> Result<&Query> { + pub fn global_ctxt(&'comp self) -> Result<&Query>> { 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()?; - let hir = hir.peek(); - let (hir_forest, resolver_outputs) = &*hir; + let hir = self.lower_to_hir()?.peek(); + let (ref hir_forest, ref resolver_outputs) = &*hir; Ok(passes::create_global_ctxt( self.compiler, lint_store, - hir_forest.steal(), + hir_forest, resolver_outputs.steal(), outputs, - &crate_name)) + &crate_name, + &self.gcx, + &self.arenas, + )) }) } - pub fn ongoing_codegen(&self) -> Result<&Query>> { + pub fn ongoing_codegen(&'comp self) -> Result<&Query>> { self.ongoing_codegen.compute(|| { let outputs = self.prepare_outputs()?; self.global_ctxt()?.peek_mut().enter(|tcx| { @@ -278,7 +287,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn linker(&self) -> Result { + pub fn linker(&'comp self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; let ongoing_codegen = self.ongoing_codegen()?; @@ -317,10 +326,18 @@ impl Linker { impl Compiler { pub fn enter(&self, f: F) -> T - where F: FnOnce(&Queries<'_>) -> T + where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T { let queries = Queries::new(&self); - f(&queries) + let ret = f(&queries); + + if self.session().opts.debugging_opts.query_stats { + if let Ok(gcx) = queries.global_ctxt() { + gcx.peek().print_stats(); + } + } + + ret } // This method is different to all the other methods in `Compiler` because diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 44d3dac16606b..d09eb0b2fc263 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -88,7 +88,7 @@ pub fn run(options: Options) -> i32 { let tests = interface::run_compiler(config, |compiler| compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; - let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); + let mut opts = scrape_test_config(lower_to_hir.peek().0.krate()); opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( From 7b71e9a9df06aebe89c162138e03577e18e09d2a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 22:56:05 +0100 Subject: [PATCH 14/20] Formatting. --- src/librustc_interface/passes.rs | 72 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 99945ebf8c4cf..b264f1d3fe70f 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -766,51 +766,49 @@ pub fn create_global_ctxt<'gcx>( arenas: &'gcx Once, ) -> BoxedGlobalCtxt<'gcx> { let sess = &compiler.session(); - let codegen_backend = compiler.codegen_backend().clone(); let defs = mem::take(&mut resolver_outputs.definitions); - let override_queries = compiler.override_queries; - - let arenas = arenas.init_locking(|| AllArenas::new()); - // Construct the HIR map. - let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) - }); + // Construct the HIR map. + let hir_map = time(sess, "indexing HIR", || { + hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) + }); - let query_result_on_disk_cache = time(sess, "load query result cache", || { - rustc_incremental::load_query_result_cache(sess) - }); + let query_result_on_disk_cache = time(sess, "load query result cache", || { + rustc_incremental::load_query_result_cache(sess) + }); - let mut local_providers = ty::query::Providers::default(); - default_provide(&mut local_providers); - codegen_backend.provide(&mut local_providers); + let codegen_backend = compiler.codegen_backend(); + let mut local_providers = ty::query::Providers::default(); + default_provide(&mut local_providers); + codegen_backend.provide(&mut local_providers); - let mut extern_providers = local_providers; - default_provide_extern(&mut extern_providers); - codegen_backend.provide_extern(&mut extern_providers); + let mut extern_providers = local_providers; + default_provide_extern(&mut extern_providers); + codegen_backend.provide_extern(&mut extern_providers); - if let Some(callback) = override_queries { - callback(sess, &mut local_providers, &mut extern_providers); - } + let override_queries = compiler.override_queries; + if let Some(callback) = override_queries { + callback(sess, &mut local_providers, &mut extern_providers); + } - let gcx = global_ctxt.init_locking(move || TyCtxt::create_global_ctxt( - sess, - lint_store, - local_providers, - extern_providers, - &arenas, - resolver_outputs, - hir_map, - query_result_on_disk_cache, - &crate_name, - &outputs - )); + let arenas = arenas.init_locking(|| AllArenas::new()); + let gcx = global_ctxt.init_locking(|| TyCtxt::create_global_ctxt( + sess, + lint_store, + local_providers, + extern_providers, + &arenas, + resolver_outputs, + hir_map, + query_result_on_disk_cache, + &crate_name, + &outputs + )); - ty::tls::enter_global(&gcx, |tcx| { - // Do some initialization of the DepGraph that can only be done with the - // tcx available. - time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); - }); + // Do some initialization of the DepGraph that can only be done with the tcx available. + ty::tls::enter_global(&gcx, |tcx| { + time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); + }); BoxedGlobalCtxt(gcx) } From 7e72b36299d54eb3e39991c9b2a9cbaeacccda3e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 26 Nov 2019 23:16:48 +0100 Subject: [PATCH 15/20] Move local Arena to Queries. --- src/librustc/ty/context.rs | 5 +++-- src/librustc_interface/passes.rs | 5 ++++- src/librustc_interface/queries.rs | 7 ++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 954565811694f..91afa0153c8b3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -995,7 +995,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> { } pub struct GlobalCtxt<'tcx> { - pub arena: WorkerLocal>, + pub arena: &'tcx WorkerLocal>, interners: CtxtInterners<'tcx>, @@ -1170,6 +1170,7 @@ impl<'tcx> TyCtxt<'tcx> { local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, + local_arena: &'tcx WorkerLocal>, resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, on_disk_query_result_cache: query::OnDiskCache<'tcx>, @@ -1225,7 +1226,7 @@ impl<'tcx> TyCtxt<'tcx> { sess: s, lint_store, cstore, - arena: WorkerLocal::new(|_| Arena::default()), + arena: local_arena, interners, dep_graph, prof: s.prof.clone(), diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index b264f1d3fe70f..963663e7d0390 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -3,6 +3,7 @@ use crate::util; use crate::proc_macro_decls; use log::{info, warn, log_enabled}; +use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir; use rustc::hir::lowering::lower_crate; @@ -22,7 +23,7 @@ use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter}; +use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter, WorkerLocal}; use rustc_errors::PResult; use rustc_incremental; use rustc_metadata::cstore; @@ -764,6 +765,7 @@ pub fn create_global_ctxt<'gcx>( crate_name: &str, global_ctxt: &'gcx Once>, arenas: &'gcx Once, + local_arena: &'gcx WorkerLocal>, ) -> BoxedGlobalCtxt<'gcx> { let sess = &compiler.session(); let defs = mem::take(&mut resolver_outputs.definitions); @@ -798,6 +800,7 @@ pub fn create_global_ctxt<'gcx>( local_providers, extern_providers, &arenas, + local_arena, resolver_outputs, hir_map, query_result_on_disk_cache, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index a90483f8c7104..4e9e476c64b99 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,10 +2,11 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt}; use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::{Lrc, Once}; +use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; +use rustc::arena::Arena; use rustc::hir; use rustc::lint; use rustc::session::Session; @@ -74,6 +75,8 @@ pub struct Queries<'comp> { arenas: Once, forest: Once, + local_arena: WorkerLocal>, + dep_graph_future: Query>, parse: Query, crate_name: Query, @@ -93,6 +96,7 @@ impl<'comp> Queries<'comp> { gcx: Once::new(), arenas: Once::new(), forest: Once::new(), + local_arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), parse: Default::default(), crate_name: Default::default(), @@ -265,6 +269,7 @@ impl<'comp> Queries<'comp> { &crate_name, &self.gcx, &self.arenas, + &self.local_arena, )) }) } From 79e232401e07c48020b327a947c9d98d0696f082 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Nov 2019 13:13:57 +0100 Subject: [PATCH 16/20] Rename lifetimes. --- src/librustc_interface/passes.rs | 18 +++++++++--------- src/librustc_interface/queries.rs | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 963663e7d0390..d3e29fa111130 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -743,10 +743,10 @@ pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { pub struct BoxedGlobalCtxt<'tcx>(&'tcx GlobalCtxt<'tcx>); -impl<'gcx> BoxedGlobalCtxt<'gcx> { +impl<'tcx> BoxedGlobalCtxt<'tcx> { pub fn enter(&mut self, f: F) -> R where - F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R, + F: FnOnce(TyCtxt<'tcx>) -> R, { ty::tls::enter_global(self.0, |tcx| f(tcx)) } @@ -756,17 +756,17 @@ impl<'gcx> BoxedGlobalCtxt<'gcx> { } } -pub fn create_global_ctxt<'gcx>( - compiler: &'gcx Compiler, +pub fn create_global_ctxt<'tcx>( + compiler: &'tcx Compiler, lint_store: Lrc, - hir_forest: &'gcx hir::map::Forest, + hir_forest: &'tcx hir::map::Forest, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, - global_ctxt: &'gcx Once>, - arenas: &'gcx Once, - local_arena: &'gcx WorkerLocal>, -) -> BoxedGlobalCtxt<'gcx> { + global_ctxt: &'tcx Once>, + arenas: &'tcx Once, + local_arena: &'tcx WorkerLocal>, +) -> BoxedGlobalCtxt<'tcx> { let sess = &compiler.session(); let defs = mem::take(&mut resolver_outputs.definitions); diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 4e9e476c64b99..04bf04189bd46 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -69,13 +69,13 @@ impl Default for Query { } } -pub struct Queries<'comp> { - compiler: &'comp Compiler, - gcx: Once>, +pub struct Queries<'tcx> { + compiler: &'tcx Compiler, + gcx: Once>, arenas: Once, forest: Once, - local_arena: WorkerLocal>, + local_arena: WorkerLocal>, dep_graph_future: Query>, parse: Query, @@ -83,14 +83,14 @@ pub struct Queries<'comp> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(&'comp hir::map::Forest, Steal)>, + lower_to_hir: Query<(&'tcx hir::map::Forest, Steal)>, prepare_outputs: Query, - global_ctxt: Query>, + global_ctxt: Query>, ongoing_codegen: Query>, } -impl<'comp> Queries<'comp> { - pub fn new(compiler: &'comp Compiler) -> Queries<'comp> { +impl<'tcx> Queries<'tcx> { + pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { Queries { compiler, gcx: Once::new(), @@ -219,8 +219,8 @@ impl<'comp> Queries<'comp> { } pub fn lower_to_hir( - &'comp self, - ) -> Result<&Query<(&'comp hir::map::Forest, Steal)>> { + &'tcx self, + ) -> Result<&Query<(&'tcx hir::map::Forest, Steal)>> { self.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); @@ -253,7 +253,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn global_ctxt(&'comp self) -> Result<&Query>> { + pub fn global_ctxt(&'tcx self) -> Result<&Query>> { self.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); @@ -274,7 +274,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn ongoing_codegen(&'comp self) -> Result<&Query>> { + pub fn ongoing_codegen(&'tcx self) -> Result<&Query>> { self.ongoing_codegen.compute(|| { let outputs = self.prepare_outputs()?; self.global_ctxt()?.peek_mut().enter(|tcx| { @@ -292,7 +292,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn linker(&'comp self) -> Result { + pub fn linker(&'tcx self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; let ongoing_codegen = self.ongoing_codegen()?; From e5ed1010987c21a4a5d4ea4e46aebf7adc872bfc Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Nov 2019 13:17:58 +0100 Subject: [PATCH 17/20] Rename BoxedGlobalCtxt. --- src/librustc_interface/passes.rs | 8 ++++---- src/librustc_interface/queries.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d3e29fa111130..d2bb2cdfaffac 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -741,9 +741,9 @@ pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { rustc_codegen_ssa::provide_extern(providers); } -pub struct BoxedGlobalCtxt<'tcx>(&'tcx GlobalCtxt<'tcx>); +pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>); -impl<'tcx> BoxedGlobalCtxt<'tcx> { +impl<'tcx> QueryContext<'tcx> { pub fn enter(&mut self, f: F) -> R where F: FnOnce(TyCtxt<'tcx>) -> R, @@ -766,7 +766,7 @@ pub fn create_global_ctxt<'tcx>( global_ctxt: &'tcx Once>, arenas: &'tcx Once, local_arena: &'tcx WorkerLocal>, -) -> BoxedGlobalCtxt<'tcx> { +) -> QueryContext<'tcx> { let sess = &compiler.session(); let defs = mem::take(&mut resolver_outputs.definitions); @@ -813,7 +813,7 @@ pub fn create_global_ctxt<'tcx>( time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); }); - BoxedGlobalCtxt(gcx) + QueryContext(gcx) } /// Runs the resolution, type-checking, region checking and other diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 04bf04189bd46..581ebe9c00fe1 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -1,5 +1,5 @@ use crate::interface::{Compiler, Result}; -use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt}; +use crate::passes::{self, BoxedResolver, QueryContext}; use rustc_incremental::DepGraphFuture; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; @@ -85,7 +85,7 @@ pub struct Queries<'tcx> { dep_graph: Query, lower_to_hir: Query<(&'tcx hir::map::Forest, Steal)>, prepare_outputs: Query, - global_ctxt: Query>, + global_ctxt: Query>, ongoing_codegen: Query>, } @@ -253,7 +253,7 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn global_ctxt(&'tcx self) -> Result<&Query>> { + pub fn global_ctxt(&'tcx self) -> Result<&Query>> { self.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); From 77a4c85e54401e06ea0cc8539a183ab8d08fa005 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Nov 2019 13:19:33 +0100 Subject: [PATCH 18/20] Simplify handling of AllArenas. --- src/librustc_interface/passes.rs | 5 ++--- src/librustc_interface/queries.rs | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index d2bb2cdfaffac..66666a027c0d5 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -764,7 +764,7 @@ pub fn create_global_ctxt<'tcx>( outputs: OutputFilenames, crate_name: &str, global_ctxt: &'tcx Once>, - arenas: &'tcx Once, + all_arenas: &'tcx AllArenas, local_arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); @@ -793,13 +793,12 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } - let arenas = arenas.init_locking(|| AllArenas::new()); let gcx = global_ctxt.init_locking(|| TyCtxt::create_global_ctxt( sess, lint_store, local_providers, extern_providers, - &arenas, + &all_arenas, local_arena, resolver_outputs, hir_map, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 581ebe9c00fe1..7e8ba9f270258 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -72,9 +72,9 @@ impl Default for Query { pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: Once>, - arenas: Once, forest: Once, + all_arenas: AllArenas, local_arena: WorkerLocal>, dep_graph_future: Query>, @@ -94,8 +94,8 @@ impl<'tcx> Queries<'tcx> { Queries { compiler, gcx: Once::new(), - arenas: Once::new(), forest: Once::new(), + all_arenas: AllArenas::new(), local_arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), parse: Default::default(), @@ -268,7 +268,7 @@ impl<'tcx> Queries<'tcx> { outputs, &crate_name, &self.gcx, - &self.arenas, + &self.all_arenas, &self.local_arena, )) }) From e321ba989c9f03748d5c19aead84edfcc9e9e69a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Nov 2019 13:24:19 +0100 Subject: [PATCH 19/20] Misc renames. --- src/librustc/ty/context.rs | 4 ++-- src/librustc_interface/passes.rs | 7 +++---- src/librustc_interface/queries.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 91afa0153c8b3..3c1cfa3f79f37 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1170,7 +1170,7 @@ impl<'tcx> TyCtxt<'tcx> { local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, - local_arena: &'tcx WorkerLocal>, + arena: &'tcx WorkerLocal>, resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, on_disk_query_result_cache: query::OnDiskCache<'tcx>, @@ -1226,7 +1226,7 @@ impl<'tcx> TyCtxt<'tcx> { sess: s, lint_store, cstore, - arena: local_arena, + arena, interners, dep_graph, prof: s.prof.clone(), diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 66666a027c0d5..1df84ce0b7394 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -765,7 +765,7 @@ pub fn create_global_ctxt<'tcx>( crate_name: &str, global_ctxt: &'tcx Once>, all_arenas: &'tcx AllArenas, - local_arena: &'tcx WorkerLocal>, + arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); let defs = mem::take(&mut resolver_outputs.definitions); @@ -788,8 +788,7 @@ pub fn create_global_ctxt<'tcx>( default_provide_extern(&mut extern_providers); codegen_backend.provide_extern(&mut extern_providers); - let override_queries = compiler.override_queries; - if let Some(callback) = override_queries { + if let Some(callback) = compiler.override_queries { callback(sess, &mut local_providers, &mut extern_providers); } @@ -799,7 +798,7 @@ pub fn create_global_ctxt<'tcx>( local_providers, extern_providers, &all_arenas, - local_arena, + arena, resolver_outputs, hir_map, query_result_on_disk_cache, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 7e8ba9f270258..53ab5eb990ddf 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -75,7 +75,7 @@ pub struct Queries<'tcx> { forest: Once, all_arenas: AllArenas, - local_arena: WorkerLocal>, + arena: WorkerLocal>, dep_graph_future: Query>, parse: Query, @@ -96,7 +96,7 @@ impl<'tcx> Queries<'tcx> { gcx: Once::new(), forest: Once::new(), all_arenas: AllArenas::new(), - local_arena: WorkerLocal::new(|_| Arena::default()), + arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), parse: Default::default(), crate_name: Default::default(), @@ -269,7 +269,7 @@ impl<'tcx> Queries<'tcx> { &crate_name, &self.gcx, &self.all_arenas, - &self.local_arena, + &self.arena, )) }) } From 1e12f39d83eeddd523e384e20ab4f1fa56eb8888 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Nov 2019 13:32:28 +0100 Subject: [PATCH 20/20] Allocate HIR Forest on arena. --- src/librustc/arena.rs | 1 + src/librustc_interface/queries.rs | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 9b13a910c6174..193b04eabb3fb 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -93,6 +93,7 @@ macro_rules! arena_types { rustc::hir::def_id::CrateNum > >, + [few] hir_forest: rustc::hir::map::Forest, [few] diagnostic_items: rustc_data_structures::fx::FxHashMap< syntax::symbol::Symbol, rustc::hir::def_id::DefId, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 53ab5eb990ddf..6103d42c5dbcb 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -72,7 +72,6 @@ impl Default for Query { pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: Once>, - forest: Once, all_arenas: AllArenas, arena: WorkerLocal>, @@ -94,7 +93,6 @@ impl<'tcx> Queries<'tcx> { Queries { compiler, gcx: Once::new(), - forest: Once::new(), all_arenas: AllArenas::new(), arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), @@ -236,7 +234,7 @@ impl<'tcx> Queries<'tcx> { &krate ) })?; - let hir = self.forest.init_locking(|| hir); + let hir = self.arena.alloc(hir); Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) }) }