summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_interface/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_interface/src')
-rw-r--r--compiler/rustc_interface/src/callbacks.rs13
-rw-r--r--compiler/rustc_interface/src/errors.rs4
-rw-r--r--compiler/rustc_interface/src/interface.rs51
-rw-r--r--compiler/rustc_interface/src/lib.rs1
-rw-r--r--compiler/rustc_interface/src/passes.rs71
-rw-r--r--compiler/rustc_interface/src/queries.rs158
-rw-r--r--compiler/rustc_interface/src/tests.rs36
-rw-r--r--compiler/rustc_interface/src/util.rs41
8 files changed, 177 insertions, 198 deletions
diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs
index 76442de69..ee0552d77 100644
--- a/compiler/rustc_interface/src/callbacks.rs
+++ b/compiler/rustc_interface/src/callbacks.rs
@@ -10,6 +10,7 @@
//! origin crate when the `TyCtxt` is not present in TLS.
use rustc_errors::{Diagnostic, TRACK_DIAGNOSTICS};
+use rustc_middle::dep_graph::TaskDepsRef;
use rustc_middle::ty::tls;
use std::fmt;
@@ -26,14 +27,22 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
/// This is a callback from `rustc_ast` as it cannot access the implicit state
/// in `rustc_middle` otherwise. It is used when diagnostic messages are
/// emitted and stores them in the current query, if there is one.
-fn track_diagnostic(diagnostic: &Diagnostic) {
+fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
tls::with_context_opt(|icx| {
if let Some(icx) = icx {
if let Some(diagnostics) = icx.diagnostics {
let mut diagnostics = diagnostics.lock();
diagnostics.extend(Some(diagnostic.clone()));
+ std::mem::drop(diagnostics);
}
+
+ // Diagnostics are tracked, we can ignore the dependency.
+ let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() };
+ return tls::enter_context(&icx, move |_| (*f)(diagnostic));
}
+
+ // In any other case, invoke diagnostics anyway.
+ (*f)(diagnostic);
})
}
@@ -55,5 +64,5 @@ fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) ->
pub fn setup_callbacks() {
rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_)));
rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _));
- TRACK_DIAGNOSTICS.swap(&(track_diagnostic as fn(&_)));
+ TRACK_DIAGNOSTICS.swap(&(track_diagnostic as _));
}
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index f5135c78d..15d7e977b 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -87,3 +87,7 @@ pub struct FailedWritingFile<'a> {
pub path: &'a Path,
pub error: io::Error,
}
+
+#[derive(Diagnostic)]
+#[diag(interface_proc_macro_crate_panic_abort)]
+pub struct ProcMacroCratePanicAbort;
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 4c22ab68a..7a5e45ada 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,10 +14,10 @@ use rustc_middle::ty;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt;
use rustc_session::config::{self, CheckCfg, ErrorOutputType, Input, OutputFilenames};
-use rustc_session::early_error;
use rustc_session::lint;
use rustc_session::parse::{CrateConfig, ParseSess};
use rustc_session::Session;
+use rustc_session::{early_error, CompilerIO};
use rustc_span::source_map::{FileLoader, FileName};
use rustc_span::symbol::sym;
use std::path::PathBuf;
@@ -35,11 +35,6 @@ pub type Result<T> = result::Result<T, ErrorGuaranteed>;
pub struct Compiler {
pub(crate) sess: Lrc<Session>,
codegen_backend: Lrc<Box<dyn CodegenBackend>>,
- pub(crate) input: Input,
- pub(crate) input_path: Option<PathBuf>,
- pub(crate) output_dir: Option<PathBuf>,
- pub(crate) output_file: Option<PathBuf>,
- pub(crate) temps_dir: Option<PathBuf>,
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
pub(crate) override_queries:
Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
@@ -52,18 +47,6 @@ impl Compiler {
pub fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
&self.codegen_backend
}
- pub fn input(&self) -> &Input {
- &self.input
- }
- pub fn output_dir(&self) -> &Option<PathBuf> {
- &self.output_dir
- }
- pub fn output_file(&self) -> &Option<PathBuf> {
- &self.output_file
- }
- pub fn temps_dir(&self) -> &Option<PathBuf> {
- &self.temps_dir
- }
pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
&self.register_lints
}
@@ -72,14 +55,7 @@ impl Compiler {
sess: &Session,
attrs: &[ast::Attribute],
) -> OutputFilenames {
- util::build_output_filenames(
- &self.input,
- &self.output_dir,
- &self.output_file,
- &self.temps_dir,
- attrs,
- sess,
- )
+ util::build_output_filenames(attrs, sess)
}
}
@@ -90,8 +66,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
.into_iter()
.map(|s| {
let sess = ParseSess::with_silent_emitter(Some(format!(
- "this error occurred on the command line: `--cfg={}`",
- s
+ "this error occurred on the command line: `--cfg={s}`"
)));
let filename = FileName::cfg_spec_source_code(&s);
@@ -150,8 +125,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
'specs: for s in specs {
let sess = ParseSess::with_silent_emitter(Some(format!(
- "this error occurred on the command line: `--check-cfg={}`",
- s
+ "this error occurred on the command line: `--check-cfg={s}`"
)));
let filename = FileName::cfg_spec_source_code(&s);
@@ -246,7 +220,6 @@ pub struct Config {
pub crate_check_cfg: CheckCfg,
pub input: Input,
- pub input_path: Option<PathBuf>,
pub output_dir: Option<PathBuf>,
pub output_file: Option<PathBuf>,
pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
@@ -289,12 +262,19 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
crate::callbacks::setup_callbacks();
let registry = &config.registry;
+
+ let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let (mut sess, codegen_backend) = util::create_session(
config.opts,
config.crate_cfg,
config.crate_check_cfg,
config.file_loader,
- config.input_path.clone(),
+ CompilerIO {
+ input: config.input,
+ output_dir: config.output_dir,
+ output_file: config.output_file,
+ temps_dir,
+ },
config.lint_caps,
config.make_codegen_backend,
registry.clone(),
@@ -304,16 +284,9 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
parse_sess_created(&mut sess.parse_sess);
}
- let temps_dir = sess.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
-
let compiler = Compiler {
sess: Lrc::new(sess),
codegen_backend: Lrc::new(codegen_backend),
- input: config.input,
- input_path: config.input_path,
- output_dir: config.output_dir,
- output_file: config.output_file,
- temps_dir,
register_lints: config.register_lints,
override_queries: config.override_queries,
};
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 542b638bb..82bc4770b 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -3,6 +3,7 @@
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(once_cell)]
+#![feature(try_blocks)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index f808c1438..379a76528 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1,7 +1,8 @@
use crate::errors::{
CantEmitMIR, EmojiIdentifier, ErrorWritingDependencies, FerrisIdentifier,
GeneratedFileConflictsWithDirectory, InputFileWouldBeOverWritten, MixedBinCrate,
- MixedProcMacroCrate, OutDirError, ProcMacroDocWithoutArg, TempsDirError,
+ MixedProcMacroCrate, OutDirError, ProcMacroCratePanicAbort, ProcMacroDocWithoutArg,
+ TempsDirError,
};
use crate::interface::{Compiler, Result};
use crate::proc_macro_decls;
@@ -12,7 +13,6 @@ use rustc_ast::{self as ast, visit};
use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
-use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_errors::{ErrorGuaranteed, PResult};
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
@@ -30,12 +30,13 @@ use rustc_plugin_impl as plugin;
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
-use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn};
+use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn, Untracked};
use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::FileName;
+use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::traits;
use std::any::Any;
@@ -49,8 +50,8 @@ use std::rc::Rc;
use std::sync::LazyLock;
use std::{env, fs, iter};
-pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
- let krate = sess.time("parse_crate", || match input {
+pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
+ let krate = sess.time("parse_crate", || match &sess.io.input {
Input::File(file) => parse_crate_from_file(file, &sess.parse_sess),
Input::Str { input, name } => {
parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
@@ -380,6 +381,10 @@ pub fn configure_and_expand(
}
}
+ if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort {
+ sess.emit_warning(ProcMacroCratePanicAbort);
+ }
+
// For backwards compatibility, we don't try to run proc macro injection
// if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
// specified. This should only affect users who manually invoke 'rustdoc', as
@@ -553,7 +558,7 @@ fn write_out_deps(
}
let deps_filename = outputs.path(OutputType::DepInfo);
- let result = (|| -> io::Result<()> {
+ let result: io::Result<()> = try {
// Build a list of files used to compile the output and
// write Makefile-compatible dependency rules
let mut files: Vec<String> = sess
@@ -620,7 +625,7 @@ fn write_out_deps(
// prevents `make` from spitting out an error if a file is later
// deleted. For more info see #28735
for path in files {
- writeln!(file, "{}:", path)?;
+ writeln!(file, "{path}:")?;
}
// Emit special comments with information about accessed environment variables.
@@ -633,16 +638,14 @@ fn write_out_deps(
envs.sort_unstable();
writeln!(file)?;
for (k, v) in envs {
- write!(file, "# env-dep:{}", k)?;
+ write!(file, "# env-dep:{k}")?;
if let Some(v) = v {
- write!(file, "={}", v)?;
+ write!(file, "={v}")?;
}
writeln!(file)?;
}
}
-
- Ok(())
- })();
+ };
match result {
Ok(_) => {
@@ -660,7 +663,6 @@ fn write_out_deps(
pub fn prepare_outputs(
sess: &Session,
- compiler: &Compiler,
krate: &ast::Crate,
boxed_resolver: &RefCell<BoxedResolver>,
crate_name: Symbol,
@@ -668,20 +670,13 @@ pub fn prepare_outputs(
let _timer = sess.timer("prepare_outputs");
// FIXME: rustdoc passes &[] instead of &krate.attrs here
- let outputs = util::build_output_filenames(
- &compiler.input,
- &compiler.output_dir,
- &compiler.output_file,
- &compiler.temps_dir,
- &krate.attrs,
- sess,
- );
+ let outputs = util::build_output_filenames(&krate.attrs, sess);
let output_paths =
- generated_output_paths(sess, &outputs, compiler.output_file.is_some(), crate_name);
+ generated_output_paths(sess, &outputs, sess.io.output_file.is_some(), crate_name);
// Ensure the source file isn't accidentally overwritten during compilation.
- if let Some(ref input_path) = compiler.input_path {
+ if let Some(ref input_path) = sess.io.input.opt_path() {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path });
@@ -695,7 +690,7 @@ pub fn prepare_outputs(
}
}
- if let Some(ref dir) = compiler.temps_dir {
+ if let Some(ref dir) = sess.io.temps_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(TempsDirError);
return Err(reported);
@@ -708,7 +703,7 @@ pub fn prepare_outputs(
&& sess.opts.output_types.len() == 1;
if !only_dep_info {
- if let Some(ref dir) = compiler.output_dir {
+ if let Some(ref dir) = sess.io.output_dir {
if fs::create_dir_all(dir).is_err() {
let reported = sess.emit_err(OutDirError);
return Err(reported);
@@ -769,11 +764,8 @@ impl<'tcx> QueryContext<'tcx> {
pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>,
- krate: Lrc<ast::Crate>,
dep_graph: DepGraph,
- resolver: Rc<RefCell<BoxedResolver>>,
- outputs: OutputFilenames,
- crate_name: Symbol,
+ untracked: Untracked,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
@@ -784,8 +776,6 @@ pub fn create_global_ctxt<'tcx>(
// incr. comp. yet.
dep_graph.assert_ignored();
- let resolver_outputs = BoxedResolver::to_resolver_outputs(resolver);
-
let sess = &compiler.session();
let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
@@ -804,12 +794,6 @@ pub fn create_global_ctxt<'tcx>(
TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache)
});
- let ty::ResolverOutputs {
- definitions,
- global_ctxt: untracked_resolutions,
- ast_lowering: untracked_resolver_for_lowering,
- } = resolver_outputs;
-
let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(move || {
TyCtxt::create_global_ctxt(
@@ -817,25 +801,16 @@ pub fn create_global_ctxt<'tcx>(
lint_store,
arena,
hir_arena,
- definitions,
- untracked_resolutions,
- krate,
+ untracked,
dep_graph,
queries.on_disk_cache.as_ref().map(OnDiskCache::as_dyn),
queries.as_dyn(),
rustc_query_impl::query_callbacks(arena),
- crate_name,
- outputs,
)
})
});
- let mut qcx = QueryContext { gcx };
- qcx.enter(|tcx| {
- tcx.feed_unit_query()
- .resolver_for_lowering(tcx.arena.alloc(Steal::new(untracked_resolver_for_lowering)))
- });
- qcx
+ QueryContext { gcx }
}
/// Runs the resolution, type-checking, region checking and other
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 39e1f2204..d5a49dd75 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -5,6 +5,7 @@ use crate::passes::{self, BoxedResolver, QueryContext};
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
+use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_hir::def_id::LOCAL_CRATE;
@@ -12,50 +13,60 @@ use rustc_incremental::DepGraphFuture;
use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
-use rustc_middle::ty::{GlobalCtxt, TyCtxt};
+use rustc_middle::ty::{self, GlobalCtxt, TyCtxt};
use rustc_query_impl::Queries as TcxQueries;
use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_session::{output::find_crate_name, Session};
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use std::any::Any;
-use std::cell::{Ref, RefCell, RefMut};
+use std::cell::{RefCell, RefMut};
use std::rc::Rc;
use std::sync::Arc;
/// Represent the result of a query.
///
-/// This result can be stolen with the [`take`] method and generated with the [`compute`] method.
+/// This result can be stolen once with the [`steal`] method and generated with the [`compute`] method.
///
-/// [`take`]: Self::take
+/// [`steal`]: Steal::steal
/// [`compute`]: Self::compute
pub struct Query<T> {
- result: RefCell<Option<Result<T>>>,
+ /// `None` means no value has been computed yet.
+ result: RefCell<Option<Result<Steal<T>>>>,
}
impl<T> Query<T> {
- fn compute<F: FnOnce() -> Result<T>>(&self, f: F) -> Result<&Query<T>> {
- self.result.borrow_mut().get_or_insert_with(f).as_ref().map(|_| self).map_err(|&err| err)
+ fn compute<F: FnOnce() -> Result<T>>(&self, f: F) -> Result<QueryResult<'_, T>> {
+ RefMut::filter_map(
+ self.result.borrow_mut(),
+ |r: &mut Option<Result<Steal<T>>>| -> Option<&mut Steal<T>> {
+ r.get_or_insert_with(|| f().map(Steal::new)).as_mut().ok()
+ },
+ )
+ .map_err(|r| *r.as_ref().unwrap().as_ref().map(|_| ()).unwrap_err())
+ .map(QueryResult)
}
+}
+
+pub struct QueryResult<'a, T>(RefMut<'a, Steal<T>>);
+
+impl<'a, T> std::ops::Deref for QueryResult<'a, T> {
+ type Target = RefMut<'a, Steal<T>>;
- /// Takes ownership of the query result. Further attempts to take or peek the query
- /// result will panic unless it is generated by calling the `compute` method.
- pub fn take(&self) -> T {
- self.result.borrow_mut().take().expect("missing query result").unwrap()
+ fn deref(&self) -> &Self::Target {
+ &self.0
}
+}
- /// 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| {
- r.as_ref().unwrap().as_ref().expect("missing query result")
- })
+impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
}
+}
- /// Mutably borrows the query result using the RefCell. Panics if the result is stolen.
- pub fn peek_mut(&self) -> RefMut<'_, T> {
- RefMut::map(self.result.borrow_mut(), |r| {
- r.as_mut().unwrap().as_mut().expect("missing query result")
- })
+impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> {
+ pub fn enter<T>(mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
+ (*self.0).get_mut().enter(f)
}
}
@@ -79,7 +90,6 @@ pub struct Queries<'tcx> {
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
expansion: Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
- prepare_outputs: Query<OutputFilenames>,
global_ctxt: Query<QueryContext<'tcx>>,
ongoing_codegen: Query<Box<dyn Any>>,
}
@@ -98,7 +108,6 @@ impl<'tcx> Queries<'tcx> {
register_plugins: Default::default(),
expansion: Default::default(),
dep_graph: Default::default(),
- prepare_outputs: Default::default(),
global_ctxt: Default::default(),
ongoing_codegen: Default::default(),
}
@@ -111,24 +120,22 @@ impl<'tcx> Queries<'tcx> {
self.compiler.codegen_backend()
}
- fn dep_graph_future(&self) -> Result<&Query<Option<DepGraphFuture>>> {
+ fn dep_graph_future(&self) -> Result<QueryResult<'_, Option<DepGraphFuture>>> {
self.dep_graph_future.compute(|| {
let sess = self.session();
Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess)))
})
}
- pub fn parse(&self) -> Result<&Query<ast::Crate>> {
- self.parse.compute(|| {
- passes::parse(self.session(), &self.compiler.input)
- .map_err(|mut parse_error| parse_error.emit())
- })
+ pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
+ self.parse
+ .compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
}
- pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, Lrc<LintStore>)>> {
+ pub fn register_plugins(&self) -> Result<QueryResult<'_, (ast::Crate, Lrc<LintStore>)>> {
self.register_plugins.compute(|| {
- let crate_name = self.crate_name()?.peek().clone();
- let krate = self.parse()?.take();
+ let crate_name = *self.crate_name()?.borrow();
+ let krate = self.parse()?.steal();
let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {};
let (krate, lint_store) = passes::register_plugins(
@@ -150,24 +157,25 @@ impl<'tcx> Queries<'tcx> {
})
}
- pub fn crate_name(&self) -> Result<&Query<Symbol>> {
+ fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
self.crate_name.compute(|| {
Ok({
let parse_result = self.parse()?;
- let krate = parse_result.peek();
+ let krate = parse_result.borrow();
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
- find_crate_name(self.session(), &krate.attrs, &self.compiler.input)
+ find_crate_name(self.session(), &krate.attrs)
})
})
}
pub fn expansion(
&self,
- ) -> Result<&Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>> {
+ ) -> Result<QueryResult<'_, (Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>>
+ {
trace!("expansion");
self.expansion.compute(|| {
- let crate_name = *self.crate_name()?.peek();
- let (krate, lint_store) = self.register_plugins()?.take();
+ let crate_name = *self.crate_name()?.borrow();
+ let (krate, lint_store) = self.register_plugins()?.steal();
let _timer = self.session().timer("configure_and_expand");
let sess = self.session();
let mut resolver = passes::create_resolver(
@@ -183,10 +191,10 @@ impl<'tcx> Queries<'tcx> {
})
}
- fn dep_graph(&self) -> Result<&Query<DepGraph>> {
+ fn dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
self.dep_graph.compute(|| {
let sess = self.session();
- let future_opt = self.dep_graph_future()?.take();
+ let future_opt = self.dep_graph_future()?.steal();
let dep_graph = future_opt
.and_then(|future| {
let (prev_graph, prev_work_products) =
@@ -199,45 +207,48 @@ impl<'tcx> Queries<'tcx> {
})
}
- pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
- self.prepare_outputs.compute(|| {
- let (krate, boxed_resolver, _) = &*self.expansion()?.peek();
- let crate_name = *self.crate_name()?.peek();
- passes::prepare_outputs(
- self.session(),
- self.compiler,
- krate,
- &*boxed_resolver,
- crate_name,
- )
- })
- }
-
- pub fn global_ctxt(&'tcx self) -> Result<&Query<QueryContext<'tcx>>> {
+ pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, QueryContext<'tcx>>> {
self.global_ctxt.compute(|| {
- let crate_name = *self.crate_name()?.peek();
- let outputs = self.prepare_outputs()?.take();
- let dep_graph = self.dep_graph()?.peek().clone();
- let (krate, resolver, lint_store) = self.expansion()?.take();
- Ok(passes::create_global_ctxt(
+ let crate_name = *self.crate_name()?.borrow();
+ let (krate, resolver, lint_store) = self.expansion()?.steal();
+
+ let outputs = passes::prepare_outputs(self.session(), &krate, &resolver, crate_name)?;
+
+ let ty::ResolverOutputs {
+ untracked,
+ global_ctxt: untracked_resolutions,
+ ast_lowering: untracked_resolver_for_lowering,
+ } = BoxedResolver::to_resolver_outputs(resolver);
+
+ let mut qcx = passes::create_global_ctxt(
self.compiler,
lint_store,
- krate,
- dep_graph,
- resolver,
- outputs,
- crate_name,
+ self.dep_graph()?.steal(),
+ untracked,
&self.queries,
&self.gcx,
&self.arena,
&self.hir_arena,
- ))
+ );
+
+ qcx.enter(|tcx| {
+ let feed = tcx.feed_unit_query();
+ feed.resolver_for_lowering(
+ tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
+ );
+ feed.resolutions(tcx.arena.alloc(untracked_resolutions));
+ feed.output_filenames(tcx.arena.alloc(std::sync::Arc::new(outputs)));
+ feed.features_query(tcx.sess.features_untracked());
+ let feed = tcx.feed_local_crate();
+ feed.crate_name(crate_name);
+ });
+ Ok(qcx)
})
}
- pub fn ongoing_codegen(&'tcx self) -> Result<&Query<Box<dyn Any>>> {
+ pub fn ongoing_codegen(&'tcx self) -> Result<QueryResult<'_, Box<dyn Any>>> {
self.ongoing_codegen.compute(|| {
- self.global_ctxt()?.peek_mut().enter(|tcx| {
+ self.global_ctxt()?.enter(|tcx| {
tcx.analysis(()).ok();
// Don't do code generation if there were any errors
@@ -293,12 +304,10 @@ impl<'tcx> Queries<'tcx> {
let sess = self.session().clone();
let codegen_backend = self.codegen_backend().clone();
- let dep_graph = self.dep_graph()?.peek().clone();
- let (crate_hash, prepare_outputs) = self
- .global_ctxt()?
- .peek_mut()
- .enter(|tcx| (tcx.crate_hash(LOCAL_CRATE), tcx.output_filenames(()).clone()));
- let ongoing_codegen = self.ongoing_codegen()?.take();
+ let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
+ (tcx.crate_hash(LOCAL_CRATE), tcx.output_filenames(()).clone(), tcx.dep_graph.clone())
+ });
+ let ongoing_codegen = self.ongoing_codegen()?.steal();
Ok(Linker {
sess,
@@ -382,6 +391,7 @@ impl Compiler {
// NOTE: intentionally does not compute the global context if it hasn't been built yet,
// since that likely means there was a parse error.
if let Some(Ok(gcx)) = &mut *queries.global_ctxt.result.borrow_mut() {
+ let gcx = gcx.get_mut();
// We assume that no queries are run past here. If there are new queries
// after this point, they'll show up as "<unknown>" in self-profiling data.
{
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 2b8f6557c..f94bc4d4c 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -3,29 +3,31 @@ use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
-use rustc_session::config::InstrumentCoverage;
-use rustc_session::config::Strip;
+use rustc_session::config::rustc_optgroups;
+use rustc_session::config::Input;
+use rustc_session::config::TraitSolver;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{
- rustc_optgroups, ErrorOutputType, ExternLocation, LocationDetail, Options, Passes,
-};
-use rustc_session::config::{
BranchProtection, Externs, OomStrategy, OutputType, OutputTypes, PAuthKey, PacRet,
ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
+use rustc_session::config::{DumpMonoStatsFormat, MirSpanview};
+use rustc_session::config::{ErrorOutputType, ExternLocation, LocationDetail, Options, Strip};
+use rustc_session::config::{InstrumentCoverage, Passes};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
+use rustc_session::CompilerIO;
use rustc_session::{build_session, getopts, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
+use rustc_span::FileName;
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
-use std::iter::FromIterator;
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
@@ -40,7 +42,14 @@ fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options
fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
let registry = registry::Registry::new(&[]);
let (sessopts, cfg) = build_session_options_and_crate_config(matches);
- let sess = build_session(sessopts, None, None, registry, Default::default(), None, None);
+ let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
+ let io = CompilerIO {
+ input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
+ output_dir: None,
+ output_file: None,
+ temps_dir,
+ };
+ let sess = build_session(sessopts, io, None, registry, Default::default(), None, None);
(sess, cfg)
}
@@ -648,12 +657,14 @@ fn test_unstable_options_tracking_hash() {
untracked!(dump_mir_dir, String::from("abc"));
untracked!(dump_mir_exclude_pass_number, true);
untracked!(dump_mir_graphviz, true);
+ untracked!(dump_mir_spanview, Some(MirSpanview::Statement));
+ untracked!(dump_mono_stats, SwitchWithOptPath::Enabled(Some("mono-items-dir/".into())));
+ untracked!(dump_mono_stats_format, DumpMonoStatsFormat::Json);
untracked!(dylib_lto, true);
untracked!(emit_stack_sizes, true);
untracked!(future_incompat_test, true);
untracked!(hir_stats, true);
untracked!(identify_regions, true);
- untracked!(incremental_ignore_spans, true);
untracked!(incremental_info, true);
untracked!(incremental_verify_ich, true);
untracked!(input_stats, true);
@@ -714,7 +725,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(asm_comments, true);
tracked!(assume_incomplete_release, true);
tracked!(binary_dep_depinfo, true);
- tracked!(box_noalias, Some(false));
+ tracked!(box_noalias, false);
tracked!(
branch_protection,
Some(BranchProtection {
@@ -722,7 +733,6 @@ fn test_unstable_options_tracking_hash() {
pac_ret: Some(PacRet { leaf: true, key: PAuthKey::B })
})
);
- tracked!(chalk, true);
tracked!(codegen_backend, Some("abc".to_string()));
tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(debug_info_for_profiling, true);
@@ -738,6 +748,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(fuel, Some(("abc".to_string(), 99)));
tracked!(function_sections, Some(false));
tracked!(human_readable_cgu_names, true);
+ tracked!(incremental_ignore_spans, true);
tracked!(inline_in_all_cgus, Some(true));
tracked!(inline_mir, Some(true));
tracked!(inline_mir_hint_threshold, Some(123));
@@ -747,14 +758,16 @@ fn test_unstable_options_tracking_hash() {
tracked!(link_only, true);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
+ tracked!(log_backtrace, Some("filter".to_string()));
tracked!(maximal_hir_to_mir_coverage, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
tracked!(mir_opt_level, Some(4));
tracked!(move_size_limit, Some(4096));
- tracked!(mutable_noalias, Some(true));
+ tracked!(mutable_noalias, false);
tracked!(no_generate_arange_section, true);
+ tracked!(no_jump_tables, true);
tracked!(no_link, true);
tracked!(no_profiler_runtime, true);
tracked!(no_unique_section_names, true);
@@ -790,6 +803,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(thinlto, Some(true));
tracked!(thir_unsafeck, true);
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
+ tracked!(trait_solver, TraitSolver::Chalk);
tracked!(translate_remapped_path_to_local_path, false);
tracked!(trap_unreachable, Some(false));
tracked!(treat_err_as_bug, NonZeroUsize::new(1));
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 4142964a0..54363e07b 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -8,7 +8,7 @@ use rustc_parse::validate_attr;
use rustc_session as session;
use rustc_session::config::CheckCfg;
use rustc_session::config::{self, CrateType};
-use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
+use rustc_session::config::{ErrorOutputType, OutputFilenames};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
use rustc_session::parse::CrateConfig;
@@ -17,6 +17,7 @@ use rustc_span::edition::Edition;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::FileLoader;
use rustc_span::symbol::{sym, Symbol};
+use session::CompilerIO;
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::mem;
@@ -58,7 +59,7 @@ pub fn create_session(
cfg: FxHashSet<(String, Option<String>)>,
check_cfg: CheckCfg,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
- input_path: Option<PathBuf>,
+ io: CompilerIO,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
@@ -89,7 +90,7 @@ pub fn create_session(
let mut sess = session::build_session(
sopts,
- input_path,
+ io,
bundle,
descriptions,
lint_caps,
@@ -205,13 +206,13 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
fn load_backend_from_dylib(path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
- let err = format!("couldn't load codegen backend {:?}: {}", path, err);
+ let err = format!("couldn't load codegen backend {path:?}: {err}");
early_error(ErrorOutputType::default(), &err);
});
let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| {
- let err = format!("couldn't load codegen backend: {}", e);
+ let err = format!("couldn't load codegen backend: {e}");
early_error(ErrorOutputType::default(), &err);
});
@@ -304,8 +305,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
.join("\n* ");
let err = format!(
"failed to find a `codegen-backends` folder \
- in the sysroot candidates:\n* {}",
- candidates
+ in the sysroot candidates:\n* {candidates}"
);
early_error(ErrorOutputType::default(), &err);
});
@@ -325,7 +325,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
let expected_names = &[
format!("rustc_codegen_{}-{}", backend_name, env!("CFG_RELEASE")),
- format!("rustc_codegen_{}", backend_name),
+ format!("rustc_codegen_{backend_name}"),
];
for entry in d.filter_map(|e| e.ok()) {
let path = entry.path();
@@ -354,7 +354,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> M
match file {
Some(ref s) => load_backend_from_dylib(s),
None => {
- let err = format!("unsupported builtin codegen backend `{}`", backend_name);
+ let err = format!("unsupported builtin codegen backend `{backend_name}`");
early_error(ErrorOutputType::default(), &err);
}
}
@@ -389,7 +389,7 @@ pub(crate) fn check_attr_crate_type(
BuiltinLintDiagnostics::UnknownCrateTypes(
span,
"did you mean".to_string(),
- format!("\"{}\"", candidate),
+ format!("\"{candidate}\""),
),
);
} else {
@@ -487,20 +487,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
base
}
-pub fn build_output_filenames(
- input: &Input,
- odir: &Option<PathBuf>,
- ofile: &Option<PathBuf>,
- temps_dir: &Option<PathBuf>,
- attrs: &[ast::Attribute],
- sess: &Session,
-) -> OutputFilenames {
- match *ofile {
+pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> OutputFilenames {
+ match sess.io.output_file {
None => {
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
- let dirpath = (*odir).as_ref().cloned().unwrap_or_default();
+ let dirpath = sess.io.output_dir.clone().unwrap_or_default();
// If a crate name is present, we use it as the link name
let stem = sess
@@ -508,13 +501,13 @@ pub fn build_output_filenames(
.crate_name
.clone()
.or_else(|| rustc_attr::find_crate_name(sess, attrs).map(|n| n.to_string()))
- .unwrap_or_else(|| input.filestem().to_owned());
+ .unwrap_or_else(|| sess.io.input.filestem().to_owned());
OutputFilenames::new(
dirpath,
stem,
None,
- temps_dir.clone(),
+ sess.io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)
@@ -535,7 +528,7 @@ pub fn build_output_filenames(
}
Some(out_file.clone())
};
- if *odir != None {
+ if sess.io.output_dir != None {
sess.warn("ignoring --out-dir flag due to -o flag");
}
@@ -543,7 +536,7 @@ pub fn build_output_filenames(
out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(),
ofile,
- temps_dir.clone(),
+ sess.io.temps_dir.clone(),
sess.opts.cg.extra_filename.clone(),
sess.opts.output_types.clone(),
)