diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_session/src/session.rs | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_session/src/session.rs')
-rw-r--r-- | compiler/rustc_session/src/session.rs | 157 |
1 files changed, 110 insertions, 47 deletions
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index bbe52dbce..5be122ffb 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,8 +1,10 @@ use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; 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::config::{ + self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath, +}; +use crate::config::{ErrorOutputType, Input}; use crate::errors; use crate::parse::{add_feature_diagnostics, ParseSess}; use crate::search_paths::{PathKind, SearchPath}; @@ -23,7 +25,7 @@ use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted, + ErrorGuaranteed, FluentBundle, Handler, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted, TerminalUrl, }; use rustc_macros::HashStable_Generic; @@ -128,14 +130,12 @@ pub struct Limits { pub move_size_limit: Limit, /// The maximum length of types during monomorphization. pub type_length_limit: Limit, - /// The maximum blocks a const expression can evaluate. - pub const_eval_limit: Limit, } pub struct CompilerIO { pub input: Input, pub output_dir: Option<PathBuf>, - pub output_file: Option<PathBuf>, + pub output_file: Option<OutFileName>, pub temps_dir: Option<PathBuf>, } @@ -234,6 +234,27 @@ pub enum MetadataKind { Compressed, } +#[derive(Clone, Copy)] +pub enum CodegenUnits { + /// Specified by the user. In this case we try fairly hard to produce the + /// number of CGUs requested. + User(usize), + + /// A default value, i.e. not specified by the user. In this case we take + /// more liberties about CGU formation, e.g. avoid producing very small + /// CGUs. + Default(usize), +} + +impl CodegenUnits { + pub fn as_usize(self) -> usize { + match self { + CodegenUnits::User(n) => n, + CodegenUnits::Default(n) => n, + } + } +} + impl Session { pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option<Symbol>) { self.miri_unleashed_features.lock().push((span, feature_gate)); @@ -988,11 +1009,11 @@ impl Session { self.edition().rust_2024() } - /// Returns `true` if we cannot skip the PLT for shared library calls. + /// Returns `true` if we should use the PLT for shared library calls. pub fn needs_plt(&self) -> bool { - // Check if the current target usually needs PLT to be enabled. + // Check if the current target usually wants PLT to be enabled. // The user can use the command line flag to override it. - let needs_plt = self.target.needs_plt; + let want_plt = self.target.plt_by_default; let dbg_opts = &self.opts.unstable_opts; @@ -1004,8 +1025,8 @@ impl Session { let full_relro = RelroLevel::Full == relro_level; // If user didn't explicitly forced us to use / skip the PLT, - // then try to skip it where possible. - dbg_opts.plt.unwrap_or(needs_plt || !full_relro) + // then use it unless the target doesn't want it by default or the full relro forces it on. + dbg_opts.plt.unwrap_or(want_plt || !full_relro) } /// Checks if LLVM lifetime markers should be emitted. @@ -1104,7 +1125,7 @@ impl Session { // If there's only one codegen unit and LTO isn't enabled then there's // no need for ThinLTO so just return false. - if self.codegen_units() == 1 { + if self.codegen_units().as_usize() == 1 { return config::Lto::No; } @@ -1206,19 +1227,19 @@ impl Session { /// Returns the number of codegen units that should be used for this /// compilation - pub fn codegen_units(&self) -> usize { + pub fn codegen_units(&self) -> CodegenUnits { if let Some(n) = self.opts.cli_forced_codegen_units { - return n; + return CodegenUnits::User(n); } if let Some(n) = self.target.default_codegen_units { - return n as usize; + return CodegenUnits::Default(n as usize); } // If incremental compilation is turned on, we default to a high number // codegen units in order to reduce the "collateral damage" small // changes cause. if self.opts.incremental.is_some() { - return 256; + return CodegenUnits::Default(256); } // Why is 16 codegen units the default all the time? @@ -1271,7 +1292,7 @@ impl Session { // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. - 16 + CodegenUnits::Default(16) } pub fn teach(&self, code: &DiagnosticId) -> bool { @@ -1361,6 +1382,7 @@ fn default_emitter( // JUSTIFICATION: literally session construction #[allow(rustc::bad_opt_access)] pub fn build_session( + handler: &EarlyErrorHandler, sopts: config::Options, io: CompilerIO, bundle: Option<Lrc<rustc_errors::FluentBundle>>, @@ -1387,13 +1409,12 @@ pub fn build_session( None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"), }; - let target_cfg = config::build_target_config(&sopts, target_override, &sysroot); + let target_cfg = config::build_target_config(handler, &sopts, target_override, &sysroot); let host_triple = TargetTriple::from_triple(config::host_triple()); - let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| { - early_error(sopts.error_format, format!("Error loading host specification: {e}")) - }); + let (host, target_warnings) = Target::search(&host_triple, &sysroot) + .unwrap_or_else(|e| handler.early_error(format!("Error loading host specification: {e}"))); for warning in target_warnings.warning_messages() { - early_warn(sopts.error_format, warning) + handler.early_warn(warning) } let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); @@ -1435,7 +1456,7 @@ pub fn build_session( match profiler { Ok(profiler) => Some(Arc::new(profiler)), Err(e) => { - early_warn(sopts.error_format, format!("failed to create profiler: {e}")); + handler.early_warn(format!("failed to create profiler: {e}")); None } } @@ -1675,6 +1696,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) { if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray { sess.emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() }); } + + if let Some(flavor) = sess.opts.cg.linker_flavor { + if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) { + let flavor = flavor.desc(); + sess.emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list }); + } + } } /// Holds data on the current incremental compilation session, if there is one. @@ -1695,7 +1723,64 @@ pub enum IncrCompSession { InvalidBecauseOfErrors { session_directory: PathBuf }, } -fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler { +/// A wrapper around an [`Handler`] that is used for early error emissions. +pub struct EarlyErrorHandler { + handler: Handler, +} + +impl EarlyErrorHandler { + pub fn new(output: ErrorOutputType) -> Self { + let emitter = mk_emitter(output); + Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter) } + } + + pub fn abort_if_errors(&self) { + self.handler.abort_if_errors() + } + + /// Swap out the underlying handler once we acquire the user's preference on error emission + /// format. Any errors prior to that will cause an abort and all stashed diagnostics of the + /// previous handler will be emitted. + pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) { + self.handler.abort_if_errors(); + + let emitter = mk_emitter(output); + self.handler = Handler::with_emitter(true, None, emitter); + } + + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) { + self.handler.struct_note_without_error(msg).emit() + } + + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_help(&self, msg: impl Into<DiagnosticMessage>) { + self.handler.struct_help(msg).emit() + } + + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + #[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"] + pub fn early_error_no_abort(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed { + self.handler.struct_err(msg).emit() + } + + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_error(&self, msg: impl Into<DiagnosticMessage>) -> ! { + self.handler.struct_fatal(msg).emit() + } + + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_warn(&self, msg: impl Into<DiagnosticMessage>) { + self.handler.struct_warn(msg).emit() + } +} + +fn mk_emitter(output: ErrorOutputType) -> Box<dyn Emitter + sync::Send + 'static> { // 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 = @@ -1727,27 +1812,5 @@ fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler TerminalUrl::No, )), }; - rustc_errors::Handler::with_emitter(true, None, emitter) -} - -#[allow(rustc::untranslatable_diagnostic)] -#[allow(rustc::diagnostic_outside_of_impl)] -#[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"] -pub fn early_error_no_abort( - output: config::ErrorOutputType, - msg: impl Into<DiagnosticMessage>, -) -> 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: impl Into<DiagnosticMessage>) -> ! { - 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: impl Into<DiagnosticMessage>) { - early_error_handler(output).struct_warn(msg).emit() + emitter } |