diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
commit | e02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch) | |
tree | fd60ebbbb5299e16e5fca8c773ddb74f764760db /compiler/rustc_session | |
parent | Adding debian version 1.73.0+dfsg1-1. (diff) | |
download | rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_session')
-rw-r--r-- | compiler/rustc_session/messages.ftl | 3 | ||||
-rw-r--r-- | compiler/rustc_session/src/config.rs | 97 | ||||
-rw-r--r-- | compiler/rustc_session/src/cstore.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_session/src/errors.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_session/src/lib.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_session/src/options.rs | 63 | ||||
-rw-r--r-- | compiler/rustc_session/src/output.rs | 19 | ||||
-rw-r--r-- | compiler/rustc_session/src/parse.rs | 17 | ||||
-rw-r--r-- | compiler/rustc_session/src/session.rs | 37 | ||||
-rw-r--r-- | compiler/rustc_session/src/utils.rs | 56 |
10 files changed, 226 insertions, 80 deletions
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index b07c6db59..e06b63809 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -8,6 +8,9 @@ session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible session_cgu_not_recorded = CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded +session_cli_feature_diagnostic_help = + add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable + session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}` session_crate_name_empty = crate name must not be empty diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f00472f18..d29ab02c1 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -381,6 +381,24 @@ pub enum DebugInfo { Full, } +#[derive(Clone, Copy, Debug, PartialEq, Hash)] +pub enum DebugInfoCompression { + None, + Zlib, + Zstd, +} + +impl ToString for DebugInfoCompression { + fn to_string(&self) -> String { + match self { + DebugInfoCompression::None => "none", + DebugInfoCompression::Zlib => "zlib", + DebugInfoCompression::Zstd => "zstd", + } + .to_owned() + } +} + /// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split /// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform /// uses DWARF for debug-information. @@ -880,6 +898,9 @@ impl OutFileName { #[derive(Clone, Hash, Debug, HashStable_Generic)] pub struct OutputFilenames { pub out_directory: PathBuf, + /// Crate name. Never contains '-'. + crate_stem: String, + /// Typically based on `.rs` input file name. Any '-' is preserved. filestem: String, pub single_output_file: Option<OutFileName>, pub temps_directory: Option<PathBuf>, @@ -893,6 +914,7 @@ pub const DWARF_OBJECT_EXT: &str = "dwo"; impl OutputFilenames { pub fn new( out_directory: PathBuf, + out_crate_name: String, out_filestem: String, single_output_file: Option<OutFileName>, temps_directory: Option<PathBuf>, @@ -904,6 +926,7 @@ impl OutputFilenames { single_output_file, temps_directory, outputs, + crate_stem: format!("{out_crate_name}{extra}"), filestem: format!("{out_filestem}{extra}"), } } @@ -920,7 +943,12 @@ impl OutputFilenames { /// should be placed on disk. pub fn output_path(&self, flavor: OutputType) -> PathBuf { let extension = flavor.extension(); - self.with_directory_and_extension(&self.out_directory, extension) + match flavor { + OutputType::Metadata => { + self.out_directory.join(format!("lib{}.{}", self.crate_stem, extension)) + } + _ => self.with_directory_and_extension(&self.out_directory, extension), + } } /// Gets the path where a compilation artifact of the given type for the @@ -1015,6 +1043,7 @@ impl Default for Options { crate_types: Vec::new(), optimize: OptLevel::No, debuginfo: DebugInfo::None, + debuginfo_compression: DebugInfoCompression::None, lint_opts: Vec::new(), lint_cap: None, describe_lints: false, @@ -1067,7 +1096,7 @@ impl Options { /// Returns `true` if there will be an output file generated. pub fn will_create_output_file(&self) -> bool { !self.unstable_opts.parse_only && // The file is just being parsed - !self.unstable_opts.ls // The file is just being queried + self.unstable_opts.ls.is_empty() // The file is just being queried } #[inline] @@ -1084,12 +1113,6 @@ impl Options { pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion { self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy) } - - #[allow(rustc::bad_opt_access)] - pub fn incremental_relative_spans(&self) -> bool { - self.unstable_opts.incremental_relative_spans - || (self.unstable_features.is_nightly_build() && self.incremental.is_some()) - } } impl UnstableOptions { @@ -2160,12 +2183,6 @@ fn collect_print_requests( prints.extend(matches.opt_strs("print").into_iter().map(|req| { let (req, out) = split_out_file_name(&req); - if out.is_some() && !unstable_opts.unstable_options { - handler.early_error( - "the `-Z unstable-options` flag must also be passed to \ - enable the path print option", - ); - } let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) { Some((_, PrintKind::TargetSpec)) => { if unstable_opts.unstable_options { @@ -2283,6 +2300,13 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf if max_g > max_c { DebugInfo::Full } else { cg.debuginfo } } +fn select_debuginfo_compression( + _handler: &EarlyErrorHandler, + unstable_opts: &UnstableOptions, +) -> DebugInfoCompression { + unstable_opts.debuginfo_compression +} + pub(crate) fn parse_assert_incr_state( handler: &EarlyErrorHandler, opt_assertion: &Option<String>, @@ -2451,6 +2475,19 @@ pub fn parse_externs( Some((opts, name)) => (Some(opts), name.to_string()), }; + if !crate::utils::is_ascii_ident(&name) { + let mut error = handler.early_struct_error(format!( + "crate name `{name}` passed to `--extern` is not a valid ASCII identifier" + )); + let adjusted_name = name.replace("-", "_"); + if crate::utils::is_ascii_ident(&adjusted_name) { + error.help(format!( + "consider replacing the dashes with underscores: `{adjusted_name}`" + )); + } + error.emit(); + } + let path = path.map(|p| CanonicalizedPath::new(p)); let entry = externs.entry(name.to_owned()); @@ -2758,6 +2795,8 @@ pub fn build_session_options( // for more details. let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No); let debuginfo = select_debuginfo(matches, &cg); + let debuginfo_compression: DebugInfoCompression = + select_debuginfo_compression(handler, &unstable_opts); let mut search_paths = vec![]; for s in &matches.opt_strs("L") { @@ -2834,6 +2873,7 @@ pub fn build_session_options( crate_types, optimize: opt_level, debuginfo, + debuginfo_compression, lint_opts, lint_cap, describe_lints, @@ -2959,6 +2999,7 @@ pub mod nightly_options { ) { let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options"); let really_allows_unstable_options = match_is_nightly_build(matches); + let mut nightly_options_on_stable = 0; for opt in flags.iter() { if opt.stability == OptionStability::Stable { @@ -2979,20 +3020,27 @@ pub mod nightly_options { } match opt.stability { OptionStability::Unstable => { + nightly_options_on_stable += 1; let msg = format!( "the option `{}` is only accepted on the nightly compiler", opt.name ); let _ = handler.early_error_no_abort(msg); - handler.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>"); - handler.early_help( - "consider switching to a nightly toolchain: `rustup default nightly`", - ); - handler.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>"); } OptionStability::Stable => {} } } + if nightly_options_on_stable > 0 { + handler + .early_help("consider switching to a nightly toolchain: `rustup default nightly`"); + handler.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>"); + handler.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>"); + handler.early_error(format!( + "{} nightly option{} were parsed", + nightly_options_on_stable, + if nightly_options_on_stable > 1 { "s" } else { "" } + )); + } } } @@ -3119,11 +3167,11 @@ impl PpMode { /// how the hash should be calculated when adding a new command-line argument. pub(crate) mod dep_tracking { use super::{ - BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType, - InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, - OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Passes, ResolveDocLinks, - SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, - TraitSolver, TrimmedDefPaths, + BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression, + ErrorOutputType, InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto, + LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, + Passes, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, + SymbolManglingVersion, TraitSolver, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -3201,6 +3249,7 @@ pub(crate) mod dep_tracking { OptLevel, LtoCli, DebugInfo, + DebugInfoCompression, UnstableFeatures, NativeLib, NativeLibKind, diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index c53a355b5..d816842b0 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -7,7 +7,7 @@ use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; use rustc_data_structures::owned_slice::OwnedSlice; -use rustc_data_structures::sync::{self, AppendOnlyIndexVec, RwLock}; +use rustc_data_structures::sync::{self, AppendOnlyIndexVec, FreezeLock}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_span::hygiene::{ExpnHash, ExpnId}; @@ -258,8 +258,8 @@ pub trait CrateStore: std::fmt::Debug { pub type CrateStoreDyn = dyn CrateStore + sync::DynSync + sync::DynSend; pub struct Untracked { - pub cstore: RwLock<Box<CrateStoreDyn>>, + pub cstore: FreezeLock<Box<CrateStoreDyn>>, /// Reference span for definitions. pub source_span: AppendOnlyIndexVec<LocalDefId, Span>, - pub definitions: RwLock<Definitions>, + pub definitions: FreezeLock<Definitions>, } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 78940462b..5f8bbfca8 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -57,6 +57,12 @@ pub struct FeatureDiagnosticHelp { pub feature: Symbol, } +#[derive(Subdiagnostic)] +#[help(session_cli_feature_diagnostic_help)] +pub struct CliFeatureDiagnosticHelp { + pub feature: Symbol, +} + #[derive(Diagnostic)] #[diag(session_not_circumvent_feature)] pub struct NotCircumventFeature; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index a270817f3..d6c746a7b 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -10,7 +10,7 @@ #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -#![cfg_attr(not(bootstrap), allow(internal_features))] +#![allow(internal_features)] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 055ab2d9c..c1424db60 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -20,7 +20,7 @@ use std::collections::BTreeMap; use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; -use std::num::NonZeroUsize; +use std::num::{IntErrorKind, NonZeroUsize}; use std::path::PathBuf; use std::str; @@ -139,6 +139,7 @@ top_level_options!( /// can influence whether overflow checks are done or not. debug_assertions: bool [TRACKED], debuginfo: DebugInfo [TRACKED], + debuginfo_compression: DebugInfoCompression [TRACKED], lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH], lint_cap: Option<lint::Level> [TRACKED_NO_CRATE_HASH], describe_lints: bool [UNTRACKED], @@ -376,6 +377,7 @@ mod desc { "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)"; pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`"; + pub const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; @@ -385,7 +387,7 @@ mod desc { "`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`"; pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; - pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; + pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; pub const parse_trait_solver: &str = "one of the supported solver modes (`classic`, `next`, or `next-coherence`)"; pub const parse_lto: &str = @@ -782,6 +784,19 @@ mod parse { true } + pub(crate) fn parse_debuginfo_compression( + slot: &mut DebugInfoCompression, + v: Option<&str>, + ) -> bool { + match v { + Some("none") => *slot = DebugInfoCompression::None, + Some("zlib") => *slot = DebugInfoCompression::Zlib, + Some("zstd") => *slot = DebugInfoCompression::Zstd, + _ => return false, + }; + true + } + pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool { match v.and_then(LinkerFlavorCli::from_str) { Some(lf) => *slot = Some(lf), @@ -971,10 +986,16 @@ mod parse { pub(crate) fn parse_treat_err_as_bug(slot: &mut Option<NonZeroUsize>, v: Option<&str>) -> bool { match v { - Some(s) => { - *slot = s.parse().ok(); - slot.is_some() - } + Some(s) => match s.parse() { + Ok(val) => { + *slot = Some(val); + true + } + Err(e) => { + *slot = None; + e.kind() == &IntErrorKind::Zero + } + }, None => { *slot = NonZeroUsize::new(1); true @@ -1424,6 +1445,8 @@ options! { "emit discriminators and other data necessary for AutoFDO"), debug_macros: bool = (false, parse_bool, [TRACKED], "emit line numbers debug info inside macros (default: no)"), + debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED], + "compress debug info sections (none, zlib, zstd, default: none)"), deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED], "deduplicate identical diagnostics (default: yes)"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], @@ -1435,17 +1458,11 @@ options! { dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ (default: no)"), - drop_tracking: bool = (false, parse_bool, [TRACKED], - "enables drop tracking in generators (default: no)"), - drop_tracking_mir: bool = (false, parse_bool, [TRACKED], - "enables drop tracking on MIR in generators (default: no)"), dual_proc_macros: bool = (false, parse_bool, [TRACKED], "load proc macros for both target and host, but only link to the target (default: no)"), dump_dep_graph: bool = (false, parse_bool, [UNTRACKED], "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \ (default: no)"), - dump_drop_tracking_cfg: Option<String> = (None, parse_opt_string, [UNTRACKED], - "dump drop-tracking control-flow graph as a `.dot` file (default: no)"), dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED], "dump MIR state to file. `val` is used to select which passes and functions to dump. For example: @@ -1461,15 +1478,12 @@ options! { dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], "exclude the pass number when dumping MIR (used in tests) (default: no)"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], - "in addition to `.mir` files, create graphviz `.dot` files (and with \ - `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived \ - coverage graph) (default: no)"), + "in addition to `.mir` files, create graphviz `.dot` files (default: no)"), dump_mir_spanview: Option<MirSpanview> = (None, parse_mir_spanview, [UNTRACKED], "in addition to `.mir` files, create `.html` files to view spans for \ all `statement`s (including terminators), only `terminator` spans, or \ computed `block` spans (one span encompassing a block's terminator and \ - all statements). If `-Z instrument-coverage` is also enabled, create \ - an additional `.html` file showing the computed coverage spans."), + all statements)."), dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled, parse_switch_with_opt_path, [UNTRACKED], "output statistics about monomorphization collection"), @@ -1519,14 +1533,13 @@ options! { "generate human-readable, predictable names for codegen units (default: no)"), identify_regions: bool = (false, parse_bool, [UNTRACKED], "display unnamed regions as `'<id>`, using a non-ident unique id (default: no)"), + ignore_directory_in_diagnostics_source_blocks: Vec<String> = (Vec::new(), parse_string_push, [UNTRACKED], + "do not display the source code block in diagnostics for files in the directory"), incremental_ignore_spans: bool = (false, parse_bool, [TRACKED], "ignore spans during ICH computation -- used for testing (default: no)"), incremental_info: bool = (false, parse_bool, [UNTRACKED], "print high-level information about incremental reuse (or the lack thereof) \ (default: no)"), - #[rustc_lint_opt_deny_field_access("use `Session::incremental_relative_spans` instead of this field")] - incremental_relative_spans: bool = (false, parse_bool, [TRACKED], - "hash spans relative to their parent item for incr. comp. (default: no)"), incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], "verify incr. comp. hashes of green query instances (default: no)"), inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED], @@ -1580,8 +1593,9 @@ options! { "what location details should be tracked when using caller_location, either \ `none`, or a comma separated list of location details, for which \ valid options are `file`, `line`, and `column` (default: `file,line,column`)"), - ls: bool = (false, parse_bool, [UNTRACKED], - "list the symbols defined by a library crate (default: no)"), + ls: Vec<String> = (Vec::new(), parse_list, [UNTRACKED], + "decode and print various parts of the crate metadata for a library crate \ + (space separated)"), macro_backtrace: bool = (false, parse_bool, [UNTRACKED], "show macro backtraces (default: no)"), maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED], @@ -1631,6 +1645,8 @@ options! { "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], "prevent automatic injection of the profiler_builtins crate"), + no_trait_vptr: bool = (false, parse_no_flag, [TRACKED], + "disable generation of trait vptr in vtable for upcasting"), no_unique_section_names: bool = (false, parse_bool, [TRACKED], "do not use unique names for text and data sections when -Z function-sections is used"), normalize_docs: bool = (false, parse_bool, [TRACKED], @@ -1830,7 +1846,8 @@ written to standard error output)"), trap_unreachable: Option<bool> = (None, parse_opt_bool, [TRACKED], "generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)"), treat_err_as_bug: Option<NonZeroUsize> = (None, parse_treat_err_as_bug, [TRACKED], - "treat error number `val` that occurs as bug"), + "treat the `val`th error that occurs as bug (default if not specified: 0 - don't treat errors as bugs. \ + default if specified without a value: 1 - treat the first error as bug)"), trim_diagnostic_paths: bool = (true, parse_bool, [UNTRACKED], "in diagnostics, use heuristics to shorten paths referring to items"), tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED], diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index c0884fb21..7a57b0621 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -119,26 +119,11 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) { } } -pub fn filename_for_metadata( - sess: &Session, - crate_name: Symbol, - outputs: &OutputFilenames, -) -> OutFileName { - // If the command-line specified the path, use that directly. - if let Some(Some(out_filename)) = sess.opts.output_types.get(&OutputType::Metadata) { - return out_filename.clone(); - } - - let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename); - - let out_filename = outputs.single_output_file.clone().unwrap_or_else(|| { - OutFileName::Real(outputs.out_directory.join(&format!("lib{libname}.rmeta"))) - }); - +pub fn filename_for_metadata(sess: &Session, outputs: &OutputFilenames) -> OutFileName { + let out_filename = outputs.path(OutputType::Metadata); if let OutFileName::Real(ref path) = out_filename { check_file_is_writeable(path, sess); } - out_filename } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 1cf63e9b7..671204c0d 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -2,7 +2,9 @@ //! It also serves as an input to the parser itself. use crate::config::CheckCfg; -use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError}; +use crate::errors::{ + CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError, +}; use crate::lint::{ builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId, }; @@ -110,7 +112,7 @@ pub fn feature_err_issue( } let mut err = sess.create_err(FeatureGateError { span, explain: explain.into() }); - add_feature_diagnostics_for_issue(&mut err, sess, feature, issue); + add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false); err } @@ -139,7 +141,7 @@ pub fn feature_warn_issue( explain: &'static str, ) { let mut err = sess.span_diagnostic.struct_span_warn(span, explain); - add_feature_diagnostics_for_issue(&mut err, sess, feature, issue); + add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false); // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level let lint = UNSTABLE_SYNTAX_PRE_EXPANSION; @@ -158,7 +160,7 @@ pub fn feature_warn_issue( /// Adds the diagnostics for a feature to an existing error. pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) { - add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language); + add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false); } /// Adds the diagnostics for a feature to an existing error. @@ -171,6 +173,7 @@ pub fn add_feature_diagnostics_for_issue( sess: &ParseSess, feature: Symbol, issue: GateIssue, + feature_from_cli: bool, ) { if let Some(n) = find_feature_issue(feature, issue) { err.subdiagnostic(FeatureDiagnosticForIssue { n }); @@ -178,7 +181,11 @@ pub fn add_feature_diagnostics_for_issue( // #23973: do not suggest `#![feature(...)]` if we are in beta/stable if sess.unstable_features.is_nightly_build() { - err.subdiagnostic(FeatureDiagnosticHelp { feature }); + if feature_from_cli { + err.subdiagnostic(CliFeatureDiagnosticHelp { feature }); + } else { + err.subdiagnostic(FeatureDiagnosticHelp { feature }); + } } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 086ce4e69..b484978ee 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -17,10 +17,10 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::jobserver::{self, Client}; use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{ - self, AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst, + AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst, }; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter; -use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; +use rustc_errors::emitter::{DynEmitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ @@ -204,6 +204,12 @@ pub struct Session { /// The version of the rustc process, possibly including a commit hash and description. pub cfg_version: &'static str, + + /// All commandline args used to invoke the compiler, with @file args fully expanded. + /// This will only be used within debug info, e.g. in the pdb file on windows + /// This is mainly useful for other tools that reads that debuginfo to figure out + /// how to call the compiler with the same arguments. + pub expanded_args: Vec<String>, } pub struct PerfStats { @@ -1251,7 +1257,7 @@ fn default_emitter( source_map: Lrc<SourceMap>, bundle: Option<Lrc<FluentBundle>>, fallback_bundle: LazyFallbackBundle, -) -> Box<dyn Emitter + sync::Send> { +) -> Box<DynEmitter> { 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 { @@ -1289,7 +1295,10 @@ fn default_emitter( .diagnostic_width(sopts.diagnostic_width) .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) - .terminal_url(terminal_url); + .terminal_url(terminal_url) + .ignored_directories_in_source_blocks( + sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), + ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } } @@ -1306,7 +1315,10 @@ fn default_emitter( track_diagnostics, terminal_url, ) - .ui_testing(sopts.unstable_opts.ui_testing), + .ui_testing(sopts.unstable_opts.ui_testing) + .ignored_directories_in_source_blocks( + sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), + ), ), } } @@ -1325,6 +1337,7 @@ pub fn build_session( target_override: Option<Target>, cfg_version: &'static str, ice_file: Option<PathBuf>, + expanded_args: Vec<String>, ) -> Session { // FIXME: This is not general enough to make the warning lint completely override // normal diagnostic warnings, since the warning lint can also be denied and changed @@ -1467,6 +1480,7 @@ pub fn build_session( target_features: Default::default(), unstable_target_features: Default::default(), cfg_version, + expanded_args, }; validate_commandline_args_with_session_available(&sess); @@ -1712,17 +1726,26 @@ impl EarlyErrorHandler { #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] + pub(crate) fn early_struct_error( + &self, + msg: impl Into<DiagnosticMessage>, + ) -> DiagnosticBuilder<'_, !> { + self.handler.struct_fatal(msg) + } + + #[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> { +fn mk_emitter(output: ErrorOutputType) -> Box<DynEmitter> { // 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 { + let emitter: Box<DynEmitter> = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); Box::new(EmitterWriter::stderr(color_config, fallback_bundle).short_message(short)) diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 71f2591fe..aea7c6c28 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -111,3 +111,59 @@ impl CanonicalizedPath { &self.original } } + +/// Gets a list of extra command-line flags provided by the user, as strings. +/// +/// This function is used during ICEs to show more information useful for +/// debugging, since some ICEs only happens with non-default compiler flags +/// (and the users don't always report them). +pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> { + const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"]; + + const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"]; + + const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"]; + + let mut args = std::env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable(); + + let mut result = Vec::new(); + let mut excluded_cargo_defaults = false; + while let Some(arg) = args.next() { + if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) { + let content = if arg.len() == a.len() { + // A space-separated option, like `-C incremental=foo` or `--crate-type rlib` + match args.next() { + Some(arg) => arg.to_string(), + None => continue, + } + } else if arg.get(a.len()..a.len() + 1) == Some("=") { + // An equals option, like `--crate-type=rlib` + arg[a.len() + 1..].to_string() + } else { + // A non-space option, like `-Cincremental=foo` + arg[a.len()..].to_string() + }; + let option = content.split_once('=').map(|s| s.0).unwrap_or(&content); + if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) { + excluded_cargo_defaults = true; + } else { + result.push(a.to_string()); + match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) { + Some(s) => result.push(format!("{s}=[REDACTED]")), + None => result.push(content), + } + } + } + } + + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } +} + +pub(crate) fn is_ascii_ident(string: &str) -> bool { + let mut chars = string.chars(); + if let Some(start) = chars.next() && (start.is_ascii_alphabetic() || start == '_') { + chars.all(|char| char.is_ascii_alphanumeric() || char == '_') + } else { + false + } +} |