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/interface.rs318
-rw-r--r--compiler/rustc_interface/src/lib.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs73
-rw-r--r--compiler/rustc_interface/src/queries.rs168
-rw-r--r--compiler/rustc_interface/src/tests.rs104
-rw-r--r--compiler/rustc_interface/src/util.rs39
6 files changed, 308 insertions, 400 deletions
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index c4962707f..d58d60fc8 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -1,26 +1,24 @@
use crate::util;
use rustc_ast::token;
-use rustc_ast::{self as ast, LitKind, MetaItemKind};
+use rustc_ast::{LitKind, MetaItemKind};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::defer;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_errors::registry::Registry;
-use rustc_errors::{ErrorGuaranteed, Handler};
+use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_lint::LintStore;
+use rustc_middle::ty;
use rustc_middle::util::Providers;
-use rustc_middle::{bug, ty};
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::print_query_stack;
-use rustc_session::config::{
- self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames,
-};
+use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::parse::ParseSess;
-use rustc_session::{lint, CompilerIO, EarlyErrorHandler, Session};
+use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
use rustc_span::source_map::FileLoader;
use rustc_span::symbol::sym;
use rustc_span::FileName;
@@ -38,33 +36,13 @@ pub type Result<T> = result::Result<T, ErrorGuaranteed>;
/// Can be used to run `rustc_interface` queries.
/// Created by passing [`Config`] to [`run_compiler`].
pub struct Compiler {
- pub(crate) sess: Lrc<Session>,
- codegen_backend: Lrc<dyn CodegenBackend>,
- pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
+ pub sess: Session,
+ pub codegen_backend: Box<dyn CodegenBackend>,
pub(crate) override_queries: Option<fn(&Session, &mut Providers)>,
}
-impl Compiler {
- pub fn session(&self) -> &Lrc<Session> {
- &self.sess
- }
- pub fn codegen_backend(&self) -> &Lrc<dyn CodegenBackend> {
- &self.codegen_backend
- }
- pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
- &self.register_lints
- }
- pub fn build_output_filenames(
- &self,
- sess: &Session,
- attrs: &[ast::Attribute],
- ) -> OutputFilenames {
- util::build_output_filenames(attrs, sess)
- }
-}
-
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
-pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg {
+pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
cfgs.into_iter()
.map(|s| {
let sess = ParseSess::with_silent_emitter(Some(format!(
@@ -74,10 +52,13 @@ pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg {
macro_rules! error {
($reason: expr) => {
- handler.early_error(format!(
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ dcx.struct_fatal(format!(
concat!("invalid `--cfg` argument: `{}` (", $reason, ")"),
s
- ));
+ ))
+ .emit();
};
}
@@ -119,14 +100,13 @@ pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg {
}
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
-pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
+pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
// If any --check-cfg is passed then exhaustive_values and exhaustive_names
// are enabled by default.
let exhaustive_names = !specs.is_empty();
let exhaustive_values = !specs.is_empty();
let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() };
- let mut old_syntax = None;
for s in specs {
let sess = ParseSess::with_silent_emitter(Some(format!(
"this error occurred on the command line: `--check-cfg={s}`"
@@ -135,10 +115,13 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
macro_rules! error {
($reason:expr) => {
- handler.early_error(format!(
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ dcx.struct_fatal(format!(
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
s
))
+ .emit()
};
}
@@ -164,162 +147,101 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
expected_error();
};
- let mut set_old_syntax = || {
- // defaults are flipped for the old syntax
- if old_syntax == None {
- check_cfg.exhaustive_names = false;
- check_cfg.exhaustive_values = false;
- }
- old_syntax = Some(true);
- };
-
- if meta_item.has_name(sym::names) {
- set_old_syntax();
-
- check_cfg.exhaustive_names = true;
- for arg in args {
- if arg.is_word() && let Some(ident) = arg.ident() {
- check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any);
- } else {
- error!("`names()` arguments must be simple identifiers");
- }
- }
- } else if meta_item.has_name(sym::values) {
- set_old_syntax();
-
- if let Some((name, values)) = args.split_first() {
- if name.is_word() && let Some(ident) = name.ident() {
- let expected_values = check_cfg
- .expecteds
- .entry(ident.name)
- .and_modify(|expected_values| match expected_values {
- ExpectedValues::Some(_) => {}
- ExpectedValues::Any => {
- // handle the case where names(...) was done
- // before values by changing to a list
- *expected_values = ExpectedValues::Some(FxHashSet::default());
- }
- })
- .or_insert_with(|| ExpectedValues::Some(FxHashSet::default()));
+ if !meta_item.has_name(sym::cfg) {
+ expected_error();
+ }
- let ExpectedValues::Some(expected_values) = expected_values else {
- bug!("`expected_values` should be a list a values")
- };
+ let mut names = Vec::new();
+ let mut values: FxHashSet<_> = Default::default();
- for val in values {
- if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) {
- expected_values.insert(Some(*s));
- } else {
- error!("`values()` arguments must be string literals");
- }
- }
+ let mut any_specified = false;
+ let mut values_specified = false;
+ let mut values_any_specified = false;
- if values.is_empty() {
- expected_values.insert(None);
- }
- } else {
- error!("`values()` first argument must be a simple identifier");
+ for arg in args {
+ if arg.is_word()
+ && let Some(ident) = arg.ident()
+ {
+ if values_specified {
+ error!("`cfg()` names cannot be after values");
}
- } else if args.is_empty() {
- check_cfg.exhaustive_values = true;
- } else {
- expected_error();
- }
- } else if meta_item.has_name(sym::cfg) {
- old_syntax = Some(false);
-
- let mut names = Vec::new();
- let mut values: FxHashSet<_> = Default::default();
-
- let mut any_specified = false;
- let mut values_specified = false;
- let mut values_any_specified = false;
-
- for arg in args {
- if arg.is_word() && let Some(ident) = arg.ident() {
- if values_specified {
- error!("`cfg()` names cannot be after values");
- }
- names.push(ident);
- } else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
- if any_specified {
- error!("`any()` cannot be specified multiple times");
- }
- any_specified = true;
- if !args.is_empty() {
- error!("`any()` must be empty");
- }
- } else if arg.has_name(sym::values) && let Some(args) = arg.meta_item_list() {
- if names.is_empty() {
- error!("`values()` cannot be specified before the names");
- } else if values_specified {
- error!("`values()` cannot be specified multiple times");
- }
- values_specified = true;
-
- for arg in args {
- if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
- values.insert(Some(*s));
- } else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
- if values_any_specified {
- error!("`any()` in `values()` cannot be specified multiple times");
- }
- values_any_specified = true;
- if !args.is_empty() {
- error!("`any()` must be empty");
- }
- } else {
- error!("`values()` arguments must be string literals or `any()`");
+ names.push(ident);
+ } else if arg.has_name(sym::any)
+ && let Some(args) = arg.meta_item_list()
+ {
+ if any_specified {
+ error!("`any()` cannot be specified multiple times");
+ }
+ any_specified = true;
+ if !args.is_empty() {
+ error!("`any()` must be empty");
+ }
+ } else if arg.has_name(sym::values)
+ && let Some(args) = arg.meta_item_list()
+ {
+ if names.is_empty() {
+ error!("`values()` cannot be specified before the names");
+ } else if values_specified {
+ error!("`values()` cannot be specified multiple times");
+ }
+ values_specified = true;
+
+ for arg in args {
+ if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
+ values.insert(Some(*s));
+ } else if arg.has_name(sym::any)
+ && let Some(args) = arg.meta_item_list()
+ {
+ if values_any_specified {
+ error!("`any()` in `values()` cannot be specified multiple times");
}
+ values_any_specified = true;
+ if !args.is_empty() {
+ error!("`any()` must be empty");
+ }
+ } else {
+ error!("`values()` arguments must be string literals or `any()`");
}
- } else {
- error!(
- "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`"
- );
}
+ } else {
+ error!("`cfg()` arguments must be simple identifiers, `any()` or `values(...)`");
}
+ }
- if values.is_empty() && !values_any_specified && !any_specified {
- values.insert(None);
- } else if !values.is_empty() && values_any_specified {
- error!(
- "`values()` arguments cannot specify string literals and `any()` at the same time"
- );
- }
+ if values.is_empty() && !values_any_specified && !any_specified {
+ values.insert(None);
+ } else if !values.is_empty() && values_any_specified {
+ error!(
+ "`values()` arguments cannot specify string literals and `any()` at the same time"
+ );
+ }
- if any_specified {
- if names.is_empty()
- && values.is_empty()
- && !values_specified
- && !values_any_specified
- {
- check_cfg.exhaustive_names = false;
- } else {
- error!("`cfg(any())` can only be provided in isolation");
- }
+ if any_specified {
+ if names.is_empty() && values.is_empty() && !values_specified && !values_any_specified {
+ check_cfg.exhaustive_names = false;
} else {
- for name in names {
- check_cfg
- .expecteds
- .entry(name.name)
- .and_modify(|v| match v {
- ExpectedValues::Some(v) if !values_any_specified => {
- v.extend(values.clone())
- }
- ExpectedValues::Some(_) => *v = ExpectedValues::Any,
- ExpectedValues::Any => {}
- })
- .or_insert_with(|| {
- if values_any_specified {
- ExpectedValues::Any
- } else {
- ExpectedValues::Some(values.clone())
- }
- });
- }
+ error!("`cfg(any())` can only be provided in isolation");
}
} else {
- expected_error();
+ for name in names {
+ check_cfg
+ .expecteds
+ .entry(name.name)
+ .and_modify(|v| match v {
+ ExpectedValues::Some(v) if !values_any_specified => {
+ v.extend(values.clone())
+ }
+ ExpectedValues::Some(_) => *v = ExpectedValues::Any,
+ ExpectedValues::Any => {}
+ })
+ .or_insert_with(|| {
+ if values_any_specified {
+ ExpectedValues::Any
+ } else {
+ ExpectedValues::Some(values.clone())
+ }
+ });
+ }
}
}
@@ -392,19 +314,23 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
// Set parallel mode before thread pool creation, which will create `Lock`s.
rustc_data_structures::sync::set_dyn_thread_safe_mode(config.opts.unstable_opts.threads > 1);
+ // Check jobserver before run_in_thread_pool_with_globals, which call jobserver::acquire_thread
+ let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
+ early_dcx.initialize_checked_jobserver();
+
util::run_in_thread_pool_with_globals(
config.opts.edition,
config.opts.unstable_opts.threads,
|| {
crate::callbacks::setup_callbacks();
- let handler = EarlyErrorHandler::new(config.opts.error_format);
+ let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
let codegen_backend = if let Some(make_codegen_backend) = config.make_codegen_backend {
make_codegen_backend(&config.opts)
} else {
util::get_codegen_backend(
- &handler,
+ &early_dcx,
&config.opts.maybe_sysroot,
config.opts.unstable_opts.codegen_backend.as_deref(),
)
@@ -421,7 +347,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
) {
Ok(bundle) => bundle,
Err(e) => {
- handler.early_error(format!("failed to load fluent bundle: {e}"));
+ early_dcx.early_error(format!("failed to load fluent bundle: {e}"));
}
};
@@ -432,7 +358,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
let target_override = codegen_backend.target_override(&config.opts);
let mut sess = rustc_session::build_session(
- &handler,
+ early_dcx,
config.opts,
CompilerIO {
input: config.input,
@@ -454,12 +380,12 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
codegen_backend.init(&sess);
- let cfg = parse_cfg(&handler, config.crate_cfg);
+ let cfg = parse_cfg(&sess.dcx(), config.crate_cfg);
let mut cfg = config::build_configuration(&sess, cfg);
util::add_configuration(&mut cfg, &mut sess, &*codegen_backend);
sess.parse_sess.config = cfg;
- let mut check_cfg = parse_check_cfg(&handler, config.crate_check_cfg);
+ let mut check_cfg = parse_check_cfg(&sess.dcx(), config.crate_check_cfg);
check_cfg.fill_well_known(&sess.target);
sess.parse_sess.check_config = check_cfg;
@@ -473,12 +399,18 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
sess.opts.untracked_state_hash = hasher.finish()
}
- let compiler = Compiler {
- sess: Lrc::new(sess),
- codegen_backend: Lrc::from(codegen_backend),
- register_lints: config.register_lints,
- override_queries: config.override_queries,
- };
+ // Even though the session holds the lint store, we can't build the
+ // lint store until after the session exists. And we wait until now
+ // so that `register_lints` sees the fully initialized session.
+ let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
+ if let Some(register_lints) = config.register_lints.as_deref() {
+ register_lints(&sess, &mut lint_store);
+ sess.registered_lints = true;
+ }
+ sess.lint_store = Some(Lrc::new(lint_store));
+
+ let compiler =
+ Compiler { sess, codegen_backend, override_queries: config.override_queries };
rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
let r = {
@@ -499,21 +431,21 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
}
pub fn try_print_query_stack(
- handler: &Handler,
+ dcx: &DiagCtxt,
num_frames: Option<usize>,
file: Option<std::fs::File>,
) {
eprintln!("query stack during panic:");
// Be careful relying on global state here: this code is called from
- // a panic hook, which means that the global `Handler` may be in a weird
+ // a panic hook, which means that the global `DiagCtxt` may be in a weird
// state if it was responsible for triggering the panic.
let i = ty::tls::with_context_opt(|icx| {
if let Some(icx) = icx {
ty::print::with_no_queries!(print_query_stack(
QueryCtxt::new(icx.tcx),
icx.query,
- handler,
+ dcx,
num_frames,
file,
))
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index ffa2667a3..cfa464478 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -6,16 +6,12 @@
#![feature(let_chains)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_fluent_macro::fluent_messages;
-
mod callbacks;
mod errors;
pub mod interface;
@@ -32,4 +28,4 @@ pub use queries::Queries;
#[cfg(test)]
mod tests;
-fluent_messages! { "../messages.ftl" }
+rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7d14d088e..21beb90d7 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
use rustc_middle::util::Providers;
use rustc_mir_build as mir_build;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
-use rustc_passes::{self, abi_test, hir_stats, layout_test};
+use rustc_passes::{abi_test, hir_stats, layout_test};
use rustc_resolve::Resolver;
use rustc_session::code_stats::VTableSizeInfo;
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
@@ -39,7 +39,7 @@ use std::any::Any;
use std::ffi::OsString;
use std::io::{self, BufWriter, Write};
use std::path::{Path, PathBuf};
-use std::sync::{Arc, LazyLock};
+use std::sync::LazyLock;
use std::{env, fs, iter};
pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
@@ -56,7 +56,7 @@ pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
}
if let Some(ref s) = sess.opts.unstable_opts.show_span {
- rustc_ast_passes::show_span::run(sess.diagnostic(), s, &krate);
+ rustc_ast_passes::show_span::run(sess.dcx(), s, &krate);
}
if sess.opts.unstable_opts.hir_stats {
@@ -72,17 +72,6 @@ fn count_nodes(krate: &ast::Crate) -> usize {
counter.count
}
-pub(crate) fn create_lint_store(
- sess: &Session,
- register_lints: Option<impl Fn(&Session, &mut LintStore)>,
-) -> LintStore {
- let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
- if let Some(register_lints) = register_lints {
- register_lints(sess, &mut lint_store);
- }
- lint_store
-}
-
fn pre_expansion_lint<'a>(
sess: &Session,
features: &Features,
@@ -125,7 +114,7 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
}
}
-/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
+/// Runs the "early phases" of the compiler: initial `cfg` processing,
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
/// harness if one is to be provided, injection of a dependency on the
/// standard library and prelude, and name resolution.
@@ -138,7 +127,7 @@ fn configure_and_expand(
let tcx = resolver.tcx();
let sess = tcx.sess;
let features = tcx.features();
- let lint_store = unerased_lint_store(tcx);
+ let lint_store = unerased_lint_store(tcx.sess);
let crate_name = tcx.crate_name(LOCAL_CRATE);
let lint_check_node = (&krate, pre_configured_attrs);
pre_expansion_lint(
@@ -161,7 +150,7 @@ fn configure_and_expand(
)
});
- util::check_attr_crate_type(sess, pre_configured_attrs, &mut resolver.lint_buffer());
+ util::check_attr_crate_type(sess, pre_configured_attrs, resolver.lint_buffer());
// Expand all macros
krate = sess.time("macro_expand_crate", || {
@@ -278,7 +267,7 @@ fn configure_and_expand(
is_proc_macro_crate,
has_proc_macro_decls,
is_test_crate,
- sess.diagnostic(),
+ sess.dcx(),
)
});
@@ -295,16 +284,16 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
let mut lint_buffer = resolver.lint_buffer.steal();
if sess.opts.unstable_opts.input_stats {
- eprintln!("Post-expansion node count: {}", count_nodes(&krate));
+ eprintln!("Post-expansion node count: {}", count_nodes(krate));
}
if sess.opts.unstable_opts.hir_stats {
- hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS", "ast-stats-2");
+ hir_stats::print_ast_stats(krate, "POST EXPANSION AST STATS", "ast-stats-2");
}
// Needs to go *after* expansion to be able to check the results of macro expansion.
sess.time("complete_gated_feature_checking", || {
- rustc_ast_passes::feature_gate::check_crate(&krate, sess, tcx.features());
+ rustc_ast_passes::feature_gate::check_crate(krate, sess, tcx.features());
});
// Add all buffered lints from the `ParseSess` to the `Session`.
@@ -317,6 +306,8 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
// Gate identifiers containing invalid Unicode codepoints that were recovered during lexing.
sess.parse_sess.bad_unicode_identifiers.with_lock(|identifiers| {
+ // We will soon sort, so the initial order does not matter.
+ #[allow(rustc::potential_query_instability)]
let mut identifiers: Vec<_> = identifiers.drain().collect();
identifiers.sort_by_key(|&(key, _)| key);
for (ident, mut spans) in identifiers.into_iter() {
@@ -330,7 +321,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
}
});
- let lint_store = unerased_lint_store(tcx);
+ let lint_store = unerased_lint_store(tcx.sess);
rustc_lint::check_ast_node(
sess,
tcx.features(),
@@ -442,6 +433,9 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
escape_dep_filename(&file.prefer_local().to_string())
};
+ // The entries will be used to declare dependencies beween files in a
+ // Makefile-like output, so the iteration order does not matter.
+ #[allow(rustc::potential_query_instability)]
let extra_tracked_files =
file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str())));
files.extend(extra_tracked_files);
@@ -497,6 +491,8 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
// Emit special comments with information about accessed environment variables.
let env_depinfo = sess.parse_sess.env_depinfo.borrow();
if !env_depinfo.is_empty() {
+ // We will soon sort, so the initial order does not matter.
+ #[allow(rustc::potential_query_instability)]
let mut envs: Vec<_> = env_depinfo
.iter()
.map(|(k, v)| (escape_dep_env(*k), v.map(escape_dep_env)))
@@ -530,13 +526,11 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
match result {
Ok(_) => {
if sess.opts.json_artifact_notifications {
- sess.parse_sess
- .span_diagnostic
- .emit_artifact_notification(&deps_filename, "dep-info");
+ sess.dcx().emit_artifact_notification(deps_filename, "dep-info");
}
}
Err(error) => {
- sess.emit_fatal(errors::ErrorWritingDependencies { path: &deps_filename, error });
+ sess.emit_fatal(errors::ErrorWritingDependencies { path: deps_filename, error });
}
}
}
@@ -564,23 +558,27 @@ fn resolver_for_lowering<'tcx>(
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate))))
}
-fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
+pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) {
+ // Make sure name resolution and macro expansion is run for
+ // the side-effect of providing a complete set of all
+ // accessed files and env vars.
+ let _ = tcx.resolver_for_lowering(());
+
let sess = tcx.sess;
- let _timer = sess.timer("prepare_outputs");
- let (_, krate) = &*tcx.resolver_for_lowering(()).borrow();
+ let _timer = sess.timer("write_dep_info");
let crate_name = tcx.crate_name(LOCAL_CRATE);
- let outputs = util::build_output_filenames(&krate.attrs, sess);
+ let outputs = tcx.output_filenames(());
let output_paths =
generated_output_paths(tcx, &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) = sess.io.input.opt_path() {
+ if let Some(input_path) = sess.io.input.opt_path() {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
sess.emit_fatal(errors::InputFileWouldBeOverWritten { path: input_path });
}
- if let Some(ref dir_path) = output_conflicts_with_dir(&output_paths) {
+ if let Some(dir_path) = output_conflicts_with_dir(&output_paths) {
sess.emit_fatal(errors::GeneratedFileConflictsWithDirectory {
input_path,
dir_path,
@@ -607,15 +605,12 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
}
}
}
-
- outputs.into()
}
pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
let providers = &mut Providers::default();
providers.analysis = analysis;
providers.hir_crate = rustc_ast_lowering::lower_to_hir;
- providers.output_filenames = output_filenames;
providers.resolver_for_lowering = resolver_for_lowering;
providers.early_lint_checks = early_lint_checks;
proc_macro_decls::provide(providers);
@@ -645,7 +640,6 @@ pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
crate_types: Vec<CrateType>,
stable_crate_id: StableCrateId,
- lint_store: Lrc<LintStore>,
dep_graph: DepGraph,
untracked: Untracked,
gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
@@ -657,10 +651,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);
@@ -676,7 +670,6 @@ pub fn create_global_ctxt<'tcx>(
sess,
crate_types,
stable_crate_id,
- lint_store,
arena,
hir_arena,
untracked,
@@ -769,7 +762,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
});
tcx.hir().par_body_owners(|def_id| {
- if let rustc_hir::def::DefKind::Coroutine = tcx.def_kind(def_id) {
+ if tcx.is_coroutine(def_id.to_def_id()) {
tcx.ensure().mir_coroutine_witnesses(def_id);
tcx.ensure().check_coroutine_obligations(def_id);
}
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 3a5f788e8..8a553b95e 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,13 +1,14 @@
use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
use crate::interface::{Compiler, Result};
-use crate::{passes, util};
+use crate::{errors, passes, util};
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::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
+use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal};
+use rustc_hir::def::DefKind;
use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_incremental::setup_dep_graph;
@@ -15,9 +16,11 @@ use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::{GlobalCtxt, TyCtxt};
+use rustc_serialize::opaque::FileEncodeResult;
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};
@@ -83,7 +86,6 @@ pub struct Queries<'tcx> {
hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
parse: Query<ast::Crate>,
- pre_configure: Query<(ast::Crate, ast::AttrVec)>,
// This just points to what's in `gcx_cell`.
gcx: Query<&'tcx GlobalCtxt<'tcx>>,
}
@@ -96,29 +98,26 @@ impl<'tcx> Queries<'tcx> {
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
parse: Default::default(),
- pre_configure: Default::default(),
gcx: Default::default(),
}
}
- fn session(&self) -> &Lrc<Session> {
- &self.compiler.sess
- }
- fn codegen_backend(&self) -> &Lrc<dyn CodegenBackend> {
- self.compiler.codegen_backend()
+ pub fn finish(&self) -> FileEncodeResult {
+ if let Some(gcx) = self.gcx_cell.get() { gcx.finish() } else { Ok(0) }
}
pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
- 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."]
- pub fn pre_configure(&self) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec)>> {
- self.pre_configure.compute(|| {
+ pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
+ self.gcx.compute(|| {
+ let sess = &self.compiler.sess;
+
let mut krate = self.parse()?.steal();
- let sess = self.session();
rustc_builtin_macros::cmdline_attrs::inject(
&mut krate,
&sess.parse_sess,
@@ -127,15 +126,6 @@ impl<'tcx> Queries<'tcx> {
let pre_configured_attrs =
rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
- Ok((krate, pre_configured_attrs))
- })
- }
-
- pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
- self.gcx.compute(|| {
- let sess = self.session();
- #[allow(deprecated)]
- let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
let crate_name = find_crate_name(sess, &pre_configured_attrs);
@@ -146,12 +136,11 @@ impl<'tcx> Queries<'tcx> {
sess.opts.cg.metadata.clone(),
sess.cfg_version,
);
+ let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
- let lint_store =
- Lrc::new(passes::create_lint_store(sess, self.compiler.register_lints.as_deref()));
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));
@@ -164,7 +153,6 @@ impl<'tcx> Queries<'tcx> {
self.compiler,
crate_types,
stable_crate_id,
- lint_store,
dep_graph,
untracked,
&self.gcx_cell,
@@ -183,25 +171,20 @@ impl<'tcx> Queries<'tcx> {
crate_name,
)));
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
+ feed.output_filenames(Arc::new(outputs));
+
+ let feed = tcx.feed_local_def_id(CRATE_DEF_ID);
+ feed.def_kind(DefKind::Mod);
});
Ok(qcx)
})
}
- pub fn ongoing_codegen(&'tcx self) -> Result<Box<dyn Any>> {
+ pub fn write_dep_info(&'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))
- })
+ passes::write_dep_info(tcx);
+ });
+ Ok(())
}
/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
@@ -211,16 +194,16 @@ impl<'tcx> Queries<'tcx> {
let Some((def_id, _)) = tcx.entry_fn(()) else { return };
for attr in tcx.get_attrs(def_id, sym::rustc_error) {
match attr.meta_item_list() {
- // Check if there is a `#[rustc_error(delay_span_bug_from_inside_query)]`.
+ // Check if there is a `#[rustc_error(span_delayed_bug_from_inside_query)]`.
Some(list)
if list.iter().any(|list_item| {
matches!(
list_item.ident().map(|i| i.name),
- Some(sym::delay_span_bug_from_inside_query)
+ Some(sym::span_delayed_bug_from_inside_query)
)
}) =>
{
- tcx.ensure().trigger_delay_span_bug(def_id);
+ tcx.ensure().trigger_span_delayed_bug(def_id);
}
// Bare `#[rustc_error]`.
@@ -238,68 +221,61 @@ impl<'tcx> Queries<'tcx> {
}
}
- pub fn linker(&'tcx self, ongoing_codegen: Box<dyn Any>) -> Result<Linker> {
- let sess = self.session().clone();
- let codegen_backend = self.codegen_backend().clone();
+ pub fn codegen_and_build_linker(&'tcx self) -> Result<Linker> {
+ self.global_ctxt()?.enter(|tcx| {
+ // Don't do code generation if there were any errors
+ self.compiler.sess.compile_status()?;
- let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
- (
- if tcx.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None },
- tcx.output_filenames(()).clone(),
- tcx.dep_graph.clone(),
- )
- });
+ // 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.dcx().flush_delayed();
- Ok(Linker {
- sess,
- codegen_backend,
+ // Hook for UI tests.
+ Self::check_for_rustc_errors_attr(tcx);
- dep_graph,
- prepare_outputs,
- crate_hash,
- ongoing_codegen,
+ 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(),
+ crate_hash: if tcx.needs_crate_hash() {
+ Some(tcx.crate_hash(LOCAL_CRATE))
+ } else {
+ None
+ },
+ ongoing_codegen,
+ })
})
}
}
pub struct Linker {
- // compilation inputs
- sess: Lrc<Session>,
- codegen_backend: Lrc<dyn CodegenBackend>,
-
- // compilation outputs
dep_graph: DepGraph,
- prepare_outputs: Arc<OutputFilenames>,
+ output_filenames: Arc<OutputFilenames>,
// Only present when incr. comp. is enabled.
crate_hash: Option<Svh>,
ongoing_codegen: Box<dyn Any>,
}
impl Linker {
- pub fn link(self) -> Result<()> {
- let (codegen_results, work_products) = self.codegen_backend.join_codegen(
- self.ongoing_codegen,
- &self.sess,
- &self.prepare_outputs,
- )?;
+ pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) -> Result<()> {
+ let (codegen_results, work_products) =
+ codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames)?;
- self.sess.compile_status()?;
+ sess.compile_status()?;
- let sess = &self.sess;
- let dep_graph = self.dep_graph;
sess.time("serialize_work_products", || {
- rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)
+ rustc_incremental::save_work_product_index(sess, &self.dep_graph, work_products)
});
- let prof = self.sess.prof.clone();
- prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
+ let prof = sess.prof.clone();
+ prof.generic_activity("drop_dep_graph").run(move || drop(self.dep_graph));
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
- rustc_incremental::finalize_session_directory(&self.sess, self.crate_hash);
+ rustc_incremental::finalize_session_directory(sess, self.crate_hash);
- if !self
- .sess
+ if !sess
.opts
.output_types
.keys()
@@ -309,14 +285,19 @@ impl Linker {
}
if sess.opts.unstable_opts.no_link {
- let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
- CodegenResults::serialize_rlink(sess, &rlink_file, &codegen_results)
- .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
+ let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT);
+ CodegenResults::serialize_rlink(
+ sess,
+ &rlink_file,
+ &codegen_results,
+ &*self.output_filenames,
+ )
+ .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
return Ok(());
}
let _timer = sess.prof.verbose_generic_activity("link_crate");
- self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs)
+ codegen_backend.link(sess, codegen_results, &self.output_filenames)
}
}
@@ -325,6 +306,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);
@@ -337,15 +319,19 @@ impl Compiler {
// after this point, they'll show up as "<unknown>" 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"));
+ if let Err((path, error)) = queries.finish() {
+ self.sess.emit_err(errors::FailedWritingFile { path: &path, error });
+ }
ret
}
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index d30816955..04a7714d4 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -5,15 +5,15 @@ use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::{
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
- InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained,
- LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options, OutFileName,
- OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip,
- SwitchWithOptPath, SymbolManglingVersion, TraitSolver, WasiExecModel,
+ FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
+ LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, NextSolverConfig,
+ OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius,
+ ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
-use rustc_session::{build_session, getopts, CompilerIO, EarlyErrorHandler, Session};
+use rustc_session::{build_session, getopts, CompilerIO, EarlyDiagCtxt, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::{FileName, SourceFileHashAlgorithm};
@@ -24,10 +24,12 @@ use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
use std::sync::Arc;
-fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, Cfg) {
+fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {
+ let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
+ early_dcx.initialize_checked_jobserver();
+
let registry = registry::Registry::new(&[]);
- let sessopts = build_session_options(handler, &matches);
- let cfg = parse_cfg(handler, matches.opt_strs("cfg"));
+ let sessopts = build_session_options(&mut early_dcx, &matches);
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() },
@@ -36,7 +38,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
temps_dir,
};
let sess = build_session(
- handler,
+ early_dcx,
sessopts,
io,
None,
@@ -50,6 +52,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
Arc::default(),
Default::default(),
);
+ let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg"));
(sess, cfg)
}
@@ -116,8 +119,7 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) {
fn test_switch_implies_cfg_test() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
- let (sess, cfg) = mk_session(&mut handler, matches);
+ let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, cfg);
assert!(cfg.contains(&(sym::test, None)));
});
@@ -128,8 +130,7 @@ fn test_switch_implies_cfg_test() {
fn test_switch_implies_cfg_test_unless_cfg_test() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
- let (sess, cfg) = mk_session(&mut handler, matches);
+ let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, cfg);
let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
assert!(test_items.next().is_some());
@@ -141,24 +142,21 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
fn test_can_print_warnings() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
- let (sess, _) = mk_session(&mut handler, matches);
- assert!(!sess.diagnostic().can_emit_warnings());
+ let (sess, _) = mk_session(matches);
+ assert!(!sess.dcx().can_emit_warnings());
});
rustc_span::create_default_session_globals_then(|| {
let matches =
optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
- let (sess, _) = mk_session(&mut handler, matches);
- assert!(sess.diagnostic().can_emit_warnings());
+ let (sess, _) = mk_session(matches);
+ assert!(sess.dcx().can_emit_warnings());
});
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
- let (sess, _) = mk_session(&mut handler, matches);
- assert!(sess.diagnostic().can_emit_warnings());
+ let (sess, _) = mk_session(matches);
+ assert!(sess.dcx().can_emit_warnings());
});
}
@@ -303,36 +301,36 @@ fn test_search_paths_tracking_hash_different_order() {
let mut v3 = Options::default();
let mut v4 = Options::default();
- let handler = EarlyErrorHandler::new(JSON);
+ let early_dcx = EarlyDiagCtxt::new(JSON);
const JSON: ErrorOutputType = ErrorOutputType::Json {
pretty: false,
json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
};
// Reference
- v1.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
- v1.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
- v1.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
- v1.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
- v1.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
-
- v2.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
- v2.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
- v2.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
- v2.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
- v2.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
-
- v3.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
- v3.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
- v3.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
- v3.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
- v3.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
-
- v4.search_paths.push(SearchPath::from_cli_opt(&handler, "all=mno"));
- v4.search_paths.push(SearchPath::from_cli_opt(&handler, "native=abc"));
- v4.search_paths.push(SearchPath::from_cli_opt(&handler, "crate=def"));
- v4.search_paths.push(SearchPath::from_cli_opt(&handler, "dependency=ghi"));
- v4.search_paths.push(SearchPath::from_cli_opt(&handler, "framework=jkl"));
+ v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc"));
+ v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def"));
+ v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi"));
+ v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl"));
+ v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno"));
+
+ v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc"));
+ v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi"));
+ v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def"));
+ v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl"));
+ v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno"));
+
+ v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def"));
+ v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl"));
+ v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc"));
+ v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi"));
+ v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno"));
+
+ v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno"));
+ v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc"));
+ v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def"));
+ v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi"));
+ v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl"));
assert_same_hash(&v1, &v2);
assert_same_hash(&v1, &v3);
@@ -679,7 +677,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(incremental_info, true);
untracked!(incremental_verify_ich, true);
untracked!(input_stats, true);
- untracked!(keep_hygiene_data, true);
untracked!(link_native_libraries, false);
untracked!(llvm_time_trace, true);
untracked!(ls, vec!["all".to_owned()]);
@@ -691,7 +688,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(no_leak_check, true);
untracked!(no_parallel_llvm, true);
untracked!(parse_only, true);
- untracked!(perf_stats, true);
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
untracked!(print_codegen_stats, true);
@@ -751,6 +747,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true);
tracked!(debug_macros, true);
+ tracked!(default_hidden_visibility, Some(true));
tracked!(dep_info_omit_d_target, true);
tracked!(dual_proc_macros, true);
tracked!(dwarf_version, Some(5));
@@ -760,6 +757,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(flatten_format_args, false);
tracked!(force_unstable_if_unmarked, true);
tracked!(fuel, Some(("abc".to_string(), 99)));
+ tracked!(function_return, FunctionReturn::ThunkExtern);
tracked!(function_sections, Some(false));
tracked!(human_readable_cgu_names, true);
tracked!(incremental_ignore_spans, true);
@@ -771,6 +769,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(instrument_xray, Some(InstrumentXRay::default()));
tracked!(link_directives, false);
tracked!(link_only, true);
+ tracked!(llvm_module_flag, vec![("bar".to_string(), 123, "max".to_string())]);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
tracked!(maximal_hir_to_mir_coverage, true);
@@ -781,6 +780,10 @@ fn test_unstable_options_tracking_hash() {
tracked!(mir_opt_level, Some(4));
tracked!(move_size_limit, Some(4096));
tracked!(mutable_noalias, false);
+ tracked!(
+ next_solver,
+ Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() })
+ );
tracked!(no_generate_arange_section, true);
tracked!(no_jump_tables, true);
tracked!(no_link, true);
@@ -822,7 +825,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(thir_unsafeck, true);
tracked!(tiny_const_eval_limit, true);
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
- tracked!(trait_solver, TraitSolver::NextCoherence);
tracked!(translate_remapped_path_to_local_path, false);
tracked!(trap_unreachable, Some(false));
tracked!(treat_err_as_bug, NonZeroUsize::new(1));
@@ -852,9 +854,9 @@ fn test_edition_parsing() {
let options = Options::default();
assert!(options.edition == DEFAULT_EDITION);
- let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
+ let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
- let sessopts = build_session_options(&mut handler, &matches);
+ let sessopts = build_session_options(&mut early_dcx, &matches);
assert!(sessopts.edition == Edition::Edition2018)
}
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 22d127934..bffa74321 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -14,7 +14,7 @@ use rustc_session::{filesearch, output, Session};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::symbol::{sym, Symbol};
-use session::EarlyErrorHandler;
+use session::EarlyDiagCtxt;
use std::env;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::mem;
@@ -107,7 +107,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::{deadlock, QueryContext};
- let registry = sync::Registry::new(threads);
+ let registry = sync::Registry::new(std::num::NonZeroUsize::new(threads).unwrap());
if !sync::is_dyn_thread_safe() {
return run_in_thread_with_globals(edition, || {
@@ -126,11 +126,8 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
.deadlock_handler(|| {
// On deadlock, creates a new thread and forwards information in thread
// locals to it. The new thread runs the deadlock handler.
- let query_map = FromDyn::from(tls::with(|tcx| {
- QueryCtxt::new(tcx)
- .try_collect_active_jobs()
- .expect("active jobs shouldn't be locked in deadlock handler")
- }));
+ let query_map =
+ FromDyn::from(tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs()));
let registry = rayon_core::Registry::current();
thread::spawn(move || deadlock(query_map.into_inner(), &registry));
});
@@ -164,16 +161,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
})
}
-fn load_backend_from_dylib(handler: &EarlyErrorHandler, path: &Path) -> MakeBackendFn {
+fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {path:?}: {err}");
- handler.early_error(err);
+ early_dcx.early_error(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}");
- handler.early_error(err);
+ early_dcx.early_error(err);
});
// Intentionally leak the dynamic library. We can't ever unload it
@@ -188,7 +185,7 @@ fn load_backend_from_dylib(handler: &EarlyErrorHandler, path: &Path) -> MakeBack
///
/// A name of `None` indicates that the default backend should be used.
pub fn get_codegen_backend(
- handler: &EarlyErrorHandler,
+ early_dcx: &EarlyDiagCtxt,
maybe_sysroot: &Option<PathBuf>,
backend_name: Option<&str>,
) -> Box<dyn CodegenBackend> {
@@ -199,11 +196,11 @@ pub fn get_codegen_backend(
match backend_name.unwrap_or(default_codegen_backend) {
filename if filename.contains('.') => {
- load_backend_from_dylib(handler, filename.as_ref())
+ load_backend_from_dylib(early_dcx, filename.as_ref())
}
#[cfg(feature = "llvm")]
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
- backend_name => get_codegen_sysroot(handler, maybe_sysroot, backend_name),
+ backend_name => get_codegen_sysroot(early_dcx, maybe_sysroot, backend_name),
}
});
@@ -236,7 +233,7 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
}
fn get_codegen_sysroot(
- handler: &EarlyErrorHandler,
+ early_dcx: &EarlyDiagCtxt,
maybe_sysroot: &Option<PathBuf>,
backend_name: &str,
) -> MakeBackendFn {
@@ -274,7 +271,7 @@ fn get_codegen_sysroot(
"failed to find a `codegen-backends` folder \
in the sysroot candidates:\n* {candidates}"
);
- handler.early_error(err);
+ early_dcx.early_error(err);
});
info!("probing {} for a codegen backend", sysroot.display());
@@ -285,7 +282,7 @@ fn get_codegen_sysroot(
sysroot.display(),
e
);
- handler.early_error(err);
+ early_dcx.early_error(err);
});
let mut file: Option<PathBuf> = None;
@@ -313,16 +310,16 @@ fn get_codegen_sysroot(
prev.display(),
path.display()
);
- handler.early_error(err);
+ early_dcx.early_error(err);
}
file = Some(path.clone());
}
match file {
- Some(ref s) => load_backend_from_dylib(handler, s),
+ Some(ref s) => load_backend_from_dylib(early_dcx, s),
None => {
let err = format!("unsupported builtin codegen backend `{backend_name}`");
- handler.early_error(err);
+ early_dcx.early_error(err);
}
}
}
@@ -415,7 +412,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
let mut base = session.opts.crate_types.clone();
if base.is_empty() {
let attr_types = attrs.iter().filter_map(|a| {
- if a.has_name(sym::crate_type) && let Some(s) = a.value_str() {
+ if a.has_name(sym::crate_type)
+ && let Some(s) = a.value_str()
+ {
categorize_crate_type(s)
} else {
None