summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src/session.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_session/src/session.rs178
1 files changed, 123 insertions, 55 deletions
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 9669287b3..a001f87db 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -2,6 +2,13 @@ use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
+use crate::errors::{
+ CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
+ NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
+ SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
+ SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
+ TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
+};
use crate::parse::{add_feature_diagnostics, ParseSess};
use crate::search_paths::{PathKind, SearchPath};
use crate::{filesearch, lint};
@@ -20,8 +27,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
use rustc_errors::json::JsonEmitter;
use rustc_errors::registry::Registry;
use rustc_errors::{
- fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
- ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan,
+ error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
+ EmissionGuarantee, ErrorGuaranteed, FluentBundle, Handler, LazyFallbackBundle, MultiSpan,
};
use rustc_macros::HashStable_Generic;
pub use rustc_span::def_id::StableCrateId;
@@ -31,7 +38,7 @@ use rustc_span::{sym, SourceFileHashAlgorithm, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
use rustc_target::spec::{
- SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
+ DebuginfoKind, SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
};
use std::cell::{self, RefCell};
@@ -110,6 +117,12 @@ impl Mul<usize> for Limit {
}
}
+impl rustc_errors::IntoDiagnosticArg for Limit {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ self.to_string().into_diagnostic_arg()
+ }
+}
+
#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct Limits {
/// The maximum recursion limit for potentially infinitely recursive
@@ -214,9 +227,9 @@ pub struct PerfStats {
/// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic].
#[rustc_diagnostic_item = "SessionDiagnostic"]
pub trait SessionDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> {
- /// Write out as a diagnostic out of `sess`.
+ /// Write out as a diagnostic out of `Handler`.
#[must_use]
- fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, T>;
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>;
}
impl Session {
@@ -229,6 +242,9 @@ impl Session {
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
+ // FIXME(#100717): needs eager translation/lists
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
let mut diag = self.struct_warn("skipping const checks");
for &(span, feature_gate) in unleashed_features.iter() {
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
@@ -244,10 +260,7 @@ impl Session {
// If we should err, make sure we did.
if must_err && self.has_errors().is_none() {
// We have skipped a feature gate, and not run into other errors... reject.
- self.err(
- "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
- gates, except when testing error paths in the CTFE engine",
- );
+ self.emit_err(NotCircumventFeature);
}
}
}
@@ -284,6 +297,8 @@ impl Session {
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -292,6 +307,8 @@ impl Session {
self.diagnostic().struct_span_warn(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn_with_expectation<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -301,6 +318,8 @@ impl Session {
self.diagnostic().struct_span_warn_with_expectation(sp, msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -310,10 +329,14 @@ impl Session {
self.diagnostic().struct_span_warn_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_warn(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -322,6 +345,8 @@ impl Session {
self.diagnostic().struct_warn_with_expectation(msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_allow<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -330,10 +355,14 @@ impl Session {
self.diagnostic().struct_span_allow(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.diagnostic().struct_allow(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_expect(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -342,6 +371,8 @@ impl Session {
self.diagnostic().struct_expect(msg, id)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -350,6 +381,8 @@ impl Session {
self.diagnostic().struct_span_err(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -360,6 +393,8 @@ impl Session {
}
// FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -367,6 +402,8 @@ impl Session {
self.parse_sess.struct_err(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_err_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -375,6 +412,8 @@ impl Session {
self.diagnostic().struct_err_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_warn_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -383,6 +422,8 @@ impl Session {
self.diagnostic().struct_warn_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_fatal<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -391,6 +432,8 @@ impl Session {
self.diagnostic().struct_span_fatal(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -400,15 +443,21 @@ impl Session {
self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
self.diagnostic().struct_fatal(msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().span_fatal(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -418,10 +467,14 @@ impl Session {
self.diagnostic().span_fatal_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! {
self.diagnostic().fatal(msg).raise()
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err_or_warn<S: Into<MultiSpan>>(
&self,
is_warning: bool,
@@ -435,6 +488,8 @@ impl Session {
}
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -443,6 +498,8 @@ impl Session {
self.diagnostic().span_err(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -467,6 +524,9 @@ impl Session {
feature: Symbol,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut err = self.parse_sess.create_err(err);
+ if err.code.is_none() {
+ err.code = std::option::Option::Some(error_code!(E0658));
+ }
add_feature_diagnostics(&mut err, &self.parse_sess, feature);
err
}
@@ -482,6 +542,15 @@ impl Session {
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
self.parse_sess.emit_warning(warning)
}
+ pub fn create_fatal<'a>(
+ &'a self,
+ fatal: impl SessionDiagnostic<'a, !>,
+ ) -> DiagnosticBuilder<'a, !> {
+ self.parse_sess.create_fatal(fatal)
+ }
+ pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
+ self.parse_sess.emit_fatal(fatal)
+ }
#[inline]
pub fn err_count(&self) -> usize {
self.diagnostic().err_count()
@@ -516,9 +585,13 @@ impl Session {
Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
}
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().span_warn(sp, msg)
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -567,6 +640,8 @@ impl Session {
) {
self.diagnostic().span_note_without_error(sp, msg)
}
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_note_without_error(
&self,
msg: impl Into<DiagnosticMessage>,
@@ -638,7 +713,7 @@ impl Session {
let found_positive = requested_features.clone().any(|r| r == "+crt-static");
// JUSTIFICATION: necessary use of crate_types directly (see FIXME below)
- #[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+ #[allow(rustc::bad_opt_access)]
if found_positive || found_negative {
found_positive
} else if crate_type == Some(CrateType::ProcMacro)
@@ -661,8 +736,9 @@ impl Session {
)
}
+ /// Returns `true` if the target can use the current split debuginfo configuration.
pub fn target_can_use_split_dwarf(&self) -> bool {
- !self.target.is_like_windows && !self.target.is_like_osx
+ self.target.debuginfo_kind == DebuginfoKind::Dwarf
}
pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String {
@@ -894,7 +970,7 @@ impl Session {
}
// JUSTIFICATION: defn of the suggested wrapper fns
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
impl Session {
pub fn verbose(&self) -> bool {
self.opts.unstable_opts.verbose
@@ -1174,7 +1250,7 @@ impl Session {
}
// JUSTIFICATION: part of session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn default_emitter(
sopts: &config::Options,
registry: rustc_errors::registry::Registry,
@@ -1260,7 +1336,7 @@ pub enum DiagnosticOutput {
}
// JUSTIFICATION: literally session construction
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
pub fn build_session(
sopts: config::Options,
local_crate_source_file: Option<PathBuf>,
@@ -1277,10 +1353,8 @@ pub fn build_session(
let warnings_allow = sopts
.lint_opts
.iter()
- .filter(|&&(ref key, _)| *key == "warnings")
- .map(|&(_, ref level)| *level == lint::Allow)
- .last()
- .unwrap_or(false);
+ .rfind(|&&(ref key, _)| *key == "warnings")
+ .map_or(false, |&(_, level)| level == lint::Allow);
let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow);
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
@@ -1437,7 +1511,7 @@ pub fn build_session(
/// If it is useful to have a Session available already for validating a commandline argument, you
/// can do so here.
// JUSTIFICATION: needs to access args to validate them
-#[cfg_attr(not(bootstrap), allow(rustc::bad_opt_access))]
+#[allow(rustc::bad_opt_access)]
fn validate_commandline_args_with_session_available(sess: &Session) {
// Since we don't know if code in an rlib will be linked to statically or
// dynamically downstream, rustc generates `__imp_` symbols that help linkers
@@ -1450,40 +1524,28 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
&& sess.opts.cg.prefer_dynamic
&& sess.target.is_like_windows
{
- sess.err(
- "Linker plugin based LTO is not supported together with \
- `-C prefer-dynamic` when targeting Windows-like targets",
- );
+ sess.emit_err(LinkerPluginToWindowsNotSupported);
}
// Make sure that any given profiling data actually exists so LLVM can't
// decide to silently skip PGO.
if let Some(ref path) = sess.opts.cg.profile_use {
if !path.exists() {
- sess.err(&format!(
- "File `{}` passed to `-C profile-use` does not exist.",
- path.display()
- ));
+ sess.emit_err(ProfileUseFileDoesNotExist { path });
}
}
// Do the same for sample profile data.
if let Some(ref path) = sess.opts.unstable_opts.profile_sample_use {
if !path.exists() {
- sess.err(&format!(
- "File `{}` passed to `-C profile-sample-use` does not exist.",
- path.display()
- ));
+ sess.emit_err(ProfileSampleUseFileDoesNotExist { path });
}
}
// Unwind tables cannot be disabled if the target requires them.
if let Some(include_uwtables) = sess.opts.cg.force_unwind_tables {
if sess.target.requires_uwtable && !include_uwtables {
- sess.err(
- "target requires unwind tables, they cannot be disabled with \
- `-C force-unwind-tables=no`.",
- );
+ sess.emit_err(TargetRequiresUnwindTables);
}
}
@@ -1493,56 +1555,56 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
match unsupported_sanitizers.into_iter().count() {
0 => {}
1 => {
- sess.err(&format!(
- "{} sanitizer is not supported for this target",
- unsupported_sanitizers
- ));
+ sess.emit_err(SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
}
_ => {
- sess.err(&format!(
- "{} sanitizers are not supported for this target",
- unsupported_sanitizers
- ));
+ sess.emit_err(SanitizersNotSupported { us: unsupported_sanitizers.to_string() });
}
}
// Cannot mix and match sanitizers.
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
- sess.err(&format!("`-Zsanitizer={first}` is incompatible with `-Zsanitizer={second}`"));
+ sess.emit_err(CannotMixAndMatchSanitizers {
+ first: first.to_string(),
+ second: second.to_string(),
+ });
}
// Cannot enable crt-static with sanitizers on Linux
if sess.crt_static(None) && !sess.opts.unstable_opts.sanitizer.is_empty() {
- sess.err(
- "sanitizer is incompatible with statically linked libc, \
- disable it using `-C target-feature=-crt-static`",
- );
+ sess.emit_err(CannotEnableCrtStaticLinux);
}
// LLVM CFI and VFE both require LTO.
if sess.lto() != config::Lto::Fat {
if sess.is_sanitizer_cfi_enabled() {
- sess.err("`-Zsanitizer=cfi` requires `-Clto`");
+ sess.emit_err(SanitizerCfiEnabled);
}
if sess.opts.unstable_opts.virtual_function_elimination {
- sess.err("`-Zvirtual-function-elimination` requires `-Clto`");
+ sess.emit_err(UnstableVirtualFunctionElimination);
}
}
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
- sess.warn(&format!(
- "`-Z stack-protector={}` is not supported for target {} and will be ignored",
- sess.opts.unstable_opts.stack_protector, sess.opts.target_triple
- ))
+ sess.emit_warning(StackProtectorNotSupportedForTarget {
+ stack_protector: sess.opts.unstable_opts.stack_protector,
+ target_triple: &sess.opts.target_triple,
+ });
}
}
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
if dwarf_version > 5 {
- sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version));
+ sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
}
}
+
+ if !sess.target.options.supported_split_debuginfo.contains(&sess.split_debuginfo())
+ && !sess.opts.unstable_opts.unstable_options
+ {
+ sess.emit_err(SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
+ }
}
/// Holds data on the current incremental compilation session, if there is one.
@@ -1586,14 +1648,20 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
rustc_errors::Handler::with_emitter(true, None, emitter)
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
early_error_handler(output).struct_err(msg).emit()
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
early_error_handler(output).struct_fatal(msg).emit()
}
+#[allow(rustc::untranslatable_diagnostic)]
+#[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
early_error_handler(output).struct_warn(msg).emit()
}