summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_session
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.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.ftl3
-rw-r--r--compiler/rustc_session/src/config.rs97
-rw-r--r--compiler/rustc_session/src/cstore.rs6
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/options.rs63
-rw-r--r--compiler/rustc_session/src/output.rs19
-rw-r--r--compiler/rustc_session/src/parse.rs17
-rw-r--r--compiler/rustc_session/src/session.rs37
-rw-r--r--compiler/rustc_session/src/utils.rs56
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
+ }
+}