diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b80736f41ada1..6f7b943c64972 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -45,7 +45,7 @@ use rustc_errors::registry::Registry; use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown}; use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, get_codegen_backend}; -use rustc_interface::{Linker, interface, passes}; +use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes}; use rustc_lint::unerased_lint_store; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; @@ -387,76 +387,69 @@ fn run_compiler( return early_exit(); } - let linker = compiler.enter(|queries| { + // Parse the crate root source code (doesn't parse submodules yet) + // Everything else is parsed during macro expansion. + let krate = passes::parse(sess); + + // If pretty printing is requested: Figure out the representation, print it and exit + if let Some(pp_mode) = sess.opts.pretty { + if pp_mode.needs_ast_map() { + create_and_enter_global_ctxt(compiler, krate, |tcx| { + tcx.ensure().early_lint_checks(()); + pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx }); + passes::write_dep_info(tcx); + }); + } else { + pretty::print(sess, pp_mode, pretty::PrintExtra::AfterParsing { krate: &krate }); + } + trace!("finished pretty-printing"); + return early_exit(); + } + + if callbacks.after_crate_root_parsing(compiler, &krate) == Compilation::Stop { + return early_exit(); + } + + if sess.opts.unstable_opts.parse_crate_root_only { + return early_exit(); + } + + let linker = create_and_enter_global_ctxt(compiler, krate, |tcx| { let early_exit = || { sess.dcx().abort_if_errors(); None }; - // Parse the crate root source code (doesn't parse submodules yet) - // Everything else is parsed during macro expansion. - queries.parse(); - - // If pretty printing is requested: Figure out the representation, print it and exit - if let Some(pp_mode) = sess.opts.pretty { - if pp_mode.needs_ast_map() { - queries.global_ctxt().enter(|tcx| { - tcx.ensure().early_lint_checks(()); - pretty::print(sess, pp_mode, pretty::PrintExtra::NeedsAstMap { tcx }); - passes::write_dep_info(tcx); - }); - } else { - let krate = queries.parse(); - pretty::print(sess, pp_mode, pretty::PrintExtra::AfterParsing { - krate: &*krate.borrow(), - }); - } - trace!("finished pretty-printing"); + // Make sure name resolution and macro expansion is run. + let _ = tcx.resolver_for_lowering(); + + if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir { + dump_feature_usage_metrics(tcx, metrics_dir); + } + + if callbacks.after_expansion(compiler, tcx) == Compilation::Stop { return early_exit(); } - if callbacks.after_crate_root_parsing(compiler, &*queries.parse().borrow()) - == Compilation::Stop + passes::write_dep_info(tcx); + + if sess.opts.output_types.contains_key(&OutputType::DepInfo) + && sess.opts.output_types.len() == 1 { return early_exit(); } - if sess.opts.unstable_opts.parse_crate_root_only { + if sess.opts.unstable_opts.no_analysis { return early_exit(); } - queries.global_ctxt().enter(|tcx| { - // Make sure name resolution and macro expansion is run. - let _ = tcx.resolver_for_lowering(); - - if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir { - dump_feature_usage_metrics(tcx, metrics_dir); - } - - if callbacks.after_expansion(compiler, tcx) == Compilation::Stop { - return early_exit(); - } - - passes::write_dep_info(tcx); - - if sess.opts.output_types.contains_key(&OutputType::DepInfo) - && sess.opts.output_types.len() == 1 - { - return early_exit(); - } - - if sess.opts.unstable_opts.no_analysis { - return early_exit(); - } + tcx.ensure().analysis(()); - tcx.ensure().analysis(()); - - if callbacks.after_analysis(compiler, tcx) == Compilation::Stop { - return early_exit(); - } + if callbacks.after_analysis(compiler, tcx) == Compilation::Stop { + return early_exit(); + } - Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)) - }) + Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)) }); // Linking is done outside the `compiler.enter()` so that the diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 1c4dda2a4367e..a2a29612e489f 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -8,7 +8,7 @@ // tidy-alphabetical-end mod callbacks; -mod errors; +pub mod errors; pub mod interface; pub mod passes; mod proc_macro_decls; @@ -17,8 +17,8 @@ pub mod util; pub use callbacks::setup_callbacks; pub use interface::{Config, run_compiler}; -pub use passes::DEFAULT_QUERY_PROVIDERS; -pub use queries::{Linker, Queries}; +pub use passes::{DEFAULT_QUERY_PROVIDERS, create_and_enter_global_ctxt, parse}; +pub use queries::Linker; #[cfg(test)] mod tests; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f8351a81bec64..2b5271939e53f 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -41,7 +41,7 @@ use tracing::{info, instrument}; use crate::interface::Compiler; use crate::{errors, proc_macro_decls, util}; -pub(crate) fn parse<'a>(sess: &'a Session) -> ast::Crate { +pub fn parse<'a>(sess: &'a Session) -> ast::Crate { let krate = sess .time("parse_crate", || { let mut parser = unwrap_or_emit_fatal(match &sess.io.input { @@ -711,13 +711,11 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { *providers }); -pub(crate) fn create_global_ctxt<'tcx>( - compiler: &'tcx Compiler, +pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( + compiler: &Compiler, mut krate: rustc_ast::Crate, - gcx_cell: &'tcx OnceLock>, - arena: &'tcx WorkerLocal>, - hir_arena: &'tcx WorkerLocal>, -) -> &'tcx GlobalCtxt<'tcx> { + f: F, +) -> T { let sess = &compiler.sess; rustc_builtin_macros::cmdline_attrs::inject( @@ -765,44 +763,64 @@ pub(crate) fn create_global_ctxt<'tcx>( let incremental = dep_graph.is_fully_enabled(); - sess.time("setup_global_ctxt", || { - let qcx = gcx_cell.get_or_init(move || { - TyCtxt::create_global_ctxt( - sess, - crate_types, - stable_crate_id, - arena, - hir_arena, - untracked, - dep_graph, - rustc_query_impl::query_callbacks(arena), - rustc_query_impl::query_system( - providers.queries, - providers.extern_queries, - query_result_on_disk_cache, - incremental, - ), - providers.hooks, - compiler.current_gcx.clone(), - ) - }); - - qcx.enter(|tcx| { - let feed = tcx.create_crate_num(stable_crate_id).unwrap(); - assert_eq!(feed.key(), LOCAL_CRATE); - feed.crate_name(crate_name); + let gcx_cell = OnceLock::new(); + let arena = WorkerLocal::new(|_| Arena::default()); + let hir_arena = WorkerLocal::new(|_| rustc_hir::Arena::default()); + + // This closure is necessary to force rustc to perform the correct lifetime + // subtyping for GlobalCtxt::enter to be allowed. + let inner: Box< + dyn for<'tcx> FnOnce( + &'tcx Compiler, + &'tcx OnceLock>, + &'tcx WorkerLocal>, + &'tcx WorkerLocal>, + F, + ) -> T, + > = Box::new(move |compiler, gcx_cell, arena, hir_arena, f| { + let sess = &compiler.sess; + + TyCtxt::create_global_ctxt( + gcx_cell, + sess, + crate_types, + stable_crate_id, + arena, + hir_arena, + untracked, + dep_graph, + rustc_query_impl::query_callbacks(arena), + rustc_query_impl::query_system( + providers.queries, + providers.extern_queries, + query_result_on_disk_cache, + incremental, + ), + providers.hooks, + compiler.current_gcx.clone(), + |tcx| { + let feed = tcx.create_crate_num(stable_crate_id).unwrap(); + assert_eq!(feed.key(), LOCAL_CRATE); + feed.crate_name(crate_name); + + let feed = tcx.feed_unit_query(); + feed.features_query(tcx.arena.alloc(rustc_expand::config::features( + sess, + &pre_configured_attrs, + crate_name, + ))); + feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); + feed.output_filenames(Arc::new(outputs)); + + let res = f(tcx); + // FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()? + tcx.finish(); + res + }, + ) + }); - let feed = tcx.feed_unit_query(); - feed.features_query(tcx.arena.alloc(rustc_expand::config::features( - sess, - &pre_configured_attrs, - crate_name, - ))); - feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); - feed.output_filenames(Arc::new(outputs)); - }); - qcx - }) + inner(compiler, &gcx_cell, &arena, &hir_arena, f) } /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index bb2ad3b3dd014..c8914c9be9c01 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,117 +1,18 @@ use std::any::Any; -use std::cell::{RefCell, RefMut}; use std::sync::Arc; -use rustc_ast as ast; use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{OnceLock, WorkerLocal}; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; -use rustc_middle::ty::{GlobalCtxt, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; use crate::errors::FailedWritingFile; -use crate::interface::Compiler; use crate::passes; -/// Represent the result of a query. -/// -/// This result can be stolen once with the [`steal`] method and generated with the [`compute`] method. -/// -/// [`steal`]: Steal::steal -/// [`compute`]: Self::compute -pub struct Query { - /// `None` means no value has been computed yet. - result: RefCell>>, -} - -impl Query { - fn compute T>(&self, f: F) -> QueryResult<'_, T> { - QueryResult(RefMut::map( - self.result.borrow_mut(), - |r: &mut Option>| -> &mut Steal { - r.get_or_insert_with(|| Steal::new(f())) - }, - )) - } -} - -pub struct QueryResult<'a, T>(RefMut<'a, Steal>); - -impl<'a, T> std::ops::Deref for QueryResult<'a, T> { - type Target = RefMut<'a, Steal>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> { - pub fn enter(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T { - (*self.0).borrow().enter(f) - } -} - -pub struct Queries<'tcx> { - compiler: &'tcx Compiler, - gcx_cell: OnceLock>, - - arena: WorkerLocal>, - hir_arena: WorkerLocal>, - - parse: Query, - // This just points to what's in `gcx_cell`. - gcx: Query<&'tcx GlobalCtxt<'tcx>>, -} - -impl<'tcx> Queries<'tcx> { - pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { - Queries { - compiler, - gcx_cell: OnceLock::new(), - arena: WorkerLocal::new(|_| Arena::default()), - hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), - parse: Query { result: RefCell::new(None) }, - gcx: Query { result: RefCell::new(None) }, - } - } - - pub fn finish(&'tcx self) { - if let Some(gcx) = self.gcx_cell.get() { - gcx.finish(); - } - } - - pub fn parse(&self) -> QueryResult<'_, ast::Crate> { - self.parse.compute(|| passes::parse(&self.compiler.sess)) - } - - pub fn global_ctxt(&'tcx self) -> QueryResult<'tcx, &'tcx GlobalCtxt<'tcx>> { - self.gcx.compute(|| { - let krate = self.parse().steal(); - - passes::create_global_ctxt( - self.compiler, - krate, - &self.gcx_cell, - &self.arena, - &self.hir_arena, - ) - }) - } -} - pub struct Linker { dep_graph: DepGraph, output_filenames: Arc, @@ -186,22 +87,3 @@ impl Linker { codegen_backend.link(sess, codegen_results, &self.output_filenames) } } - -impl Compiler { - pub fn enter(&self, f: F) -> T - where - F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, - { - // Must declare `_timer` first so that it is dropped after `queries`. - let _timer; - let queries = Queries::new(self); - let ret = f(&queries); - - // The timer's lifetime spans the dropping of `queries`, which contains - // the global context. - _timer = self.sess.timer("free_global_ctxt"); - queries.finish(); - - ret - } -} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f32656decd212..3a1ed206c8b9d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -10,6 +10,7 @@ use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::ops::{Bound, Deref}; +use std::sync::OnceLock; use std::{fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; @@ -1346,46 +1347,6 @@ pub struct GlobalCtxt<'tcx> { /// Stores memory for globals (statics/consts). pub(crate) alloc_map: Lock>, - - current_gcx: CurrentGcx, -} - -impl<'tcx> GlobalCtxt<'tcx> { - /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of - /// `f`. - pub fn enter(&'tcx self, f: F) -> R - where - F: FnOnce(TyCtxt<'tcx>) -> R, - { - let icx = tls::ImplicitCtxt::new(self); - - // Reset `current_gcx` to `None` when we exit. - let _on_drop = defer(move || { - *self.current_gcx.value.write() = None; - }); - - // Set this `GlobalCtxt` as the current one. - { - let mut guard = self.current_gcx.value.write(); - assert!(guard.is_none(), "no `GlobalCtxt` is currently set"); - *guard = Some(self as *const _ as *const ()); - } - - tls::enter_context(&icx, || f(icx.tcx)) - } - - pub fn finish(&'tcx self) { - // We assume that no queries are run past here. If there are new queries - // after this point, they'll show up as "" in self-profiling data. - self.enter(|tcx| tcx.alloc_self_profile_query_strings()); - - self.enter(|tcx| tcx.save_dep_graph()); - self.enter(|tcx| tcx.query_key_hash_verify_all()); - - if let Err((path, error)) = self.dep_graph.finish_encoding() { - self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error }); - } - } } /// This is used to get a reference to a `GlobalCtxt` if one is available. @@ -1529,7 +1490,8 @@ impl<'tcx> TyCtxt<'tcx> { /// By only providing the `TyCtxt` inside of the closure we enforce that the type /// context and any interned value (types, args, etc.) can only be used while `ty::tls` /// has a valid reference to the context, to allow formatting values that need it. - pub fn create_global_ctxt( + pub fn create_global_ctxt( + gcx_cell: &'tcx OnceLock>, s: &'tcx Session, crate_types: Vec, stable_crate_id: StableCrateId, @@ -1541,7 +1503,8 @@ impl<'tcx> TyCtxt<'tcx> { query_system: QuerySystem<'tcx>, hooks: crate::hooks::Providers, current_gcx: CurrentGcx, - ) -> GlobalCtxt<'tcx> { + f: impl FnOnce(TyCtxt<'tcx>) -> T, + ) -> T { let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.dcx().emit_fatal(err); }); @@ -1550,7 +1513,7 @@ impl<'tcx> TyCtxt<'tcx> { let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types, s, &untracked); - GlobalCtxt { + let gcx = gcx_cell.get_or_init(|| GlobalCtxt { sess: s, crate_types, stable_crate_id, @@ -1574,8 +1537,23 @@ impl<'tcx> TyCtxt<'tcx> { canonical_param_env_cache: Default::default(), data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), - current_gcx, + }); + + let icx = tls::ImplicitCtxt::new(&gcx); + + // Reset `current_gcx` to `None` when we exit. + let _on_drop = defer(|| { + *current_gcx.value.write() = None; + }); + + // Set this `GlobalCtxt` as the current one. + { + let mut guard = current_gcx.value.write(); + assert!(guard.is_none(), "no `GlobalCtxt` is currently set"); + *guard = Some(&gcx as *const _ as *const ()); } + + tls::enter_context(&icx, || f(icx.tcx)) } /// Obtain all lang items of this crate and all dependencies (recursively) @@ -2119,6 +2097,19 @@ impl<'tcx> TyCtxt<'tcx> { pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { self.hir().expect_opaque_ty(def_id).origin } + + pub fn finish(self) { + // We assume that no queries are run past here. If there are new queries + // after this point, they'll show up as "" in self-profiling data. + self.alloc_self_profile_query_strings(); + + self.save_dep_graph(); + self.query_key_hash_verify_all(); + + if let Err((path, error)) = self.dep_graph.finish_encoding() { + self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error }); + } + } } macro_rules! nop_lift { diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 64d241067a845..dc63ea1999e5b 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -318,7 +318,7 @@ macro_rules! run_driver { ($args:expr, $callback:expr $(, $with_tcx:ident)?) => {{ use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_middle::ty::TyCtxt; - use rustc_interface::{interface, Queries}; + use rustc_interface::interface; use stable_mir::CompilerError; use std::ops::ControlFlow; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 6fee049cdf073..ce44cb1c319aa 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -174,28 +174,28 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions compiling_test_count, .. } = interface::run_compiler(config, |compiler| { - compiler.enter(|queries| { - let collector = queries.global_ctxt().enter(|tcx| { - let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); - let opts = scrape_test_config(crate_name, crate_attrs, args_path); - let enable_per_target_ignores = options.enable_per_target_ignores; - - let mut collector = CreateRunnableDocTests::new(options, opts); - let hir_collector = HirCollector::new( - ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), - enable_per_target_ignores, - tcx, - ); - let tests = hir_collector.collect_crate(); - tests.into_iter().for_each(|t| collector.add_test(t)); - - collector - }); - compiler.sess.dcx().abort_if_errors(); + let krate = rustc_interface::passes::parse(&compiler.sess); + + let collector = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); + let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); + let opts = scrape_test_config(crate_name, crate_attrs, args_path); + let enable_per_target_ignores = options.enable_per_target_ignores; + + let mut collector = CreateRunnableDocTests::new(options, opts); + let hir_collector = HirCollector::new( + ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), + enable_per_target_ignores, + tcx, + ); + let tests = hir_collector.collect_crate(); + tests.into_iter().for_each(|t| collector.add_test(t)); collector - }) + }); + compiler.sess.dcx().abort_if_errors(); + + collector }); run_tests(opts, &rustdoc_options, &unused_extern_reports, standalone_tests, mergeable_tests); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5d82b8e309a6a..cf2bf38ac14a7 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -856,50 +856,41 @@ fn main_args( return; } - compiler.enter(|queries| { - let mut gcx = queries.global_ctxt(); - if sess.dcx().has_errors().is_some() { - sess.dcx().fatal("Compilation failed, aborting rustdoc"); + let krate = rustc_interface::passes::parse(sess); + if sess.dcx().has_errors().is_some() { + sess.dcx().fatal("Compilation failed, aborting rustdoc"); + } + + rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { + core::run_global_ctxt(tcx, show_coverage, render_options, output_format) + }); + info!("finished with rustc"); + + if let Some(options) = scrape_examples_options { + return scrape_examples::run(krate, render_opts, cache, tcx, options, bin_crate); } - gcx.enter(|tcx| { - let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { - core::run_global_ctxt(tcx, show_coverage, render_options, output_format) - }); - info!("finished with rustc"); - - if let Some(options) = scrape_examples_options { - return scrape_examples::run( - krate, - render_opts, - cache, - tcx, - options, - bin_crate, - ); - } - - cache.crate_version = crate_version; - - if show_coverage { - // if we ran coverage, bail early, we don't need to also generate docs at this point - // (also we didn't load in any of the useful passes) - return; - } else if run_check { - // Since we're in "check" mode, no need to generate anything beyond this point. - return; - } - - info!("going to format"); - match output_format { - config::OutputFormat::Html => sess.time("render_html", || { - run_renderer::>(krate, render_opts, cache, tcx) - }), - config::OutputFormat::Json => sess.time("render_json", || { - run_renderer::>(krate, render_opts, cache, tcx) - }), - } - }) + cache.crate_version = crate_version; + + if show_coverage { + // if we ran coverage, bail early, we don't need to also generate docs at this point + // (also we didn't load in any of the useful passes) + return; + } else if run_check { + // Since we're in "check" mode, no need to generate anything beyond this point. + return; + } + + info!("going to format"); + match output_format { + config::OutputFormat::Html => sess.time("render_html", || { + run_renderer::>(krate, render_opts, cache, tcx) + }), + config::OutputFormat::Json => sess.time("render_json", || { + run_renderer::>(krate, render_opts, cache, tcx) + }), + } }) }) } diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index d4c9fd019b0f7..bcc235e58ed33 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -77,11 +77,10 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path }; interface::run_compiler(config, |compiler| { - let linker = compiler.enter(|queries| { - queries.global_ctxt().enter(|tcx| { - let _ = tcx.analysis(()); - Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) - }) + let krate = rustc_interface::passes::parse(&compiler.sess); + let linker = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let _ = tcx.analysis(()); + Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) }); linker.link(&compiler.sess, &*compiler.codegen_backend); });