summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src/session.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session/src/session.rs')
-rw-r--r--compiler/rustc_session/src/session.rs128
1 files changed, 86 insertions, 42 deletions
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 95f199de6..12634f671 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,16 +1,9 @@
use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
-pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
+pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use crate::config::Input;
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
-use crate::errors::{
- BranchProtectionRequiresAArch64, CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers,
- LinkerPluginToWindowsNotSupported, NotCircumventFeature, ProfileSampleUseFileDoesNotExist,
- ProfileUseFileDoesNotExist, SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
- SkippingConstChecks, SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
- TargetRequiresUnwindTables, UnleashedFeatureHelp, UnstableVirtualFunctionElimination,
- UnsupportedDwarfVersion,
-};
+use crate::errors;
use crate::parse::{add_feature_diagnostics, ParseSess};
use crate::search_paths::{PathKind, SearchPath};
use crate::{filesearch, lint};
@@ -31,6 +24,7 @@ use rustc_errors::registry::Registry;
use rustc_errors::{
error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted,
+ TerminalUrl,
};
use rustc_macros::HashStable_Generic;
pub use rustc_span::def_id::StableCrateId;
@@ -163,7 +157,7 @@ pub struct Session {
/// `-C metadata` arguments passed to the compiler. Its value forms a unique
/// global identifier for the crate. It is used to allow multiple crates
/// with the same name to coexist. See the
- /// `rustc_codegen_llvm::back::symbol_names` module for more information.
+ /// `rustc_symbol_mangling` crate for more information.
pub stable_crate_id: OnceCell<StableCrateId>,
features: OnceCell<rustc_feature::Features>,
@@ -245,15 +239,15 @@ impl Session {
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
- self.emit_warning(SkippingConstChecks {
+ self.emit_warning(errors::SkippingConstChecks {
unleashed_features: unleashed_features
.iter()
.map(|(span, gate)| {
gate.map(|gate| {
must_err = true;
- UnleashedFeatureHelp::Named { span: *span, gate }
+ errors::UnleashedFeatureHelp::Named { span: *span, gate }
})
- .unwrap_or(UnleashedFeatureHelp::Unnamed { span: *span })
+ .unwrap_or(errors::UnleashedFeatureHelp::Unnamed { span: *span })
})
.collect(),
});
@@ -261,7 +255,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.emit_err(NotCircumventFeature);
+ self.emit_err(errors::NotCircumventFeature);
}
}
}
@@ -483,6 +477,8 @@ impl Session {
self.diagnostic().span_err_with_code(sp, msg, code)
}
#[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
self.diagnostic().err(msg)
}
@@ -583,12 +579,16 @@ impl Session {
))
}
}
+
+ #[rustc_lint_diagnostics]
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
#[track_caller]
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().span_warn(sp, msg)
}
+
+ #[rustc_lint_diagnostics]
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_warn_with_code<S: Into<MultiSpan>>(
@@ -599,6 +599,10 @@ impl Session {
) {
self.diagnostic().span_warn_with_code(sp, msg, code)
}
+
+ #[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn warn(&self, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().warn(msg)
}
@@ -641,11 +645,17 @@ impl Session {
self.diagnostic().delay_good_path_bug(msg)
}
+ #[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().note_without_error(msg)
}
#[track_caller]
+ #[rustc_lint_diagnostics]
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
pub fn span_note_without_error<S: Into<MultiSpan>>(
&self,
sp: S,
@@ -653,6 +663,8 @@ impl Session {
) {
self.diagnostic().span_note_without_error(sp, msg)
}
+
+ #[rustc_lint_diagnostics]
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
pub fn struct_note_without_error(
@@ -870,10 +882,14 @@ impl Session {
/// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n.
/// This expends fuel if applicable, and records fuel if applicable.
- pub fn consider_optimizing<T: Fn() -> String>(&self, crate_name: &str, msg: T) -> bool {
+ pub fn consider_optimizing(
+ &self,
+ get_crate_name: impl Fn() -> Symbol,
+ msg: impl Fn() -> String,
+ ) -> bool {
let mut ret = true;
if let Some((ref c, _)) = self.opts.unstable_opts.fuel {
- if c == crate_name {
+ if c == get_crate_name().as_str() {
assert_eq!(self.threads(), 1);
let mut fuel = self.optimization_fuel.lock();
ret = fuel.remaining != 0;
@@ -882,7 +898,7 @@ impl Session {
// We only call `msg` in case we can actually emit warnings.
// Otherwise, this could cause a `delay_good_path_bug` to
// trigger (issue #79546).
- self.warn(&format!("optimization-fuel-exhausted: {}", msg()));
+ self.emit_warning(errors::OptimisationFuelExhausted { msg: msg() });
}
fuel.out_of_fuel = true;
} else if fuel.remaining > 0 {
@@ -891,7 +907,7 @@ impl Session {
}
}
if let Some(ref c) = self.opts.unstable_opts.print_fuel {
- if c == crate_name {
+ if c == get_crate_name().as_str() {
assert_eq!(self.threads(), 1);
self.print_fuel.fetch_add(1, SeqCst);
}
@@ -899,23 +915,24 @@ impl Session {
ret
}
- pub fn rust_2015(&self) -> bool {
- self.edition() == Edition::Edition2015
+ /// Is this edition 2015?
+ pub fn is_rust_2015(&self) -> bool {
+ self.edition().is_rust_2015()
}
/// Are we allowed to use features from the Rust 2018 edition?
pub fn rust_2018(&self) -> bool {
- self.edition() >= Edition::Edition2018
+ self.edition().rust_2018()
}
/// Are we allowed to use features from the Rust 2021 edition?
pub fn rust_2021(&self) -> bool {
- self.edition() >= Edition::Edition2021
+ self.edition().rust_2021()
}
/// Are we allowed to use features from the Rust 2024 edition?
pub fn rust_2024(&self) -> bool {
- self.edition() >= Edition::Edition2024
+ self.edition().rust_2024()
}
/// Returns `true` if we cannot skip the PLT for shared library calls.
@@ -941,10 +958,10 @@ impl Session {
/// Checks if LLVM lifetime markers should be emitted.
pub fn emit_lifetime_markers(&self) -> bool {
self.opts.optimize != config::OptLevel::No
- // AddressSanitizer uses lifetimes to detect use after scope bugs.
+ // AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
- || self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
+ || self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
}
pub fn is_proc_macro_attr(&self, attr: &Attribute) -> bool {
@@ -1261,6 +1278,19 @@ fn default_emitter(
) -> Box<dyn Emitter + sync::Send> {
let macro_backtrace = sopts.unstable_opts.macro_backtrace;
let track_diagnostics = sopts.unstable_opts.track_diagnostics;
+ let terminal_url = match sopts.unstable_opts.terminal_urls {
+ TerminalUrl::Auto => {
+ match (std::env::var("COLORTERM").as_deref(), std::env::var("TERM").as_deref()) {
+ (Ok("truecolor"), Ok("xterm-256color"))
+ if sopts.unstable_features.is_nightly_build() =>
+ {
+ TerminalUrl::Yes
+ }
+ _ => TerminalUrl::No,
+ }
+ }
+ t => t,
+ };
match sopts.error_format {
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
@@ -1285,6 +1315,7 @@ fn default_emitter(
sopts.diagnostic_width,
macro_backtrace,
track_diagnostics,
+ terminal_url,
);
Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
}
@@ -1300,6 +1331,7 @@ fn default_emitter(
sopts.diagnostic_width,
macro_backtrace,
track_diagnostics,
+ terminal_url,
)
.ui_testing(sopts.unstable_opts.ui_testing),
),
@@ -1313,6 +1345,7 @@ pub fn build_session(
io: CompilerIO,
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry,
+ fluent_resources: Vec<&'static str>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>,
@@ -1357,7 +1390,7 @@ pub fn build_session(
));
let fallback_bundle = fallback_fluent_bundle(
- rustc_errors::DEFAULT_LOCALE_RESOURCES,
+ fluent_resources,
sopts.unstable_opts.translate_directionality_markers,
);
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
@@ -1482,28 +1515,28 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
&& sess.opts.cg.prefer_dynamic
&& sess.target.is_like_windows
{
- sess.emit_err(LinkerPluginToWindowsNotSupported);
+ sess.emit_err(errors::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.emit_err(ProfileUseFileDoesNotExist { path });
+ sess.emit_err(errors::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.emit_err(ProfileSampleUseFileDoesNotExist { path });
+ sess.emit_err(errors::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.emit_err(TargetRequiresUnwindTables);
+ sess.emit_err(errors::TargetRequiresUnwindTables);
}
}
@@ -1513,16 +1546,18 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
match unsupported_sanitizers.into_iter().count() {
0 => {}
1 => {
- sess.emit_err(SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
+ sess.emit_err(errors::SanitizerNotSupported { us: unsupported_sanitizers.to_string() });
}
_ => {
- sess.emit_err(SanitizersNotSupported { us: unsupported_sanitizers.to_string() });
+ sess.emit_err(errors::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.emit_err(CannotMixAndMatchSanitizers {
+ sess.emit_err(errors::CannotMixAndMatchSanitizers {
first: first.to_string(),
second: second.to_string(),
});
@@ -1530,22 +1565,22 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
// Cannot enable crt-static with sanitizers on Linux
if sess.crt_static(None) && !sess.opts.unstable_opts.sanitizer.is_empty() {
- sess.emit_err(CannotEnableCrtStaticLinux);
+ sess.emit_err(errors::CannotEnableCrtStaticLinux);
}
// LLVM CFI and VFE both require LTO.
if sess.lto() != config::Lto::Fat {
if sess.is_sanitizer_cfi_enabled() {
- sess.emit_err(SanitizerCfiEnabled);
+ sess.emit_err(errors::SanitizerCfiEnabled);
}
if sess.opts.unstable_opts.virtual_function_elimination {
- sess.emit_err(UnstableVirtualFunctionElimination);
+ sess.emit_err(errors::UnstableVirtualFunctionElimination);
}
}
// LLVM CFI and KCFI are mutually exclusive
if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
- sess.emit_err(CannotMixAndMatchSanitizers {
+ sess.emit_err(errors::CannotMixAndMatchSanitizers {
first: "cfi".to_string(),
second: "kcfi".to_string(),
});
@@ -1553,7 +1588,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
- sess.emit_warning(StackProtectorNotSupportedForTarget {
+ sess.emit_warning(errors::StackProtectorNotSupportedForTarget {
stack_protector: sess.opts.unstable_opts.stack_protector,
target_triple: &sess.opts.target_triple,
});
@@ -1561,19 +1596,23 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
if sess.opts.unstable_opts.branch_protection.is_some() && sess.target.arch != "aarch64" {
- sess.emit_err(BranchProtectionRequiresAArch64);
+ sess.emit_err(errors::BranchProtectionRequiresAArch64);
}
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
if dwarf_version > 5 {
- sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
+ sess.emit_err(errors::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() });
+ sess.emit_err(errors::SplitDebugInfoUnstablePlatform { debuginfo: sess.split_debuginfo() });
+ }
+
+ if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
+ sess.emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
}
}
@@ -1596,7 +1635,10 @@ pub enum IncrCompSession {
}
fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
- let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+ // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will
+ // need to reference every crate that might emit an early error for translation to work.
+ let fallback_bundle =
+ fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false);
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
@@ -1610,6 +1652,7 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
None,
false,
false,
+ TerminalUrl::No,
))
}
config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic(
@@ -1620,6 +1663,7 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler
None,
false,
false,
+ TerminalUrl::No,
)),
};
rustc_errors::Handler::with_emitter(true, None, emitter)