diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 6ee7213a19d83..5ab14fbc68742 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -360,8 +360,8 @@ fn run_compiler( drop(default_handler); interface::run_compiler(config, |compiler| { - let sess = compiler.session(); - let codegen_backend = compiler.codegen_backend(); + let sess = &compiler.sess; + let codegen_backend = &*compiler.codegen_backend; // This implements `-Whelp`. It should be handled very early, like // `--help`/`-Zhelp`/`-Chelp`. This is the earliest it can run, because @@ -453,8 +453,10 @@ fn run_compiler( return early_exit(); } - let ongoing_codegen = queries.ongoing_codegen()?; + let linker = queries.codegen_and_build_linker()?; + // This must run after monomorphization so that all generic types + // have been instantiated. if sess.opts.unstable_opts.print_type_sizes { sess.code_stats.print_type_sizes(); } @@ -465,10 +467,11 @@ fn run_compiler( sess.code_stats.print_vtable_sizes(crate_name); } - let linker = queries.linker(ongoing_codegen)?; Ok(Some(linker)) })?; + // Linking is done outside the `compiler.enter()` so that the + // `GlobalCtxt` within `Queries` can be freed as early as possible. if let Some(linker) = linker { let _timer = sess.timer("link"); linker.link(sess, codegen_backend)? @@ -668,7 +671,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { }; } }; - let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); + let result = compiler.codegen_backend.link(sess, codegen_results, &outputs); abort_on_err(result, sess); } else { sess.emit_fatal(RlinkNotAFile {}) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 6225424fe4ac8..91fd4b4a1d0fb 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -38,18 +38,12 @@ pub type Result = result::Result; /// Can be used to run `rustc_interface` queries. /// Created by passing [`Config`] to [`run_compiler`]. pub struct Compiler { - sess: Session, - codegen_backend: Box, + pub sess: Session, + pub codegen_backend: Box, pub(crate) override_queries: Option, } impl Compiler { - pub fn session(&self) -> &Session { - &self.sess - } - pub fn codegen_backend(&self) -> &dyn CodegenBackend { - &*self.codegen_backend - } pub fn build_output_filenames( &self, sess: &Session, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 0fc2bb7a2d4f2..99bea647bd5e7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -645,10 +645,10 @@ pub fn create_global_ctxt<'tcx>( // incr. comp. yet. dep_graph.assert_ignored(); - let sess = &compiler.session(); + let sess = &compiler.sess; let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); - let codegen_backend = compiler.codegen_backend(); + let codegen_backend = &compiler.codegen_backend; let mut providers = *DEFAULT_QUERY_PROVIDERS; codegen_backend.provide(&mut providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 3fee2d2898184..1c65cf19cde39 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -17,7 +17,8 @@ use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{GlobalCtxt, TyCtxt}; use rustc_session::config::{self, CrateType, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; -use rustc_session::{output::find_crate_name, Session}; +use rustc_session::output::find_crate_name; +use rustc_session::Session; use rustc_span::symbol::sym; use std::any::Any; use std::cell::{RefCell, RefMut}; @@ -101,17 +102,10 @@ impl<'tcx> Queries<'tcx> { } } - fn session(&self) -> &Session { - self.compiler.session() - } - - fn codegen_backend(&self) -> &dyn CodegenBackend { - self.compiler.codegen_backend() - } - pub fn parse(&self) -> Result> { - self.parse - .compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit())) + self.parse.compute(|| { + passes::parse(&self.compiler.sess).map_err(|mut parse_error| parse_error.emit()) + }) } #[deprecated = "pre_configure may be made private in the future. If you need it please open an issue with your use case."] @@ -119,7 +113,7 @@ impl<'tcx> Queries<'tcx> { self.pre_configure.compute(|| { let mut krate = self.parse()?.steal(); - let sess = self.session(); + let sess = &self.compiler.sess; rustc_builtin_macros::cmdline_attrs::inject( &mut krate, &sess.parse_sess, @@ -134,7 +128,7 @@ impl<'tcx> Queries<'tcx> { pub fn global_ctxt(&'tcx self) -> Result>> { self.gcx.compute(|| { - let sess = self.session(); + let sess = &self.compiler.sess; #[allow(deprecated)] let (krate, pre_configured_attrs) = self.pre_configure()?.steal(); @@ -150,7 +144,7 @@ impl<'tcx> Queries<'tcx> { let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?; let cstore = FreezeLock::new(Box::new(CStore::new( - self.codegen_backend().metadata_loader(), + self.compiler.codegen_backend.metadata_loader(), stable_crate_id, )) as _); let definitions = FreezeLock::new(Definitions::new(stable_crate_id)); @@ -186,22 +180,6 @@ impl<'tcx> Queries<'tcx> { }) } - pub fn ongoing_codegen(&'tcx self) -> Result> { - self.global_ctxt()?.enter(|tcx| { - // Don't do code generation if there were any errors - self.session().compile_status()?; - - // If we have any delayed bugs, for example because we created TyKind::Error earlier, - // it's likely that codegen will only cause more ICEs, obscuring the original problem - self.session().diagnostic().flush_delayed(); - - // Hook for UI tests. - Self::check_for_rustc_errors_attr(tcx); - - Ok(passes::start_codegen(self.codegen_backend(), tcx)) - }) - } - /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used /// to write UI tests that actually test that compilation succeeds without reporting /// an error. @@ -236,8 +214,20 @@ impl<'tcx> Queries<'tcx> { } } - pub fn linker(&'tcx self, ongoing_codegen: Box) -> Result { + pub fn codegen_and_build_linker(&'tcx self) -> Result { self.global_ctxt()?.enter(|tcx| { + // Don't do code generation if there were any errors + self.compiler.sess.compile_status()?; + + // If we have any delayed bugs, for example because we created TyKind::Error earlier, + // it's likely that codegen will only cause more ICEs, obscuring the original problem + self.compiler.sess.diagnostic().flush_delayed(); + + // Hook for UI tests. + Self::check_for_rustc_errors_attr(tcx); + + let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx); + Ok(Linker { dep_graph: tcx.dep_graph.clone(), output_filenames: tcx.output_filenames(()).clone(), @@ -304,6 +294,7 @@ impl Compiler { where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, { + // Must declare `_timer` first so that it is dropped after `queries`. let mut _timer = None; let queries = Queries::new(self); let ret = f(&queries); @@ -316,15 +307,16 @@ impl Compiler { // after this point, they'll show up as "" in self-profiling data. { let _prof_timer = - queries.session().prof.generic_activity("self_profile_alloc_query_strings"); + queries.compiler.sess.prof.generic_activity("self_profile_alloc_query_strings"); gcx.enter(rustc_query_impl::alloc_self_profile_query_strings); } - self.session() - .time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); + self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); } - _timer = Some(self.session().timer("free_global_ctxt")); + // The timer's lifetime spans the dropping of `queries`, which contains + // the global context. + _timer = Some(self.sess.timer("free_global_ctxt")); ret } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e551e37f18197..3a114bcc18566 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -127,17 +127,17 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { options, false, opts, - Some(compiler.session().parse_sess.clone_source_map()), + Some(compiler.sess.parse_sess.clone_source_map()), None, enable_per_target_ignores, ); let mut hir_collector = HirCollector { - sess: compiler.session(), + sess: &compiler.sess, collector: &mut collector, map: tcx.hir(), codes: ErrorCodes::from( - compiler.session().opts.unstable_features.is_nightly_build(), + compiler.sess.opts.unstable_features.is_nightly_build(), ), tcx, }; @@ -150,7 +150,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { collector }); - if compiler.session().diagnostic().has_errors_or_lint_errors().is_some() { + if compiler.sess.diagnostic().has_errors_or_lint_errors().is_some() { FatalError.raise(); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5144bbdaf5e1d..1c02e0ba76ecf 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -794,7 +794,7 @@ fn main_args( let config = core::create_config(options, &render_options, using_internal_features); interface::run_compiler(config, |compiler| { - let sess = compiler.session(); + let sess = &compiler.sess; if sess.opts.describe_lints { rustc_driver::describe_lints(sess); diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs index 9be0fdccebecf..a0bbe3851e82f 100644 --- a/tests/run-make-fulldeps/issue-19371/foo.rs +++ b/tests/run-make-fulldeps/issue-19371/foo.rs @@ -69,9 +69,8 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { interface::run_compiler(config, |compiler| { let linker = compiler.enter(|queries| { queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?; - let ongoing_codegen = queries.ongoing_codegen()?; - queries.linker(ongoing_codegen) + queries.codegen_and_build_linker() }); - linker.unwrap().link(compiler.session(), compiler.codegen_backend()).unwrap(); + linker.unwrap().link(&compiler.sess, &*compiler.codegen_backend).unwrap(); }); } diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 5df4c558ee17f..9cbe9e5900abd 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -61,7 +61,7 @@ impl rustc_driver::Callbacks for CompilerCalls { compiler: &Compiler, queries: &'tcx Queries<'tcx>, ) -> Compilation { - compiler.session().abort_if_errors(); + compiler.sess.abort_if_errors(); queries.global_ctxt().unwrap().enter(|tcx| { // Collect definition ids of MIR bodies. let hir = tcx.hir();