summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_interface
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_interface')
-rw-r--r--compiler/rustc_interface/Cargo.toml1
-rw-r--r--compiler/rustc_interface/src/errors.rs89
-rw-r--r--compiler/rustc_interface/src/interface.rs8
-rw-r--r--compiler/rustc_interface/src/lib.rs8
-rw-r--r--compiler/rustc_interface/src/passes.rs103
-rw-r--r--compiler/rustc_interface/src/queries.rs20
-rw-r--r--compiler/rustc_interface/src/tests.rs11
-rw-r--r--compiler/rustc_interface/src/util.rs4
8 files changed, 159 insertions, 85 deletions
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 1ecbc876c..da4002d09 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -17,6 +17,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_expand = { path = "../rustc_expand" }
+rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs
new file mode 100644
index 000000000..6a497aed4
--- /dev/null
+++ b/compiler/rustc_interface/src/errors.rs
@@ -0,0 +1,89 @@
+use rustc_macros::SessionDiagnostic;
+use rustc_span::{Span, Symbol};
+
+use std::io;
+use std::path::Path;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::ferris_identifier)]
+pub struct FerrisIdentifier {
+ #[primary_span]
+ pub spans: Vec<Span>,
+ #[suggestion(code = "ferris", applicability = "maybe-incorrect")]
+ pub first_span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::emoji_identifier)]
+pub struct EmojiIdentifier {
+ #[primary_span]
+ pub spans: Vec<Span>,
+ pub ident: Symbol,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::mixed_bin_crate)]
+pub struct MixedBinCrate;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::mixed_proc_macro_crate)]
+pub struct MixedProcMacroCrate;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::proc_macro_doc_without_arg)]
+pub struct ProcMacroDocWithoutArg;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::error_writing_dependencies)]
+pub struct ErrorWritingDependencies<'a> {
+ pub path: &'a Path,
+ pub error: io::Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::input_file_would_be_overwritten)]
+pub struct InputFileWouldBeOverWritten<'a> {
+ pub path: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::generated_file_conflicts_with_directory)]
+pub struct GeneratedFileConflictsWithDirectory<'a> {
+ pub input_path: &'a Path,
+ pub dir_path: &'a Path,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::temps_dir_error)]
+pub struct TempsDirError;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::out_dir_error)]
+pub struct OutDirError;
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::cant_emit_mir)]
+pub struct CantEmitMIR {
+ pub error: io::Error,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::rustc_error_fatal)]
+pub struct RustcErrorFatal {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::rustc_error_unexpected_annotation)]
+pub struct RustcErrorUnexpectedAnnotation {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(interface::failed_writing_file)]
+pub struct FailedWritingFile<'a> {
+ pub path: &'a Path,
+ pub error: io::Error,
+}
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 94f81b660..949bd02ad 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -176,7 +176,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
let ident = arg.ident().expect("multi-segment cfg key");
names_valid.insert(ident.name.to_string());
} else {
- error!("`names()` arguments must be simple identifers");
+ error!("`names()` arguments must be simple identifiers");
}
}
continue 'specs;
@@ -204,7 +204,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
continue 'specs;
} else {
error!(
- "`values()` first argument must be a simple identifer"
+ "`values()` first argument must be a simple identifier"
);
}
} else if args.is_empty() {
@@ -330,9 +330,9 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
}
// JUSTIFICATION: before session exists, only config
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
- tracing::trace!("run_compiler");
+ trace!("run_compiler");
util::run_in_thread_pool_with_globals(
config.opts.edition,
config.opts.unstable_opts.threads,
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index d443057eb..41cd7b0e9 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,12 +1,18 @@
#![feature(box_patterns)]
-#![feature(let_else)]
+#![cfg_attr(bootstrap, feature(let_else))]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
+
+#[macro_use]
+extern crate tracing;
mod callbacks;
+mod errors;
pub mod interface;
mod passes;
mod proc_macro_decls;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 8f0835917..c41b154c3 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1,3 +1,8 @@
+use crate::errors::{
+ CantEmitMIR, EmojiIdentifier, ErrorWritingDependencies, FerrisIdentifier,
+ GeneratedFileConflictsWithDirectory, InputFileWouldBeOverWritten, MixedBinCrate,
+ MixedProcMacroCrate, OutDirError, ProcMacroDocWithoutArg, TempsDirError,
+};
use crate::interface::{Compiler, Result};
use crate::proc_macro_decls;
use crate::util;
@@ -8,7 +13,7 @@ use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
-use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, PResult};
+use rustc_errors::{ErrorGuaranteed, PResult};
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
use rustc_hir::def_id::StableCrateId;
use rustc_hir::definitions::Definitions;
@@ -33,7 +38,6 @@ use rustc_span::symbol::{sym, Symbol};
use rustc_span::FileName;
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
-use tracing::{info, warn};
use std::any::Any;
use std::cell::RefCell;
@@ -64,7 +68,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
}
if sess.opts.unstable_opts.hir_stats {
- hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS");
+ hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1");
}
Ok(krate)
@@ -160,7 +164,7 @@ pub fn create_resolver(
krate: &ast::Crate,
crate_name: &str,
) -> BoxedResolver {
- tracing::trace!("create_resolver");
+ trace!("create_resolver");
BoxedResolver::new(sess, move |sess, resolver_arenas| {
Resolver::new(sess, krate, crate_name, metadata_loader, resolver_arenas)
})
@@ -274,7 +278,7 @@ pub fn configure_and_expand(
crate_name: &str,
resolver: &mut Resolver<'_>,
) -> Result<ast::Crate> {
- tracing::trace!("configure_and_expand");
+ trace!("configure_and_expand");
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
rustc_builtin_macros::register_builtin_macros(resolver);
@@ -374,10 +378,10 @@ pub fn configure_and_expand(
if crate_types.len() > 1 {
if is_executable_crate {
- sess.err("cannot mix `bin` crate type with others");
+ sess.emit_err(MixedBinCrate);
}
if is_proc_macro_crate {
- sess.err("cannot mix `proc-macro` crate type with others");
+ sess.emit_err(MixedProcMacroCrate);
}
}
@@ -388,13 +392,7 @@ pub fn configure_and_expand(
// 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 {
- let mut msg = sess.diagnostic().struct_warn(
- "Trying to document proc macro crate \
- without passing '--crate-type proc-macro to rustdoc",
- );
-
- msg.warn("The generated documentation may be incorrect");
- msg.emit();
+ sess.emit_warning(ProcMacroDocWithoutArg);
} else {
krate = sess.time("maybe_create_a_macro_crate", || {
let is_test_crate = sess.opts.test;
@@ -417,7 +415,7 @@ pub fn configure_and_expand(
}
if sess.opts.unstable_opts.hir_stats {
- hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS");
+ hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS", "ast-stats-2");
}
resolver.resolve_crate(&krate);
@@ -443,23 +441,9 @@ pub fn configure_and_expand(
spans.sort();
if ident == sym::ferris {
let first_span = spans[0];
- sess.diagnostic()
- .struct_span_err(
- MultiSpan::from(spans),
- "Ferris cannot be used as an identifier",
- )
- .span_suggestion(
- first_span,
- "try using their name instead",
- "ferris",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ sess.emit_err(FerrisIdentifier { spans, first_span });
} else {
- sess.diagnostic().span_err(
- MultiSpan::from(spans),
- &format!("identifiers cannot contain emoji: `{}`", ident),
- );
+ sess.emit_err(EmojiIdentifier { spans, ident });
}
}
});
@@ -589,13 +573,24 @@ fn write_out_deps(
// Account for explicitly marked-to-track files
// (e.g. accessed in proc macros).
let file_depinfo = sess.parse_sess.file_depinfo.borrow();
- let extra_tracked_files = file_depinfo.iter().map(|path_sym| {
- let path = PathBuf::from(path_sym.as_str());
+
+ let normalize_path = |path: PathBuf| {
let file = FileName::from(path);
escape_dep_filename(&file.prefer_local().to_string())
- });
+ };
+
+ let extra_tracked_files =
+ file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str())));
files.extend(extra_tracked_files);
+ // We also need to track used PGO profile files
+ if let Some(ref profile_instr) = sess.opts.cg.profile_use {
+ files.push(normalize_path(profile_instr.as_path().to_path_buf()));
+ }
+ if let Some(ref profile_sample) = sess.opts.unstable_opts.profile_sample_use {
+ files.push(normalize_path(profile_sample.as_path().to_path_buf()));
+ }
+
if sess.binary_dep_depinfo() {
if let Some(ref backend) = sess.opts.unstable_opts.codegen_backend {
if backend.contains('.') {
@@ -662,11 +657,9 @@ fn write_out_deps(
.emit_artifact_notification(&deps_filename, "dep-info");
}
}
- Err(e) => sess.fatal(&format!(
- "error writing dependencies to `{}`: {}",
- deps_filename.display(),
- e
- )),
+ Err(error) => {
+ sess.emit_fatal(ErrorWritingDependencies { path: &deps_filename, error });
+ }
}
}
@@ -696,20 +689,12 @@ pub fn prepare_outputs(
if let Some(ref input_path) = compiler.input_path {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
- let reported = sess.err(&format!(
- "the input file \"{}\" would be overwritten by the generated \
- executable",
- input_path.display()
- ));
+ let reported = sess.emit_err(InputFileWouldBeOverWritten { path: input_path });
return Err(reported);
}
- if let Some(dir_path) = output_conflicts_with_dir(&output_paths) {
- let reported = sess.err(&format!(
- "the generated executable for the input file \"{}\" conflicts with the \
- existing directory \"{}\"",
- input_path.display(),
- dir_path.display()
- ));
+ 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);
}
}
@@ -717,8 +702,7 @@ pub fn prepare_outputs(
if let Some(ref dir) = compiler.temps_dir {
if fs::create_dir_all(dir).is_err() {
- let reported =
- sess.err("failed to find or create the directory specified by `--temps-dir`");
+ let reported = sess.emit_err(TempsDirError);
return Err(reported);
}
}
@@ -731,8 +715,7 @@ pub fn prepare_outputs(
if !only_dep_info {
if let Some(ref dir) = compiler.output_dir {
if fs::create_dir_all(dir).is_err() {
- let reported =
- sess.err("failed to find or create the directory specified by `--out-dir`");
+ let reported = sess.emit_err(OutDirError);
return Err(reported);
}
}
@@ -907,13 +890,13 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
});
},
{
- sess.time("liveness_and_intrinsic_checking", || {
- tcx.hir().par_for_each_module(|module| {
+ sess.time("liveness_checking", || {
+ tcx.hir().par_body_owners(|def_id| {
// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
- tcx.ensure().check_mod_liveness(module);
+ tcx.ensure().check_liveness(def_id.to_def_id());
});
});
}
@@ -1015,8 +998,8 @@ pub fn start_codegen<'tcx>(
info!("Post-codegen\n{:?}", tcx.debug_stats());
if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) {
- if let Err(e) = rustc_mir_transform::dump_mir::emit_mir(tcx, outputs) {
- tcx.sess.err(&format!("could not emit MIR: {}", e));
+ if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx, outputs) {
+ tcx.sess.emit_err(CantEmitMIR { error });
tcx.sess.abort_if_errors();
}
}
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 73402ae08..6c725a01b 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,3 +1,4 @@
+use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, QueryContext};
@@ -165,7 +166,7 @@ impl<'tcx> Queries<'tcx> {
pub fn expansion(
&self,
) -> Result<&Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>> {
- tracing::trace!("expansion");
+ trace!("expansion");
self.expansion.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let (krate, lint_store) = self.register_plugins()?.take();
@@ -274,18 +275,14 @@ impl<'tcx> Queries<'tcx> {
// Bare `#[rustc_error]`.
None => {
- tcx.sess.span_fatal(
- tcx.def_span(def_id),
- "fatal error triggered by #[rustc_error]",
- );
+ tcx.sess.emit_fatal(RustcErrorFatal { span: tcx.def_span(def_id) });
}
// Some other attribute.
Some(_) => {
- tcx.sess.span_warn(
- tcx.def_span(def_id),
- "unexpected annotation used with `#[rustc_error(...)]!",
- );
+ tcx.sess.emit_warning(RustcErrorUnexpectedAnnotation {
+ span: tcx.def_span(def_id),
+ });
}
}
}
@@ -360,9 +357,8 @@ impl Linker {
if sess.opts.unstable_opts.no_link {
let encoded = CodegenResults::serialize_rlink(&codegen_results);
let rlink_file = self.prepare_outputs.with_extension(config::RLINK_EXT);
- std::fs::write(&rlink_file, encoded).map_err(|err| {
- sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
- })?;
+ std::fs::write(&rlink_file, encoded)
+ .map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
return Ok(());
}
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index a9fdfa241..c7615a577 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#![allow(rustc::bad_opt_access)]
use crate::interface::parse_cfgspecs;
use rustc_data_structures::fx::FxHashSet;
@@ -21,10 +21,8 @@ use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::SourceFileHashAlgorithm;
-use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
-use rustc_target::spec::{
- RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel,
-};
+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;
@@ -552,7 +550,7 @@ fn test_codegen_options_tracking_hash() {
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
untracked!(link_self_contained, Some(true));
untracked!(linker, Some(PathBuf::from("linker")));
- untracked!(linker_flavor, Some(LinkerFlavor::Gcc));
+ untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
untracked!(no_stack_check, true);
untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
untracked!(rpath, true);
@@ -767,6 +765,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(no_profiler_runtime, true);
tracked!(oom, OomStrategy::Panic);
tracked!(osx_rpath_install_name, true);
+ tracked!(packed_bundled_libs, true);
tracked!(panic_abort_tests, true);
tracked!(panic_in_drop, PanicStrategy::Abort);
tracked!(pick_stable_methods_before_any_unstable, false);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 5e5596f13..f7e70d355 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use info;
use libloading::Library;
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
@@ -31,7 +32,6 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock;
use std::thread;
-use tracing::info;
/// Function pointer type that constructs a new CodegenBackend.
pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
@@ -559,7 +559,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
// command line, then reuse the empty `base` Vec to hold the types that
// will be found in crate attributes.
// JUSTIFICATION: before wrapper fn is available
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
let mut base = session.opts.crate_types.clone();
if base.is_empty() {
base.extend(attr_types);