summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_interface
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_interface')
-rw-r--r--compiler/rustc_interface/Cargo.toml5
-rw-r--r--compiler/rustc_interface/locales/en-US.ftl52
-rw-r--r--compiler/rustc_interface/src/callbacks.rs2
-rw-r--r--compiler/rustc_interface/src/errors.rs25
-rw-r--r--compiler/rustc_interface/src/interface.rs3
-rw-r--r--compiler/rustc_interface/src/lib.rs5
-rw-r--r--compiler/rustc_interface/src/passes.rs308
-rw-r--r--compiler/rustc_interface/src/queries.rs87
-rw-r--r--compiler/rustc_interface/src/tests.rs9
-rw-r--r--compiler/rustc_interface/src/util.rs34
10 files changed, 244 insertions, 286 deletions
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index f817c5bc1..ac6e8fca6 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -20,11 +20,11 @@ rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
-rustc_serialize = { path = "../rustc_serialize" }
rustc_middle = { path = "../rustc_middle" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_incremental = { path = "../rustc_incremental" }
+rustc_index = { path = "../rustc_index" }
rustc_traits = { path = "../rustc_traits" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
@@ -49,9 +49,6 @@ rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
-[dev-dependencies]
-rustc_target = { path = "../rustc_target" }
-
[features]
llvm = ['rustc_codegen_llvm']
rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler']
diff --git a/compiler/rustc_interface/locales/en-US.ftl b/compiler/rustc_interface/locales/en-US.ftl
new file mode 100644
index 000000000..37994899a
--- /dev/null
+++ b/compiler/rustc_interface/locales/en-US.ftl
@@ -0,0 +1,52 @@
+interface_ferris_identifier =
+ Ferris cannot be used as an identifier
+ .suggestion = try using their name instead
+
+interface_emoji_identifier =
+ identifiers cannot contain emoji: `{$ident}`
+
+interface_mixed_bin_crate =
+ cannot mix `bin` crate type with others
+
+interface_mixed_proc_macro_crate =
+ cannot mix `proc-macro` crate type with others
+
+interface_error_writing_dependencies =
+ error writing dependencies to `{$path}`: {$error}
+
+interface_input_file_would_be_overwritten =
+ the input file "{$path}" would be overwritten by the generated executable
+
+interface_generated_file_conflicts_with_directory =
+ the generated executable for the input file "{$input_path}" conflicts with the existing directory "{$dir_path}"
+
+interface_temps_dir_error =
+ failed to find or create the directory specified by `--temps-dir`
+
+interface_out_dir_error =
+ failed to find or create the directory specified by `--out-dir`
+
+interface_cant_emit_mir =
+ could not emit MIR: {$error}
+
+interface_rustc_error_fatal =
+ fatal error triggered by #[rustc_error]
+
+interface_rustc_error_unexpected_annotation =
+ unexpected annotation used with `#[rustc_error(...)]`!
+
+interface_failed_writing_file =
+ failed to write file {$path}: {$error}"
+
+interface_proc_macro_crate_panic_abort =
+ building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
+
+interface_unsupported_crate_type_for_target =
+ dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`
+
+interface_multiple_output_types_adaption =
+ due to multiple output types requested, the explicitly specified output file name will be adapted for each output type
+
+interface_ignoring_extra_filename = ignoring -C extra-filename flag due to -o flag
+
+interface_ignoring_out_dir = ignoring --out-dir flag due to -o flag
diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs
index ee0552d77..bc6d7c209 100644
--- a/compiler/rustc_interface/src/callbacks.rs
+++ b/compiler/rustc_interface/src/callbacks.rs
@@ -38,7 +38,7 @@ fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnost
// 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));
+ return tls::enter_context(&icx, move || (*f)(diagnostic));
}
// In any other case, invoke diagnostics anyway.
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
index 15d7e977b..0eedee250 100644
--- a/compiler/rustc_interface/src/errors.rs
+++ b/compiler/rustc_interface/src/errors.rs
@@ -1,5 +1,7 @@
use rustc_macros::Diagnostic;
+use rustc_session::config::CrateType;
use rustc_span::{Span, Symbol};
+use rustc_target::spec::TargetTriple;
use std::io;
use std::path::Path;
@@ -30,10 +32,6 @@ pub struct MixedBinCrate;
pub struct MixedProcMacroCrate;
#[derive(Diagnostic)]
-#[diag(interface_proc_macro_doc_without_arg)]
-pub struct ProcMacroDocWithoutArg;
-
-#[derive(Diagnostic)]
#[diag(interface_error_writing_dependencies)]
pub struct ErrorWritingDependencies<'a> {
pub path: &'a Path,
@@ -91,3 +89,22 @@ pub struct FailedWritingFile<'a> {
#[derive(Diagnostic)]
#[diag(interface_proc_macro_crate_panic_abort)]
pub struct ProcMacroCratePanicAbort;
+
+#[derive(Diagnostic)]
+#[diag(interface_unsupported_crate_type_for_target)]
+pub struct UnsupportedCrateTypeForTarget<'a> {
+ pub crate_type: CrateType,
+ pub target_triple: &'a TargetTriple,
+}
+
+#[derive(Diagnostic)]
+#[diag(interface_multiple_output_types_adaption)]
+pub struct MultipleOutputTypesAdaption;
+
+#[derive(Diagnostic)]
+#[diag(interface_ignoring_extra_filename)]
+pub struct IgnoringExtraFilename;
+
+#[derive(Diagnostic)]
+#[diag(interface_ignoring_out_dir)]
+pub struct IgnoringOutDir;
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 7a5e45ada..5e38ca034 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -1,4 +1,3 @@
-pub use crate::passes::BoxedResolver;
use crate::util;
use rustc_ast::token;
@@ -223,6 +222,7 @@ pub struct Config {
pub output_dir: Option<PathBuf>,
pub output_file: Option<PathBuf>,
pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
+ pub locale_resources: &'static [&'static str],
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -268,6 +268,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
config.opts,
config.crate_cfg,
config.crate_check_cfg,
+ config.locale_resources,
config.file_loader,
CompilerIO {
input: config.input,
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 82bc4770b..1abbe8d4f 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -12,6 +12,9 @@
#[macro_use]
extern crate tracing;
+use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_macros::fluent_messages;
+
mod callbacks;
mod errors;
pub mod interface;
@@ -27,3 +30,5 @@ pub use queries::Queries;
#[cfg(test)]
mod tests;
+
+fluent_messages! { "../locales/en-US.ftl" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 379a76528..81c1d665e 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1,9 +1,4 @@
-use crate::errors::{
- CantEmitMIR, EmojiIdentifier, ErrorWritingDependencies, FerrisIdentifier,
- GeneratedFileConflictsWithDirectory, InputFileWouldBeOverWritten, MixedBinCrate,
- MixedProcMacroCrate, OutDirError, ProcMacroCratePanicAbort, ProcMacroDocWithoutArg,
- TempsDirError,
-};
+use crate::errors;
use crate::interface::{Compiler, Result};
use crate::proc_macro_decls;
use crate::util;
@@ -13,11 +8,12 @@ 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_errors::PResult;
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
-use rustc_hir::def_id::StableCrateId;
-use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore};
+use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
+use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
@@ -28,9 +24,9 @@ use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_a
use rustc_passes::{self, hir_stats, layout_test};
use rustc_plugin_impl as plugin;
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
-use rustc_resolve::{Resolver, ResolverArenas};
+use rustc_resolve::Resolver;
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
-use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn, Untracked};
+use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, Untracked};
use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
@@ -40,14 +36,10 @@ use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::traits;
use std::any::Any;
-use std::cell::RefCell;
use std::ffi::OsString;
use std::io::{self, BufWriter, Write};
-use std::marker::PhantomPinned;
use std::path::{Path, PathBuf};
-use std::pin::Pin;
-use std::rc::Rc;
-use std::sync::LazyLock;
+use std::sync::{Arc, LazyLock};
use std::{env, fs, iter};
pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
@@ -80,93 +72,6 @@ fn count_nodes(krate: &ast::Crate) -> usize {
counter.count
}
-pub use boxed_resolver::BoxedResolver;
-mod boxed_resolver {
- use super::*;
-
- pub struct BoxedResolver(Pin<Box<BoxedResolverInner>>);
-
- struct BoxedResolverInner {
- session: Lrc<Session>,
- resolver_arenas: Option<ResolverArenas<'static>>,
- resolver: Option<Resolver<'static>>,
- _pin: PhantomPinned,
- }
-
- // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
- // then resolver_arenas and session.
- impl Drop for BoxedResolverInner {
- fn drop(&mut self) {
- self.resolver.take();
- self.resolver_arenas.take();
- }
- }
-
- impl BoxedResolver {
- pub(super) fn new(
- session: Lrc<Session>,
- make_resolver: impl for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>,
- ) -> BoxedResolver {
- let mut boxed_resolver = Box::new(BoxedResolverInner {
- session,
- resolver_arenas: Some(Resolver::arenas()),
- resolver: None,
- _pin: PhantomPinned,
- });
- // SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
- // returns a resolver with the same lifetime as the arena. We ensure that the arena
- // outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
- unsafe {
- let resolver = make_resolver(
- std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
- std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
- boxed_resolver.resolver_arenas.as_ref().unwrap(),
- ),
- );
- boxed_resolver.resolver = Some(resolver);
- BoxedResolver(Pin::new_unchecked(boxed_resolver))
- }
- }
-
- pub fn access<F: for<'a> FnOnce(&mut Resolver<'a>) -> R, R>(&mut self, f: F) -> R {
- // SAFETY: The resolver doesn't need to be pinned.
- let mut resolver = unsafe {
- self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
- };
- f((&mut *resolver).as_mut().unwrap())
- }
-
- pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ty::ResolverOutputs {
- match Rc::try_unwrap(resolver) {
- Ok(resolver) => {
- let mut resolver = resolver.into_inner();
- // SAFETY: The resolver doesn't need to be pinned.
- let mut resolver = unsafe {
- resolver
- .0
- .as_mut()
- .map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
- };
- resolver.take().unwrap().into_outputs()
- }
- Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
- }
- }
- }
-}
-
-pub fn create_resolver(
- sess: Lrc<Session>,
- metadata_loader: Box<MetadataLoaderDyn>,
- krate: &ast::Crate,
- crate_name: Symbol,
-) -> BoxedResolver {
- trace!("create_resolver");
- BoxedResolver::new(sess, move |sess, resolver_arenas| {
- Resolver::new(sess, krate, crate_name, metadata_loader, resolver_arenas)
- })
-}
-
pub fn register_plugins<'a>(
sess: &'a Session,
metadata_loader: &'a dyn MetadataLoader,
@@ -267,14 +172,12 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
/// 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.
-pub fn configure_and_expand(
- sess: &Session,
- lint_store: &LintStore,
- mut krate: ast::Crate,
- crate_name: Symbol,
- resolver: &mut Resolver<'_>,
-) -> Result<ast::Crate> {
- trace!("configure_and_expand");
+#[instrument(level = "trace", skip(krate, resolver))]
+fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>) -> ast::Crate {
+ let tcx = resolver.tcx();
+ let sess = tcx.sess;
+ let lint_store = unerased_lint_store(tcx);
+ let crate_name = tcx.crate_name(LOCAL_CRATE);
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
rustc_builtin_macros::register_builtin_macros(resolver);
@@ -345,20 +248,19 @@ pub fn configure_and_expand(
ecx.check_unused_macros();
});
- let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
+ // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
+ // with a large AST
+ if ecx.reduced_recursion_limit.is_some() {
+ sess.abort_if_errors();
+ unreachable!();
+ }
if cfg!(windows) {
env::set_var("PATH", &old_path);
}
- if recursion_limit_hit {
- // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
- // with a large AST
- Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
- } else {
- Ok(krate)
- }
- })?;
+ krate
+ });
sess.time("maybe_building_test_harness", || {
rustc_builtin_macros::test_harness::inject(sess, resolver, &mut krate)
@@ -374,39 +276,29 @@ pub fn configure_and_expand(
if crate_types.len() > 1 {
if is_executable_crate {
- sess.emit_err(MixedBinCrate);
+ sess.emit_err(errors::MixedBinCrate);
}
if is_proc_macro_crate {
- sess.emit_err(MixedProcMacroCrate);
+ sess.emit_err(errors::MixedProcMacroCrate);
}
}
if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort {
- sess.emit_warning(ProcMacroCratePanicAbort);
+ sess.emit_warning(errors::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
- // 'cargo doc' will automatically pass the proper '--crate-type' flags.
- // However, we do emit a warning, to let such users know that they should
- // start passing '--crate-type proc-macro'
- if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate {
- sess.emit_warning(ProcMacroDocWithoutArg);
- } else {
- krate = sess.time("maybe_create_a_macro_crate", || {
- let is_test_crate = sess.opts.test;
- rustc_builtin_macros::proc_macro_harness::inject(
- sess,
- resolver,
- krate,
- is_proc_macro_crate,
- has_proc_macro_decls,
- is_test_crate,
- sess.diagnostic(),
- )
- });
- }
+ krate = sess.time("maybe_create_a_macro_crate", || {
+ let is_test_crate = sess.opts.test;
+ rustc_builtin_macros::proc_macro_harness::inject(
+ sess,
+ resolver,
+ krate,
+ is_proc_macro_crate,
+ has_proc_macro_decls,
+ is_test_crate,
+ sess.diagnostic(),
+ )
+ });
// Done with macro expansion!
@@ -441,9 +333,9 @@ pub fn configure_and_expand(
spans.sort();
if ident == sym::ferris {
let first_span = spans[0];
- sess.emit_err(FerrisIdentifier { spans, first_span });
+ sess.emit_err(errors::FerrisIdentifier { spans, first_span });
} else {
- sess.emit_err(EmojiIdentifier { spans, ident });
+ sess.emit_err(errors::EmojiIdentifier { spans, ident });
}
}
});
@@ -461,7 +353,7 @@ pub fn configure_and_expand(
)
});
- Ok(krate)
+ krate
}
// Returns all the paths that correspond to generated files.
@@ -548,7 +440,7 @@ fn escape_dep_env(symbol: Symbol) -> String {
fn write_out_deps(
sess: &Session,
- boxed_resolver: &RefCell<BoxedResolver>,
+ cstore: &CrateStoreDyn,
outputs: &OutputFilenames,
out_filenames: &[PathBuf],
) {
@@ -600,20 +492,19 @@ fn write_out_deps(
}
}
- boxed_resolver.borrow_mut().access(|resolver| {
- for cnum in resolver.cstore().crates_untracked() {
- let source = resolver.cstore().crate_source_untracked(cnum);
- if let Some((path, _)) = &source.dylib {
- files.push(escape_dep_filename(&path.display().to_string()));
- }
- if let Some((path, _)) = &source.rlib {
- files.push(escape_dep_filename(&path.display().to_string()));
- }
- if let Some((path, _)) = &source.rmeta {
- files.push(escape_dep_filename(&path.display().to_string()));
- }
+ let cstore = cstore.as_any().downcast_ref::<CStore>().unwrap();
+ for cnum in cstore.crates_untracked() {
+ let source = cstore.crate_source_untracked(cnum);
+ if let Some((path, _)) = &source.dylib {
+ files.push(escape_dep_filename(&path.display().to_string()));
+ }
+ if let Some((path, _)) = &source.rlib {
+ files.push(escape_dep_filename(&path.display().to_string()));
}
- });
+ if let Some((path, _)) = &source.rmeta {
+ files.push(escape_dep_filename(&path.display().to_string()));
+ }
+ }
}
let mut file = BufWriter::new(fs::File::create(&deps_filename)?);
@@ -656,18 +547,38 @@ fn write_out_deps(
}
}
Err(error) => {
- sess.emit_fatal(ErrorWritingDependencies { path: &deps_filename, error });
+ sess.emit_fatal(errors::ErrorWritingDependencies { path: &deps_filename, error });
}
}
}
-pub fn prepare_outputs(
- sess: &Session,
- krate: &ast::Crate,
- boxed_resolver: &RefCell<BoxedResolver>,
- crate_name: Symbol,
-) -> Result<OutputFilenames> {
+fn resolver_for_lowering<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ (): (),
+) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
+ let arenas = Resolver::arenas();
+ let krate = tcx.crate_for_resolver(()).steal();
+ let mut resolver = Resolver::new(tcx, &krate, &arenas);
+ let krate = configure_and_expand(krate, &mut resolver);
+
+ // Make sure we don't mutate the cstore from here on.
+ tcx.untracked().cstore.leak();
+
+ let ty::ResolverOutputs {
+ global_ctxt: untracked_resolutions,
+ ast_lowering: untracked_resolver_for_lowering,
+ } = resolver.into_outputs();
+
+ let feed = tcx.feed_unit_query();
+ feed.resolutions(tcx.arena.alloc(untracked_resolutions));
+ tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate))))
+}
+
+fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
+ let sess = tcx.sess;
let _timer = sess.timer("prepare_outputs");
+ let (_, krate) = &*tcx.resolver_for_lowering(()).borrow();
+ let crate_name = tcx.crate_name(LOCAL_CRATE);
// FIXME: rustdoc passes &[] instead of &krate.attrs here
let outputs = util::build_output_filenames(&krate.attrs, sess);
@@ -679,25 +590,24 @@ pub fn prepare_outputs(
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 });
- return Err(reported);
+ sess.emit_fatal(errors::InputFileWouldBeOverWritten { path: input_path });
}
if let Some(ref dir_path) = output_conflicts_with_dir(&output_paths) {
- let reported =
- sess.emit_err(GeneratedFileConflictsWithDirectory { input_path, dir_path });
- return Err(reported);
+ sess.emit_fatal(errors::GeneratedFileConflictsWithDirectory {
+ input_path,
+ dir_path,
+ });
}
}
}
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);
+ sess.emit_fatal(errors::TempsDirError);
}
}
- write_out_deps(sess, boxed_resolver, &outputs, &output_paths);
+ write_out_deps(sess, &*tcx.cstore_untracked(), &outputs, &output_paths);
let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
&& sess.opts.output_types.len() == 1;
@@ -705,19 +615,20 @@ pub fn prepare_outputs(
if !only_dep_info {
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);
+ sess.emit_fatal(errors::OutDirError);
}
}
}
- Ok(outputs)
+ 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;
proc_macro_decls::provide(providers);
rustc_const_eval::provide(providers);
rustc_middle::hir::provide(providers);
@@ -747,30 +658,16 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock:
extern_providers
});
-pub struct QueryContext<'tcx> {
- gcx: &'tcx GlobalCtxt<'tcx>,
-}
-
-impl<'tcx> QueryContext<'tcx> {
- pub fn enter<F, R>(&mut self, f: F) -> R
- where
- F: FnOnce(TyCtxt<'tcx>) -> R,
- {
- let icx = ty::tls::ImplicitCtxt::new(self.gcx);
- ty::tls::enter_context(&icx, |_| f(icx.tcx))
- }
-}
-
pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>,
dep_graph: DepGraph,
untracked: Untracked,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
- global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
+ gcx_cell: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
-) -> QueryContext<'tcx> {
+) -> &'tcx GlobalCtxt<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
@@ -794,8 +691,8 @@ pub fn create_global_ctxt<'tcx>(
TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache)
});
- let gcx = sess.time("setup_global_ctxt", || {
- global_ctxt.get_or_init(move || {
+ sess.time("setup_global_ctxt", || {
+ gcx_cell.get_or_init(move || {
TyCtxt::create_global_ctxt(
sess,
lint_store,
@@ -808,9 +705,7 @@ pub fn create_global_ctxt<'tcx>(
rustc_query_impl::query_callbacks(arena),
)
})
- });
-
- QueryContext { gcx }
+ })
}
/// Runs the resolution, type-checking, region checking and other
@@ -900,6 +795,15 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
}
});
+ if tcx.sess.opts.unstable_opts.drop_tracking_mir {
+ tcx.hir().par_body_owners(|def_id| {
+ if let rustc_hir::def::DefKind::Generator = tcx.def_kind(def_id) {
+ tcx.ensure().mir_generator_witnesses(def_id);
+ tcx.ensure().check_generator_obligations(def_id);
+ }
+ });
+ }
+
sess.time("layout_testing", || layout_test::test_layout(tcx));
// Avoid overwhelming user with errors if borrow checking failed.
@@ -975,7 +879,7 @@ pub fn start_codegen<'tcx>(
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) {
- tcx.sess.emit_err(CantEmitMIR { error });
+ tcx.sess.emit_err(errors::CantEmitMIR { error });
tcx.sess.abort_if_errors();
}
}
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index d5a49dd75..a96cc95a3 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,27 +1,29 @@
use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
use crate::interface::{Compiler, Result};
-use crate::passes::{self, BoxedResolver, QueryContext};
+use crate::passes;
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;
+use rustc_data_structures::sync::{AppendOnlyVec, Lrc, OnceCell, RwLock, WorkerLocal};
+use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::definitions::Definitions;
use rustc_incremental::DepGraphFuture;
use rustc_lint::LintStore;
+use rustc_metadata::creader::CStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
-use rustc_middle::ty::{self, GlobalCtxt, TyCtxt};
+use rustc_middle::ty::{GlobalCtxt, TyCtxt};
use rustc_query_impl::Queries as TcxQueries;
use rustc_session::config::{self, OutputFilenames, OutputType};
+use rustc_session::cstore::Untracked;
use rustc_session::{output::find_crate_name, Session};
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use std::any::Any;
use std::cell::{RefCell, RefMut};
-use std::rc::Rc;
use std::sync::Arc;
/// Represent the result of a query.
@@ -64,8 +66,8 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
}
}
-impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> {
- pub fn enter<T>(mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
+impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> {
+ pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
(*self.0).get_mut().enter(f)
}
}
@@ -78,7 +80,7 @@ impl<T> Default for Query<T> {
pub struct Queries<'tcx> {
compiler: &'tcx Compiler,
- gcx: OnceCell<GlobalCtxt<'tcx>>,
+ gcx_cell: OnceCell<GlobalCtxt<'tcx>>,
queries: OnceCell<TcxQueries<'tcx>>,
arena: WorkerLocal<Arena<'tcx>>,
@@ -88,9 +90,9 @@ pub struct Queries<'tcx> {
parse: Query<ast::Crate>,
crate_name: Query<Symbol>,
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
- expansion: Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
- global_ctxt: Query<QueryContext<'tcx>>,
+ // This just points to what's in `gcx_cell`.
+ gcx: Query<&'tcx GlobalCtxt<'tcx>>,
ongoing_codegen: Query<Box<dyn Any>>,
}
@@ -98,7 +100,7 @@ impl<'tcx> Queries<'tcx> {
pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> {
Queries {
compiler,
- gcx: OnceCell::new(),
+ gcx_cell: OnceCell::new(),
queries: OnceCell::new(),
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
@@ -106,9 +108,8 @@ impl<'tcx> Queries<'tcx> {
parse: Default::default(),
crate_name: Default::default(),
register_plugins: Default::default(),
- expansion: Default::default(),
dep_graph: Default::default(),
- global_ctxt: Default::default(),
+ gcx: Default::default(),
ongoing_codegen: Default::default(),
}
}
@@ -168,29 +169,6 @@ impl<'tcx> Queries<'tcx> {
})
}
- pub fn expansion(
- &self,
- ) -> Result<QueryResult<'_, (Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>>
- {
- trace!("expansion");
- self.expansion.compute(|| {
- 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(
- sess.clone(),
- self.codegen_backend().metadata_loader(),
- &krate,
- crate_name,
- );
- let krate = resolver.access(|resolver| {
- passes::configure_and_expand(sess, &lint_store, krate, crate_name, resolver)
- })?;
- Ok((Lrc::new(krate), Rc::new(RefCell::new(resolver)), lint_store))
- })
- }
-
fn dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
self.dep_graph.compute(|| {
let sess = self.session();
@@ -207,40 +185,41 @@ impl<'tcx> Queries<'tcx> {
})
}
- pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, QueryContext<'tcx>>> {
- self.global_ctxt.compute(|| {
+ pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
+ self.gcx.compute(|| {
let crate_name = *self.crate_name()?.borrow();
- let (krate, resolver, lint_store) = self.expansion()?.steal();
+ let (krate, lint_store) = self.register_plugins()?.steal();
- let outputs = passes::prepare_outputs(self.session(), &krate, &resolver, crate_name)?;
+ let sess = self.session();
- let ty::ResolverOutputs {
- untracked,
- global_ctxt: untracked_resolutions,
- ast_lowering: untracked_resolver_for_lowering,
- } = BoxedResolver::to_resolver_outputs(resolver);
+ let cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
+ let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
+ let source_span = AppendOnlyVec::new();
+ let _id = source_span.push(krate.spans.inner_span);
+ debug_assert_eq!(_id, CRATE_DEF_ID);
+ let untracked = Untracked { cstore, source_span, definitions };
- let mut qcx = passes::create_global_ctxt(
+ let qcx = passes::create_global_ctxt(
self.compiler,
lint_store,
self.dep_graph()?.steal(),
untracked,
&self.queries,
- &self.gcx,
+ &self.gcx_cell,
&self.arena,
&self.hir_arena,
);
qcx.enter(|tcx| {
+ let feed = tcx.feed_local_crate();
+ feed.crate_name(crate_name);
+
let feed = tcx.feed_unit_query();
- feed.resolver_for_lowering(
- tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
+ feed.crate_for_resolver(tcx.arena.alloc(Steal::new(krate)));
+ feed.metadata_loader(
+ tcx.arena.alloc(Steal::new(self.codegen_backend().metadata_loader())),
);
- 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)
})
@@ -390,7 +369,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() {
+ if let Some(Ok(gcx)) = &mut *queries.gcx.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 f94bc4d4c..18d84a702 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -5,6 +5,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::rustc_optgroups;
use rustc_session::config::Input;
+use rustc_session::config::InstrumentXRay;
use rustc_session::config::TraitSolver;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{
@@ -49,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
output_file: None,
temps_dir,
};
- let sess = build_session(sessopts, io, None, registry, Default::default(), None, None);
+ let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None);
(sess, cfg)
}
@@ -690,7 +691,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(proc_macro_execution_strategy, ProcMacroExecutionStrategy::CrossThread);
untracked!(profile_closures, true);
untracked!(query_dep_graph, true);
- untracked!(save_analysis, true);
untracked!(self_profile, SwitchWithOptPath::Enabled(None));
untracked!(self_profile_events, Some(vec![String::new()]));
untracked!(span_debug, true);
@@ -755,10 +755,11 @@ fn test_unstable_options_tracking_hash() {
tracked!(inline_mir_threshold, Some(123));
tracked!(instrument_coverage, Some(InstrumentCoverage::All));
tracked!(instrument_mcount, true);
+ tracked!(instrument_xray, Some(InstrumentXRay::default()));
+ tracked!(link_directives, false);
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);
@@ -776,7 +777,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(packed_bundled_libs, true);
tracked!(panic_abort_tests, true);
tracked!(panic_in_drop, PanicStrategy::Abort);
- tracked!(pick_stable_methods_before_any_unstable, false);
tracked!(plt, Some(true));
tracked!(polonius, true);
tracked!(precise_enum_drop_elaboration, false);
@@ -802,6 +802,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(teach, true);
tracked!(thinlto, Some(true));
tracked!(thir_unsafeck, true);
+ tracked!(tiny_const_eval_limit, true);
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
tracked!(trait_solver, TraitSolver::Chalk);
tracked!(translate_remapped_path_to_local_path, false);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 54363e07b..e5d2fb2ea 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use crate::errors;
use info;
use libloading::Library;
use rustc_ast as ast;
@@ -13,8 +14,8 @@ use rustc_session::filesearch::sysroot_candidates;
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
use rustc_session::parse::CrateConfig;
use rustc_session::{early_error, filesearch, output, Session};
+use rustc_span::edit_distance::find_best_match_for_name;
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;
@@ -58,6 +59,7 @@ pub fn create_session(
sopts: config::Options,
cfg: FxHashSet<(String, Option<String>)>,
check_cfg: CheckCfg,
+ locale_resources: &'static [&'static str],
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
io: CompilerIO,
lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -88,11 +90,15 @@ pub fn create_session(
}
};
+ let mut locale_resources = Vec::from(locale_resources);
+ locale_resources.push(codegen_backend.locale_resource());
+
let mut sess = session::build_session(
sopts,
io,
bundle,
descriptions,
+ locale_resources,
lint_caps,
file_loader,
target_override,
@@ -472,16 +478,15 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
}
base.retain(|crate_type| {
- let res = !output::invalid_output_for_target(session, *crate_type);
-
- if !res {
- session.warn(&format!(
- "dropping unsupported crate type `{}` for target `{}`",
- *crate_type, session.opts.target_triple
- ));
+ if output::invalid_output_for_target(session, *crate_type) {
+ session.emit_warning(errors::UnsupportedCrateTypeForTarget {
+ crate_type: *crate_type,
+ target_triple: &session.opts.target_triple,
+ });
+ false
+ } else {
+ true
}
-
- res
});
base
@@ -517,19 +522,16 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu
let unnamed_output_types =
sess.opts.output_types.values().filter(|a| a.is_none()).count();
let ofile = if unnamed_output_types > 1 {
- sess.warn(
- "due to multiple output types requested, the explicitly specified \
- output file name will be adapted for each output type",
- );
+ sess.emit_warning(errors::MultipleOutputTypesAdaption);
None
} else {
if !sess.opts.cg.extra_filename.is_empty() {
- sess.warn("ignoring -C extra-filename flag due to -o flag");
+ sess.emit_warning(errors::IgnoringExtraFilename);
}
Some(out_file.clone())
};
if sess.io.output_dir != None {
- sess.warn("ignoring --out-dir flag due to -o flag");
+ sess.emit_warning(errors::IgnoringOutDir);
}
OutputFilenames::new(