summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_session/src
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r--compiler/rustc_session/src/cgu_reuse_tracker.rs136
-rw-r--r--compiler/rustc_session/src/code_stats.rs16
-rw-r--r--compiler/rustc_session/src/config.rs395
-rw-r--r--compiler/rustc_session/src/errors.rs19
-rw-r--r--compiler/rustc_session/src/lib.rs5
-rw-r--r--compiler/rustc_session/src/options.rs141
-rw-r--r--compiler/rustc_session/src/output.rs8
-rw-r--r--compiler/rustc_session/src/parse.rs21
-rw-r--r--compiler/rustc_session/src/session.rs135
-rw-r--r--compiler/rustc_session/src/utils.rs4
-rw-r--r--compiler/rustc_session/src/version.rs19
11 files changed, 473 insertions, 426 deletions
diff --git a/compiler/rustc_session/src/cgu_reuse_tracker.rs b/compiler/rustc_session/src/cgu_reuse_tracker.rs
deleted file mode 100644
index 8703e5754..000000000
--- a/compiler/rustc_session/src/cgu_reuse_tracker.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-//! Some facilities for tracking how codegen-units are reused during incremental
-//! compilation. This is used for incremental compilation tests and debug
-//! output.
-
-use crate::errors::{CguNotRecorded, IncorrectCguReuseType};
-use crate::Session;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
-use rustc_span::{Span, Symbol};
-use std::borrow::Cow;
-use std::fmt::{self};
-use std::sync::{Arc, Mutex};
-
-#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
-pub enum CguReuse {
- No,
- PreLto,
- PostLto,
-}
-
-impl fmt::Display for CguReuse {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match *self {
- CguReuse::No => write!(f, "No"),
- CguReuse::PreLto => write!(f, "PreLto "),
- CguReuse::PostLto => write!(f, "PostLto "),
- }
- }
-}
-
-impl IntoDiagnosticArg for CguReuse {
- fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
- DiagnosticArgValue::Str(Cow::Owned(self.to_string()))
- }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum ComparisonKind {
- Exact,
- AtLeast,
-}
-
-struct TrackerData {
- actual_reuse: FxHashMap<String, CguReuse>,
- expected_reuse: FxHashMap<String, (String, SendSpan, CguReuse, ComparisonKind)>,
-}
-
-// Span does not implement `Send`, so we can't just store it in the shared
-// `TrackerData` object. Instead of splitting up `TrackerData` into shared and
-// non-shared parts (which would be complicated), we just mark the `Span` here
-// explicitly as `Send`. That's safe because the span data here is only ever
-// accessed from the main thread.
-struct SendSpan(Span);
-unsafe impl Send for SendSpan {}
-
-#[derive(Clone)]
-pub struct CguReuseTracker {
- data: Option<Arc<Mutex<TrackerData>>>,
-}
-
-impl CguReuseTracker {
- pub fn new() -> CguReuseTracker {
- let data =
- TrackerData { actual_reuse: Default::default(), expected_reuse: Default::default() };
-
- CguReuseTracker { data: Some(Arc::new(Mutex::new(data))) }
- }
-
- pub fn new_disabled() -> CguReuseTracker {
- CguReuseTracker { data: None }
- }
-
- pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) {
- if let Some(ref data) = self.data {
- debug!("set_actual_reuse({cgu_name:?}, {kind:?})");
-
- let prev_reuse = data.lock().unwrap().actual_reuse.insert(cgu_name.to_string(), kind);
-
- if let Some(prev_reuse) = prev_reuse {
- // The only time it is legal to overwrite reuse state is when
- // we discover during ThinLTO that we can actually reuse the
- // post-LTO version of a CGU.
- assert_eq!(prev_reuse, CguReuse::PreLto);
- }
- }
- }
-
- pub fn set_expectation(
- &self,
- cgu_name: Symbol,
- cgu_user_name: &str,
- error_span: Span,
- expected_reuse: CguReuse,
- comparison_kind: ComparisonKind,
- ) {
- if let Some(ref data) = self.data {
- debug!("set_expectation({cgu_name:?}, {expected_reuse:?}, {comparison_kind:?})");
- let mut data = data.lock().unwrap();
-
- data.expected_reuse.insert(
- cgu_name.to_string(),
- (cgu_user_name.to_string(), SendSpan(error_span), expected_reuse, comparison_kind),
- );
- }
- }
-
- pub fn check_expected_reuse(&self, sess: &Session) {
- if let Some(ref data) = self.data {
- let data = data.lock().unwrap();
-
- for (cgu_name, &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind)) in
- &data.expected_reuse
- {
- if let Some(&actual_reuse) = data.actual_reuse.get(cgu_name) {
- let (error, at_least) = match comparison_kind {
- ComparisonKind::Exact => (expected_reuse != actual_reuse, false),
- ComparisonKind::AtLeast => (actual_reuse < expected_reuse, true),
- };
-
- if error {
- let at_least = if at_least { 1 } else { 0 };
- IncorrectCguReuseType {
- span: error_span.0,
- cgu_user_name,
- actual_reuse,
- expected_reuse,
- at_least,
- };
- }
- } else {
- sess.emit_fatal(CguNotRecorded { cgu_user_name, cgu_name });
- }
- }
- }
- }
-}
diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index df81e1f83..e1eb58fec 100644
--- a/compiler/rustc_session/src/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
@@ -24,7 +24,7 @@ pub enum SizeKind {
pub enum FieldKind {
AdtField,
Upvar,
- GeneratorLocal,
+ CoroutineLocal,
}
impl std::fmt::Display for FieldKind {
@@ -32,7 +32,7 @@ impl std::fmt::Display for FieldKind {
match self {
FieldKind::AdtField => write!(w, "field"),
FieldKind::Upvar => write!(w, "upvar"),
- FieldKind::GeneratorLocal => write!(w, "local"),
+ FieldKind::CoroutineLocal => write!(w, "local"),
}
}
}
@@ -52,7 +52,7 @@ pub enum DataTypeKind {
Union,
Enum,
Closure,
- Generator,
+ Coroutine,
}
#[derive(PartialEq, Eq, Hash, Debug)]
@@ -105,9 +105,9 @@ impl CodeStats {
// Sort variants so the largest ones are shown first. A stable sort is
// used here so that source code order is preserved for all variants
// that have the same size.
- // Except for Generators, whose variants are already sorted according to
- // their yield points in `variant_info_for_generator`.
- if kind != DataTypeKind::Generator {
+ // Except for Coroutines, whose variants are already sorted according to
+ // their yield points in `variant_info_for_coroutine`.
+ if kind != DataTypeKind::Coroutine {
variants.sort_by_key(|info| cmp::Reverse(info.size));
}
let info = TypeSizeInfo {
@@ -160,7 +160,7 @@ impl CodeStats {
let struct_like = match kind {
DataTypeKind::Struct | DataTypeKind::Closure => true,
- DataTypeKind::Enum | DataTypeKind::Union | DataTypeKind::Generator => false,
+ DataTypeKind::Enum | DataTypeKind::Union | DataTypeKind::Coroutine => false,
};
for (i, variant_info) in variants.into_iter().enumerate() {
let VariantInfo { ref name, kind: _, align: _, size, ref fields } = *variant_info;
@@ -226,7 +226,7 @@ impl CodeStats {
}
}
- pub fn print_vtable_sizes(&self, crate_name: &str) {
+ pub fn print_vtable_sizes(&self, crate_name: Symbol) {
let mut infos =
std::mem::take(&mut *self.vtable_sizes.lock()).into_values().collect::<Vec<_>>();
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d29ab02c1..f745bc390 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -9,19 +9,18 @@ use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{lint, HashStableContext};
use crate::{EarlyErrorHandler, Session};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
use rustc_target::abi::Align;
+use rustc_target::spec::LinkSelfContainedComponents;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
-use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
-use rustc_span::source_map::{FileName, FilePathMapping};
+use rustc_span::source_map::FilePathMapping;
use rustc_span::symbol::{sym, Symbol};
-use rustc_span::RealFileName;
-use rustc_span::SourceFileHashAlgorithm;
+use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg};
@@ -168,6 +167,9 @@ pub enum MirSpanview {
pub enum InstrumentCoverage {
/// Default `-C instrument-coverage` or `-C instrument-coverage=statement`
All,
+ /// Additionally, instrument branches and output branch coverage.
+ /// `-Zunstable-options -C instrument-coverage=branch`
+ Branch,
/// `-Zunstable-options -C instrument-coverage=except-unused-generics`
ExceptUnusedGenerics,
/// `-Zunstable-options -C instrument-coverage=except-unused-functions`
@@ -232,63 +234,35 @@ pub struct LinkSelfContained {
/// Used for compatibility with the existing opt-in and target inference.
pub explicitly_set: Option<bool>,
- /// The components that are enabled.
- components: LinkSelfContainedComponents,
-}
-
-bitflags::bitflags! {
- #[derive(Default)]
- /// The `-C link-self-contained` components that can individually be enabled or disabled.
- pub struct LinkSelfContainedComponents: u8 {
- /// CRT objects (e.g. on `windows-gnu`, `musl`, `wasi` targets)
- const CRT_OBJECTS = 1 << 0;
- /// libc static library (e.g. on `musl`, `wasi` targets)
- const LIBC = 1 << 1;
- /// libgcc/libunwind (e.g. on `windows-gnu`, `fuchsia`, `fortanix`, `gnullvm` targets)
- const UNWIND = 1 << 2;
- /// Linker, dlltool, and their necessary libraries (e.g. on `windows-gnu` and for `rust-lld`)
- const LINKER = 1 << 3;
- /// Sanitizer runtime libraries
- const SANITIZERS = 1 << 4;
- /// Other MinGW libs and Windows import libs
- const MINGW = 1 << 5;
- }
-}
-
-impl FromStr for LinkSelfContainedComponents {
- type Err = ();
+ /// The components that are enabled on the CLI, using the `+component` syntax or one of the
+ /// `true` shorcuts.
+ enabled_components: LinkSelfContainedComponents,
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(match s {
- "crto" => LinkSelfContainedComponents::CRT_OBJECTS,
- "libc" => LinkSelfContainedComponents::LIBC,
- "unwind" => LinkSelfContainedComponents::UNWIND,
- "linker" => LinkSelfContainedComponents::LINKER,
- "sanitizers" => LinkSelfContainedComponents::SANITIZERS,
- "mingw" => LinkSelfContainedComponents::MINGW,
- _ => return Err(()),
- })
- }
+ /// The components that are disabled on the CLI, using the `-component` syntax or one of the
+ /// `false` shortcuts.
+ disabled_components: LinkSelfContainedComponents,
}
impl LinkSelfContained {
/// Incorporates an enabled or disabled component as specified on the CLI, if possible.
/// For example: `+linker`, and `-crto`.
- pub(crate) fn handle_cli_component(&mut self, component: &str) -> Result<(), ()> {
+ pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
// Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
// set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
// set in bulk with its historical values, then manually setting a component clears that
// `explicitly_set` state.
if let Some(component_to_enable) = component.strip_prefix('+') {
self.explicitly_set = None;
- self.components.insert(component_to_enable.parse()?);
- Ok(())
+ self.enabled_components
+ .insert(LinkSelfContainedComponents::from_str(component_to_enable)?);
+ Some(())
} else if let Some(component_to_disable) = component.strip_prefix('-') {
self.explicitly_set = None;
- self.components.remove(component_to_disable.parse()?);
- Ok(())
+ self.disabled_components
+ .insert(LinkSelfContainedComponents::from_str(component_to_disable)?);
+ Some(())
} else {
- Err(())
+ None
}
}
@@ -296,11 +270,14 @@ impl LinkSelfContained {
/// purposes.
pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
self.explicitly_set = Some(enabled);
- self.components = if enabled {
- LinkSelfContainedComponents::all()
+
+ if enabled {
+ self.enabled_components = LinkSelfContainedComponents::all();
+ self.disabled_components = LinkSelfContainedComponents::empty();
} else {
- LinkSelfContainedComponents::empty()
- };
+ self.enabled_components = LinkSelfContainedComponents::empty();
+ self.disabled_components = LinkSelfContainedComponents::all();
+ }
}
/// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
@@ -314,13 +291,32 @@ impl LinkSelfContained {
/// components was set individually. This would also require the `-Zunstable-options` flag, to
/// be allowed.
fn are_unstable_variants_set(&self) -> bool {
- let any_component_set = !self.components.is_empty();
+ let any_component_set =
+ !self.enabled_components.is_empty() || !self.disabled_components.is_empty();
self.explicitly_set.is_none() && any_component_set
}
- /// Returns whether the self-contained linker component is enabled.
- pub fn linker(&self) -> bool {
- self.components.contains(LinkSelfContainedComponents::LINKER)
+ /// Returns whether the self-contained linker component was enabled on the CLI, using the
+ /// `-C link-self-contained=+linker` syntax, or one of the `true` shorcuts.
+ pub fn is_linker_enabled(&self) -> bool {
+ self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
+ }
+
+ /// Returns whether the self-contained linker component was disabled on the CLI, using the
+ /// `-C link-self-contained=-linker` syntax, or one of the `false` shorcuts.
+ pub fn is_linker_disabled(&self) -> bool {
+ self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
+ }
+
+ /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
+ /// disabled.
+ fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
+ if self.explicitly_set.is_some() {
+ None
+ } else {
+ let common = self.enabled_components.intersection(self.disabled_components);
+ if common.is_empty() { None } else { Some(common) }
+ }
}
}
@@ -813,7 +809,6 @@ impl Input {
FileName::Anon(_) => None,
FileName::MacroExpansion(_) => None,
FileName::ProcMacroSourceCode(_) => None,
- FileName::CfgSpec(_) => None,
FileName::CliCrateAttr(_) => None,
FileName::Custom(_) => None,
FileName::DocTest(path, _) => Some(path),
@@ -1024,6 +1019,32 @@ impl OutputFilenames {
}
}
+bitflags::bitflags! {
+ /// Scopes used to determined if it need to apply to --remap-path-prefix
+ pub struct RemapPathScopeComponents: u8 {
+ /// Apply remappings to the expansion of std::file!() macro
+ const MACRO = 1 << 0;
+ /// Apply remappings to printed compiler diagnostics
+ const DIAGNOSTICS = 1 << 1;
+ /// Apply remappings to debug information only when they are written to
+ /// compiled executables or libraries, but not when they are in split
+ /// debuginfo files
+ const UNSPLIT_DEBUGINFO = 1 << 2;
+ /// Apply remappings to debug information only when they are written to
+ /// split debug information files, but not in compiled executables or
+ /// libraries
+ const SPLIT_DEBUGINFO = 1 << 3;
+ /// Apply remappings to the paths pointing to split debug information
+ /// files. Does nothing when these files are not generated.
+ const SPLIT_DEBUGINFO_PATH = 1 << 4;
+
+ /// An alias for macro,unsplit-debuginfo,split-debuginfo-path. This
+ /// ensures all paths in compiled executables or libraries are remapped
+ /// but not elsewhere.
+ const OBJECT = Self::MACRO.bits | Self::UNSPLIT_DEBUGINFO.bits | Self::SPLIT_DEBUGINFO_PATH.bits;
+ }
+}
+
pub fn host_triple() -> &'static str {
// Get the host triple out of the build environment. This ensures that our
// idea of the host triple is the same as for the set of libraries we've
@@ -1036,6 +1057,22 @@ pub fn host_triple() -> &'static str {
(option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
}
+fn file_path_mapping(
+ remap_path_prefix: Vec<(PathBuf, PathBuf)>,
+ unstable_opts: &UnstableOptions,
+) -> FilePathMapping {
+ FilePathMapping::new(
+ remap_path_prefix.clone(),
+ if unstable_opts.remap_path_scope.contains(RemapPathScopeComponents::DIAGNOSTICS)
+ && !remap_path_prefix.is_empty()
+ {
+ FileNameDisplayPreference::Remapped
+ } else {
+ FileNameDisplayPreference::Local
+ },
+ )
+}
+
impl Default for Options {
fn default() -> Options {
Options {
@@ -1053,6 +1090,7 @@ impl Default for Options {
target_triple: TargetTriple::from_triple(host_triple()),
test: false,
incremental: None,
+ untracked_state_hash: Default::default(),
unstable_opts: Default::default(),
prints: Vec::new(),
cg: Default::default(),
@@ -1090,7 +1128,7 @@ impl Options {
}
pub fn file_path_mapping(&self) -> FilePathMapping {
- FilePathMapping::new(self.remap_path_prefix.clone())
+ file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
}
/// Returns `true` if there will be an output file generated.
@@ -1208,8 +1246,8 @@ pub const fn default_lib_output() -> CrateType {
CrateType::Rlib
}
-fn default_configuration(sess: &Session) -> CrateConfig {
- // NOTE: This should be kept in sync with `CrateCheckConfig::fill_well_known` below.
+fn default_configuration(sess: &Session) -> Cfg {
+ // NOTE: This should be kept in sync with `CheckCfg::fill_well_known` below.
let end = &sess.target.endian;
let arch = &sess.target.arch;
let wordsz = sess.target.pointer_width.to_string();
@@ -1225,7 +1263,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
sess.emit_fatal(err);
});
- let mut ret = CrateConfig::default();
+ let mut ret = Cfg::default();
ret.reserve(7); // the minimum number of insertions
// Target bindings.
ret.insert((sym::target_os, Some(Symbol::intern(os))));
@@ -1318,55 +1356,22 @@ fn default_configuration(sess: &Session) -> CrateConfig {
ret
}
-/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
-/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
-/// but the symbol interner is not yet set up then, so we must convert it later.
-pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig {
- cfg.into_iter().map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b)))).collect()
-}
+/// The parsed `--cfg` options that define the compilation environment of the
+/// crate, used to drive conditional compilation.
+///
+/// An `FxIndexSet` is used to ensure deterministic ordering of error messages
+/// relating to `--cfg`.
+pub type Cfg = FxIndexSet<(Symbol, Option<Symbol>)>;
-/// The parsed `--check-cfg` options
-pub struct CheckCfg<T = String> {
+/// The parsed `--check-cfg` options.
+#[derive(Default)]
+pub struct CheckCfg {
/// Is well known names activated
pub exhaustive_names: bool,
/// Is well known values activated
pub exhaustive_values: bool,
/// All the expected values for a config name
- pub expecteds: FxHashMap<T, ExpectedValues<T>>,
-}
-
-impl<T> Default for CheckCfg<T> {
- fn default() -> Self {
- CheckCfg {
- exhaustive_names: false,
- exhaustive_values: false,
- expecteds: FxHashMap::default(),
- }
- }
-}
-
-impl<T> CheckCfg<T> {
- fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> {
- CheckCfg {
- exhaustive_names: self.exhaustive_names,
- exhaustive_values: self.exhaustive_values,
- expecteds: self
- .expecteds
- .into_iter()
- .map(|(name, values)| {
- (
- f(name),
- match values {
- ExpectedValues::Some(values) => ExpectedValues::Some(
- values.into_iter().map(|b| b.map(|b| f(b))).collect(),
- ),
- ExpectedValues::Any => ExpectedValues::Any,
- },
- )
- })
- .collect(),
- }
- }
+ pub expecteds: FxHashMap<Symbol, ExpectedValues<Symbol>>,
}
pub enum ExpectedValues<T> {
@@ -1401,14 +1406,7 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
}
}
-/// Converts the crate `--check-cfg` options from `String` to `Symbol`.
-/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
-/// but the symbol interner is not yet set up then, so we must convert it later.
-pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
- cfg.map_data(|s| Symbol::intern(&s))
-}
-
-impl CrateCheckConfig {
+impl CheckCfg {
pub fn fill_well_known(&mut self, current_target: &Target) {
if !self.exhaustive_values && !self.exhaustive_names {
return;
@@ -1548,7 +1546,7 @@ impl CrateCheckConfig {
}
}
-pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
+pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
// Combine the configuration requested by the session (command line) with
// some default and generated configuration items.
let default_cfg = default_configuration(sess);
@@ -2479,7 +2477,7 @@ pub fn parse_externs(
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("-", "_");
+ let adjusted_name = name.replace('-', "_");
if crate::utils::is_ascii_ident(&adjusted_name) {
error.help(format!(
"consider replacing the dashes with underscores: `{adjusted_name}`"
@@ -2675,53 +2673,40 @@ pub fn build_session_options(
);
}
- // Handle both `-Z symbol-mangling-version` and `-C symbol-mangling-version`; the latter takes
- // precedence.
- match (cg.symbol_mangling_version, unstable_opts.symbol_mangling_version) {
- (Some(smv_c), Some(smv_z)) if smv_c != smv_z => {
- handler.early_error(
- "incompatible values passed for `-C symbol-mangling-version` \
- and `-Z symbol-mangling-version`",
- );
- }
- (Some(SymbolManglingVersion::V0), _) => {}
- (Some(_), _) if !unstable_opts.unstable_options => {
- handler
- .early_error("`-C symbol-mangling-version=legacy` requires `-Z unstable-options`");
- }
- (None, None) => {}
- (None, smv) => {
- handler.early_warn(
- "`-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`",
- );
- cg.symbol_mangling_version = smv;
+ // Check for unstable values of `-C symbol-mangling-version`.
+ // This is what prevents them from being used on stable compilers.
+ match cg.symbol_mangling_version {
+ // Stable values:
+ None | Some(SymbolManglingVersion::V0) => {}
+ // Unstable values:
+ Some(SymbolManglingVersion::Legacy) => {
+ if !unstable_opts.unstable_options {
+ handler.early_error(
+ "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
+ );
+ }
}
- _ => {}
}
- // Handle both `-Z instrument-coverage` and `-C instrument-coverage`; the latter takes
- // precedence.
- match (cg.instrument_coverage, unstable_opts.instrument_coverage) {
- (Some(ic_c), Some(ic_z)) if ic_c != ic_z => {
- handler.early_error(
- "incompatible values passed for `-C instrument-coverage` \
- and `-Z instrument-coverage`",
- );
- }
- (Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
- (Some(_), _) if !unstable_opts.unstable_options => {
- handler.early_error("`-C instrument-coverage=except-*` requires `-Z unstable-options`");
- }
- (None, None) => {}
- (None, ic) => {
- handler
- .early_warn("`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`");
- cg.instrument_coverage = ic;
+ // Check for unstable values of `-C instrument-coverage`.
+ // This is what prevents them from being used on stable compilers.
+ match cg.instrument_coverage {
+ // Stable values:
+ InstrumentCoverage::All | InstrumentCoverage::Off => {}
+ // Unstable values:
+ InstrumentCoverage::Branch
+ | InstrumentCoverage::ExceptUnusedFunctions
+ | InstrumentCoverage::ExceptUnusedGenerics => {
+ if !unstable_opts.unstable_options {
+ handler.early_error(
+ "`-C instrument-coverage=branch` and `-C instrument-coverage=except-*` \
+ require `-Z unstable-options`",
+ );
+ }
}
- _ => {}
}
- if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) {
+ if cg.instrument_coverage != InstrumentCoverage::Off {
if cg.profile_generate.enabled() || cg.profile_use.is_some() {
handler.early_error(
"option `-C instrument-coverage` is not compatible with either `-C profile-use` \
@@ -2759,9 +2744,8 @@ pub fn build_session_options(
}
// For testing purposes, until we have more feedback about these options: ensure `-Z
- // unstable-options` is required when using the unstable `-C link-self-contained` options, like
- // `-C link-self-contained=+linker`, and when using the unstable `-C linker-flavor` options, like
- // `-C linker-flavor=gnu-lld-cc`.
+ // unstable-options` is required when using the unstable `-C link-self-contained` and `-C
+ // linker-flavor` options.
if !nightly_options::is_unstable_enabled(matches) {
let uses_unstable_self_contained_option =
cg.link_self_contained.are_unstable_variants_set();
@@ -2783,6 +2767,19 @@ pub fn build_session_options(
}
}
+ // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
+ // and disabled at the same time.
+ if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
+ let names: String = erroneous_components
+ .into_iter()
+ .map(|c| c.as_str().unwrap())
+ .intersperse(", ")
+ .collect();
+ handler.early_error(format!(
+ "some `-C link-self-contained` components were both enabled and disabled: {names}"
+ ));
+ }
+
let prints = collect_print_requests(handler, &mut cg, &mut unstable_opts, matches);
let cg = cg;
@@ -2860,7 +2857,7 @@ pub fn build_session_options(
handler.early_error(format!("Current directory is invalid: {e}"));
});
- let remap = FilePathMapping::new(remap_path_prefix.clone());
+ let remap = file_path_mapping(remap_path_prefix.clone(), &unstable_opts);
let (path, remapped) = remap.map_prefix(&working_dir);
let working_dir = if remapped {
RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) }
@@ -2883,6 +2880,7 @@ pub fn build_session_options(
target_triple,
test,
incremental,
+ untracked_state_hash: Default::default(),
unstable_opts,
prints,
cg,
@@ -2919,8 +2917,8 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) ->
"expanded" => Source(PpSourceMode::Expanded),
"expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
"expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
- "ast-tree" => AstTree(PpAstTreeMode::Normal),
- "ast-tree,expanded" => AstTree(PpAstTreeMode::Expanded),
+ "ast-tree" => AstTree,
+ "ast-tree,expanded" => AstTreeExpanded,
"hir" => Hir(PpHirMode::Normal),
"hir,identified" => Hir(PpHirMode::Identified),
"hir,typed" => Hir(PpHirMode::Typed),
@@ -3078,14 +3076,6 @@ pub enum PpSourceMode {
}
#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum PpAstTreeMode {
- /// `-Zunpretty=ast`
- Normal,
- /// `-Zunpretty=ast,expanded`
- Expanded,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpHirMode {
/// `-Zunpretty=hir`
Normal,
@@ -3100,7 +3090,10 @@ pub enum PpMode {
/// Options that print the source code, i.e.
/// `-Zunpretty=normal` and `-Zunpretty=expanded`
Source(PpSourceMode),
- AstTree(PpAstTreeMode),
+ /// `-Zunpretty=ast-tree`
+ AstTree,
+ /// `-Zunpretty=ast-tree,expanded`
+ AstTreeExpanded,
/// Options that print the HIR, i.e. `-Zunpretty=hir`
Hir(PpHirMode),
/// `-Zunpretty=hir-tree`
@@ -3120,10 +3113,10 @@ impl PpMode {
use PpMode::*;
use PpSourceMode::*;
match *self {
- Source(Normal | Identified) | AstTree(PpAstTreeMode::Normal) => false,
+ Source(Normal | Identified) | AstTree => false,
Source(Expanded | ExpandedIdentified | ExpandedHygiene)
- | AstTree(PpAstTreeMode::Expanded)
+ | AstTreeExpanded
| Hir(_)
| HirTree
| ThirTree
@@ -3135,7 +3128,7 @@ impl PpMode {
pub fn needs_hir(&self) -> bool {
use PpMode::*;
match *self {
- Source(_) | AstTree(_) => false,
+ Source(_) | AstTree | AstTreeExpanded => false,
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
}
@@ -3143,7 +3136,7 @@ impl PpMode {
pub fn needs_analysis(&self) -> bool {
use PpMode::*;
- matches!(*self, Mir | MirCFG | ThirTree | ThirFlat)
+ matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat)
}
}
@@ -3168,14 +3161,15 @@ impl PpMode {
pub(crate) mod dep_tracking {
use super::{
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
- ErrorOutputType, InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto,
+ ErrorOutputType, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
- Passes, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
- SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
+ Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
+ SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
- use crate::utils::{NativeLib, NativeLibKind};
+ use crate::utils::NativeLib;
+ use rustc_data_structures::stable_hasher::Hash64;
use rustc_errors::LanguageIdentifier;
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
@@ -3231,6 +3225,7 @@ pub(crate) mod dep_tracking {
usize,
NonZeroUsize,
u64,
+ Hash64,
String,
PathBuf,
lint::Level,
@@ -3245,14 +3240,12 @@ pub(crate) mod dep_tracking {
MergeFunctions,
PanicStrategy,
RelroLevel,
- Passes,
OptLevel,
LtoCli,
DebugInfo,
DebugInfoCompression,
UnstableFeatures,
NativeLib,
- NativeLibKind,
SanitizerSet,
CFGuard,
CFProtection,
@@ -3265,9 +3258,9 @@ pub(crate) mod dep_tracking {
StackProtector,
SwitchWithOptPath,
SymbolManglingVersion,
+ RemapPathScopeComponents,
SourceFileHashAlgorithm,
TrimmedDefPaths,
- Option<LdImpl>,
OutFileName,
OutputType,
RealFileName,
@@ -3276,6 +3269,8 @@ pub(crate) mod dep_tracking {
OomStrategy,
LanguageIdentifier,
TraitSolver,
+ Polonius,
+ InliningThreshold,
);
impl<T1, T2> DepTrackingHash for (T1, T2)
@@ -3414,3 +3409,43 @@ impl DumpMonoStatsFormat {
}
}
}
+
+/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
+/// or future prototype.
+#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
+pub enum Polonius {
+ /// The default value: disabled.
+ #[default]
+ Off,
+
+ /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
+ Legacy,
+
+ /// In-tree prototype, extending the NLL infrastructure.
+ Next,
+}
+
+impl Polonius {
+ /// Returns whether the legacy version of polonius is enabled
+ pub fn is_legacy_enabled(&self) -> bool {
+ matches!(self, Polonius::Legacy)
+ }
+
+ /// Returns whether the "next" version of polonius is enabled
+ pub fn is_next_enabled(&self) -> bool {
+ matches!(self, Polonius::Next)
+ }
+}
+
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum InliningThreshold {
+ Always,
+ Sometimes(usize),
+ Never,
+}
+
+impl Default for InliningThreshold {
+ fn default() -> Self {
+ Self::Sometimes(100)
+ }
+}
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 5f8bbfca8..31094e0d2 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -1,6 +1,5 @@
use std::num::NonZeroU32;
-use crate::cgu_reuse_tracker::CguReuse;
use crate::parse::ParseSess;
use rustc_ast::token;
use rustc_ast::util::literal::LitError;
@@ -9,24 +8,6 @@ use rustc_macros::Diagnostic;
use rustc_span::{BytePos, Span, Symbol};
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
-#[derive(Diagnostic)]
-#[diag(session_incorrect_cgu_reuse_type)]
-pub struct IncorrectCguReuseType<'a> {
- #[primary_span]
- pub span: Span,
- pub cgu_user_name: &'a str,
- pub actual_reuse: CguReuse,
- pub expected_reuse: CguReuse,
- pub at_least: u8,
-}
-
-#[derive(Diagnostic)]
-#[diag(session_cgu_not_recorded)]
-pub struct CguNotRecorded<'a> {
- pub cgu_user_name: &'a str,
- pub cgu_name: &'a str,
-}
-
pub struct FeatureGateError {
pub span: MultiSpan,
pub explain: DiagnosticMessage,
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index d6c746a7b..17ac3e991 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(option_get_or_insert_default)]
#![feature(rustc_attrs)]
#![feature(map_many_mut)]
+#![feature(iter_intersperse)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
@@ -22,7 +23,6 @@ extern crate tracing;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_fluent_macro::fluent_messages;
-pub mod cgu_reuse_tracker;
pub mod utils;
pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass};
pub use rustc_lint_defs as lint;
@@ -43,6 +43,9 @@ pub mod output;
pub use getopts;
+mod version;
+pub use version::RustcVersion;
+
fluent_messages! { "../messages.ftl" }
/// Requirements for a `StableHashingContext` to be used in this crate.
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index c1424db60..ed00851b4 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -4,6 +4,7 @@ use crate::search_paths::SearchPath;
use crate::utils::NativeLib;
use crate::{lint, EarlyErrorHandler};
use rustc_data_structures::profiling::TimePassesFormat;
+use rustc_data_structures::stable_hasher::Hash64;
use rustc_errors::ColorConfig;
use rustc_errors::{LanguageIdentifier, TerminalUrl};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
@@ -158,6 +159,10 @@ top_level_options!(
/// directory to store intermediate results.
incremental: Option<PathBuf> [UNTRACKED],
assert_incr_state: Option<IncrementalStateAssertion> [UNTRACKED],
+ /// Set by the `Config::hash_untracked_state` callback for custom
+ /// drivers to invalidate the incremental cache
+ #[rustc_lint_opt_deny_field_access("should only be used via `Config::hash_untracked_state`")]
+ untracked_state_hash: Hash64 [TRACKED_NO_CRATE_HASH],
unstable_opts: UnstableOptions [SUBSTRUCT],
prints: Vec<PrintRequest> [UNTRACKED],
@@ -289,7 +294,7 @@ impl CodegenOptions {
// JUSTIFICATION: defn of the suggested wrapper fn
#[allow(rustc::bad_opt_access)]
pub fn instrument_coverage(&self) -> InstrumentCoverage {
- self.instrument_coverage.unwrap_or(InstrumentCoverage::Off)
+ self.instrument_coverage
}
}
@@ -384,7 +389,7 @@ mod desc {
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
pub const parse_instrument_coverage: &str =
- "`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`";
+ "`all` (default), `branch`, `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 non-negative number";
@@ -412,9 +417,9 @@ mod desc {
"one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
pub const parse_split_dwarf_kind: &str =
"one of supported split dwarf modes (`split` or `single`)";
- pub const parse_gcc_ld: &str = "one of: no value, `lld`";
pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
+ pub const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
pub const parse_stack_protector: &str =
"one of (`none` (default), `basic`, `strong`, or `all`)";
pub const parse_branch_protection: &str =
@@ -422,6 +427,9 @@ mod desc {
pub const parse_proc_macro_execution_strategy: &str =
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
+ pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
+ pub const parse_inlining_threshold: &str =
+ "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
}
mod parse {
@@ -472,6 +480,21 @@ mod parse {
}
}
+ /// Parses whether polonius is enabled, and if so, which version.
+ pub(crate) fn parse_polonius(slot: &mut Polonius, v: Option<&str>) -> bool {
+ match v {
+ Some("legacy") | None => {
+ *slot = Polonius::Legacy;
+ true
+ }
+ Some("next") => {
+ *slot = Polonius::Next;
+ true
+ }
+ _ => false,
+ }
+ }
+
/// Use this for any string option that has a static default.
pub(crate) fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
match v {
@@ -892,24 +915,25 @@ mod parse {
}
pub(crate) fn parse_instrument_coverage(
- slot: &mut Option<InstrumentCoverage>,
+ slot: &mut InstrumentCoverage,
v: Option<&str>,
) -> bool {
if v.is_some() {
- let mut bool_arg = None;
- if parse_opt_bool(&mut bool_arg, v) {
- *slot = bool_arg.unwrap().then_some(InstrumentCoverage::All);
+ let mut bool_arg = false;
+ if parse_bool(&mut bool_arg, v) {
+ *slot = if bool_arg { InstrumentCoverage::All } else { InstrumentCoverage::Off };
return true;
}
}
let Some(v) = v else {
- *slot = Some(InstrumentCoverage::All);
+ *slot = InstrumentCoverage::All;
return true;
};
- *slot = Some(match v {
+ *slot = match v {
"all" => InstrumentCoverage::All,
+ "branch" => InstrumentCoverage::Branch,
"except-unused-generics" | "except_unused_generics" => {
InstrumentCoverage::ExceptUnusedGenerics
}
@@ -918,7 +942,7 @@ mod parse {
}
"off" | "no" | "n" | "false" | "0" => InstrumentCoverage::Off,
_ => return false,
- });
+ };
true
}
@@ -1075,6 +1099,30 @@ mod parse {
true
}
+ pub(crate) fn parse_remap_path_scope(
+ slot: &mut RemapPathScopeComponents,
+ v: Option<&str>,
+ ) -> bool {
+ if let Some(v) = v {
+ *slot = RemapPathScopeComponents::empty();
+ for s in v.split(',') {
+ *slot |= match s {
+ "macro" => RemapPathScopeComponents::MACRO,
+ "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
+ "unsplit-debuginfo" => RemapPathScopeComponents::UNSPLIT_DEBUGINFO,
+ "split-debuginfo" => RemapPathScopeComponents::SPLIT_DEBUGINFO,
+ "split-debuginfo-path" => RemapPathScopeComponents::SPLIT_DEBUGINFO_PATH,
+ "object" => RemapPathScopeComponents::OBJECT,
+ "all" => RemapPathScopeComponents::all(),
+ _ => return false,
+ }
+ }
+ true
+ } else {
+ false
+ }
+ }
+
pub(crate) fn parse_relocation_model(slot: &mut Option<RelocModel>, v: Option<&str>) -> bool {
match v.and_then(|s| RelocModel::from_str(s).ok()) {
Some(relocation_model) => *slot = Some(relocation_model),
@@ -1166,7 +1214,7 @@ mod parse {
// 2. Parse a list of enabled and disabled components.
for comp in s.split(',') {
- if slot.handle_cli_component(comp).is_err() {
+ if slot.handle_cli_component(comp).is_none() {
return false;
}
}
@@ -1202,15 +1250,6 @@ mod parse {
true
}
- pub(crate) fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
- match v {
- None => *slot = None,
- Some("lld") => *slot = Some(LdImpl::Lld),
- _ => return false,
- }
- true
- }
-
pub(crate) fn parse_stack_protector(slot: &mut StackProtector, v: Option<&str>) -> bool {
match v.and_then(|s| StackProtector::from_str(s).ok()) {
Some(ssp) => *slot = ssp,
@@ -1273,6 +1312,26 @@ mod parse {
};
true
}
+
+ pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
+ match v {
+ Some("always" | "yes") => {
+ *slot = InliningThreshold::Always;
+ }
+ Some("never") => {
+ *slot = InliningThreshold::Never;
+ }
+ Some(v) => {
+ if let Ok(threshold) = v.parse() {
+ *slot = InliningThreshold::Sometimes(threshold);
+ } else {
+ return false;
+ }
+ }
+ None => return false,
+ }
+ true
+ }
}
options! {
@@ -1315,11 +1374,12 @@ options! {
inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
"set the threshold for inlining a function"),
#[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
- instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
+ instrument_coverage: InstrumentCoverage = (InstrumentCoverage::Off, parse_instrument_coverage, [TRACKED],
"instrument the generated code to support LLVM source-based code coverage \
reports (note, the compiler build config must include `profiler = true`); \
implies `-C symbol-mangling-version=v0`. Optional values are:
`=all` (implicit value)
+ `=branch`
`=except-unused-generics`
`=except-unused-functions`
`=off` (default)"),
@@ -1441,6 +1501,8 @@ options! {
"combine CGUs into a single one"),
crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
"inject the given attribute in the crate"),
+ cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED],
+ "threshold to allow cross crate inlining of functions"),
debug_info_for_profiling: bool = (false, parse_bool, [TRACKED],
"emit discriminators and other data necessary for AutoFDO"),
debug_macros: bool = (false, parse_bool, [TRACKED],
@@ -1452,9 +1514,6 @@ options! {
dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
"in dep-info output, omit targets for tracking dependencies of the dep-info files \
themselves (default: no)"),
- dep_tasks: bool = (false, parse_bool, [UNTRACKED],
- "print tasks that execute and the color their dep node gets (requires debug build) \
- (default: no)"),
dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
"emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \
(default: no)"),
@@ -1492,8 +1551,6 @@ options! {
dump_solver_proof_tree: DumpSolverProofTree = (DumpSolverProofTree::Never, parse_dump_solver_proof_tree, [UNTRACKED],
"dump a proof tree for every goal evaluated by the new trait solver. If the flag is specified without any options after it
then it defaults to `always`. If the flag is not specified at all it defaults to `on-request`."),
- dump_solver_proof_tree_use_cache: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
- "determines whether dumped proof trees use the global cache"),
dwarf_version: Option<u32> = (None, parse_opt_number, [TRACKED],
"version of DWARF debug information to emit (default: 2 or 4, depending on platform)"),
dylib_lto: bool = (false, parse_bool, [UNTRACKED],
@@ -1521,7 +1578,6 @@ options! {
"whether each function should go in its own section"),
future_incompat_test: bool = (false, parse_bool, [UNTRACKED],
"forces all lints to be future incompatible, used for internal testing (default: no)"),
- gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
"use dark-themed colors in graphviz output (default: no)"),
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
@@ -1554,15 +1610,6 @@ options! {
"a default MIR inlining threshold (default: 50)"),
input_stats: bool = (false, parse_bool, [UNTRACKED],
"gather statistics about the input (default: no)"),
- #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
- instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
- "instrument the generated code to support LLVM source-based code coverage \
- reports (note, the compiler build config must include `profiler = true`); \
- implies `-C symbol-mangling-version=v0`. Optional values are:
- `=all` (implicit value)
- `=except-unused-generics`
- `=except-unused-functions`
- `=off` (default)"),
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
instrument_xray: Option<InstrumentXRay> = (None, parse_instrument_xray, [TRACKED],
@@ -1610,9 +1657,10 @@ options! {
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED],
- "use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the specified passes to be \
- enabled, overriding all other checks. Passes that are not specified are enabled or \
- disabled by other flags as usual."),
+ "use like `-Zmir-enable-passes=+DestinationPropagation,-InstSimplify`. Forces the \
+ specified passes to be enabled, overriding all other checks. In particular, this will \
+ enable unsound (known-buggy and hence usually disabled) passes without further warning! \
+ Passes that are not specified are enabled or disabled by other flags as usual."),
mir_include_spans: bool = (false, parse_bool, [UNTRACKED],
"use line numbers relative to the function in mir pretty printing"),
mir_keep_place_mention: bool = (false, parse_bool, [TRACKED],
@@ -1669,7 +1717,7 @@ options! {
"whether to use the PLT when calling into shared libraries;
only has effect for PIC code on systems with ELF binaries
(default: PLT is disabled if full relro is enabled on x86_64)"),
- polonius: bool = (false, parse_bool, [TRACKED],
+ polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED],
"enable polonius-based borrow-checker (default: no)"),
polymorphize: bool = (false, parse_bool, [TRACKED],
"perform polymorphization analysis"),
@@ -1720,6 +1768,8 @@ options! {
"choose which RELRO level to use"),
remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"remap paths under the current working directory to this path prefix"),
+ remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED],
+ "remap path scope (default: all)"),
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"directory into which to write optimization remarks (if not specified, they will be \
written to standard error output)"),
@@ -1791,11 +1841,6 @@ written to standard error output)"),
"prefer dynamic linking to static linking for staticlibs (default: no)"),
strict_init_checks: bool = (false, parse_bool, [TRACKED],
"control if mem::uninitialized and mem::zeroed panic on more UB"),
- strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
- "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
- symbol_mangling_version: Option<SymbolManglingVersion> = (None,
- parse_symbol_mangling_version, [TRACKED],
- "which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
#[rustc_lint_opt_deny_field_access("use `Session::teach` instead of this field")]
teach: bool = (false, parse_bool, [TRACKED],
"show extended diagnostic help (default: no)"),
@@ -1869,6 +1914,7 @@ written to standard error output)"),
`hir` (the HIR), `hir,identified`,
`hir,typed` (HIR with types for each node),
`hir-tree` (dump the raw HIR),
+ `thir-tree`, `thir-flat`,
`mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
unsound_mir_opts: bool = (false, parse_bool, [TRACKED],
"enable unsound and buggy MIR optimizations (default: no)"),
@@ -1906,8 +1952,3 @@ pub enum WasiExecModel {
Command,
Reactor,
}
-
-#[derive(Clone, Copy, Hash)]
-pub enum LdImpl {
- Lld,
-}
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index 7a57b0621..9cd96895a 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -186,10 +186,14 @@ pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool
return true;
}
}
- if let CrateType::ProcMacro | CrateType::Dylib = crate_type && sess.target.only_cdylib {
+ if let CrateType::ProcMacro | CrateType::Dylib = crate_type
+ && sess.target.only_cdylib
+ {
return true;
}
- if let CrateType::Executable = crate_type && !sess.target.executables {
+ if let CrateType::Executable = crate_type
+ && !sess.target.executables
+ {
return true;
}
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 671204c0d..4d20d6d41 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -1,7 +1,7 @@
//! Contains `ParseSess` which holds state living beyond what one `Parser` might.
//! It also serves as an input to the parser itself.
-use crate::config::CheckCfg;
+use crate::config::{Cfg, CheckCfg};
use crate::errors::{
CliFeatureDiagnosticHelp, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError,
};
@@ -9,7 +9,7 @@ use crate::lint::{
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
};
use rustc_ast::node_id::NodeId;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
use rustc_errors::{emitter::SilentEmitter, Handler};
use rustc_errors::{
@@ -25,11 +25,6 @@ use rustc_span::{Span, Symbol};
use rustc_ast::attr::AttrIdGenerator;
use std::str;
-/// The set of keys (and, optionally, values) that define the compilation
-/// environment of the crate, used to drive conditional compilation.
-pub type CrateConfig = FxIndexSet<(Symbol, Option<Symbol>)>;
-pub type CrateCheckConfig = CheckCfg<Symbol>;
-
/// Collected spans during parsing for places where a certain feature was
/// used and should be feature gated accordingly in `check_crate`.
#[derive(Default)]
@@ -39,7 +34,7 @@ pub struct GatedSpans {
impl GatedSpans {
/// Feature gate the given `span` under the given `feature`
- /// which is same `Symbol` used in `active.rs`.
+ /// which is same `Symbol` used in `unstable.rs`.
pub fn gate(&self, feature: Symbol, span: Span) {
self.spans.borrow_mut().entry(feature).or_default().push(span);
}
@@ -78,7 +73,7 @@ impl SymbolGallery {
}
/// Construct a diagnostic for a language feature error due to the given `span`.
-/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
+/// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbols`.
#[track_caller]
pub fn feature_err(
sess: &ParseSess,
@@ -193,8 +188,8 @@ pub fn add_feature_diagnostics_for_issue(
pub struct ParseSess {
pub span_diagnostic: Handler,
pub unstable_features: UnstableFeatures,
- pub config: CrateConfig,
- pub check_config: CrateCheckConfig,
+ pub config: Cfg,
+ pub check_config: CheckCfg,
pub edition: Edition,
/// Places where raw identifiers were used. This is used to avoid complaining about idents
/// clashing with keywords in new editions.
@@ -237,8 +232,8 @@ impl ParseSess {
Self {
span_diagnostic: handler,
unstable_features: UnstableFeatures::from_environment(None),
- config: FxIndexSet::default(),
- check_config: CrateCheckConfig::default(),
+ config: Cfg::default(),
+ check_config: CheckCfg::default(),
edition: ExpnId::root().expn_data().edition,
raw_identifier_spans: Default::default(),
bad_unicode_identifiers: Lock::new(Default::default()),
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index b484978ee..80a549b30 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,8 +1,8 @@
-use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use crate::config::{
- self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, SwitchWithOptPath,
+ self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType,
+ RemapPathScopeComponents, SwitchWithOptPath,
};
use crate::config::{ErrorOutputType, Input};
use crate::errors;
@@ -31,8 +31,8 @@ use rustc_errors::{
use rustc_macros::HashStable_Generic;
pub use rustc_span::def_id::StableCrateId;
use rustc_span::edition::Edition;
-use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap, Span};
-use rustc_span::{SourceFileHashAlgorithm, Symbol};
+use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap};
+use rustc_span::{SourceFileHashAlgorithm, Span, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
use rustc_target::spec::{
@@ -45,7 +45,7 @@ use std::fmt;
use std::ops::{Div, Mul};
use std::path::{Path, PathBuf};
use std::str::FromStr;
-use std::sync::Arc;
+use std::sync::{atomic::AtomicBool, Arc};
use std::time::Duration;
pub struct OptimizationFuel {
@@ -153,9 +153,6 @@ pub struct Session {
pub io: CompilerIO,
incr_comp_session: OneThread<RefCell<IncrCompSession>>,
- /// Used for incremental compilation tests. Will only be populated if
- /// `-Zquery-dep-graph` is specified.
- pub cgu_reuse_tracker: CguReuseTracker,
/// Used by `-Z self-profile`.
pub prof: SelfProfilerRef,
@@ -205,6 +202,12 @@ pub struct Session {
/// The version of the rustc process, possibly including a commit hash and description.
pub cfg_version: &'static str,
+ /// The inner atomic value is set to true when a feature marked as `internal` is
+ /// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
+ /// internal features are wontfix, and they are usually the cause of the ICEs.
+ /// None signifies that this is not tracked.
+ pub using_internal_features: Arc<AtomicBool>,
+
/// 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
@@ -258,7 +261,11 @@ impl Session {
pub fn local_crate_source_file(&self) -> Option<PathBuf> {
let path = self.io.input.opt_path()?;
- Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned())
+ if self.should_prefer_remapped_for_codegen() {
+ Some(self.opts.file_path_mapping().map_prefix(path).0.into_owned())
+ } else {
+ Some(path.to_path_buf())
+ }
}
fn check_miri_unleashed_features(&self) {
@@ -701,6 +708,10 @@ impl Session {
self.opts.cg.instrument_coverage() != InstrumentCoverage::Off
}
+ pub fn instrument_coverage_branch(&self) -> bool {
+ self.opts.cg.instrument_coverage() == InstrumentCoverage::Branch
+ }
+
pub fn instrument_coverage_except_unused_generics(&self) -> bool {
self.opts.cg.instrument_coverage() == InstrumentCoverage::ExceptUnusedGenerics
}
@@ -1247,6 +1258,53 @@ impl Session {
pub fn link_dead_code(&self) -> bool {
self.opts.cg.link_dead_code.unwrap_or(false)
}
+
+ pub fn should_prefer_remapped_for_codegen(&self) -> bool {
+ // bail out, if any of the requested crate types aren't:
+ // "compiled executables or libraries"
+ for crate_type in &self.opts.crate_types {
+ match crate_type {
+ CrateType::Executable
+ | CrateType::Dylib
+ | CrateType::Rlib
+ | CrateType::Staticlib
+ | CrateType::Cdylib => continue,
+ CrateType::ProcMacro => return false,
+ }
+ }
+
+ let has_split_debuginfo = match self.split_debuginfo() {
+ SplitDebuginfo::Off => false,
+ SplitDebuginfo::Packed => true,
+ SplitDebuginfo::Unpacked => true,
+ };
+
+ let remap_path_scopes = &self.opts.unstable_opts.remap_path_scope;
+ let mut prefer_remapped = false;
+
+ if remap_path_scopes.contains(RemapPathScopeComponents::UNSPLIT_DEBUGINFO) {
+ prefer_remapped |= !has_split_debuginfo;
+ }
+
+ if remap_path_scopes.contains(RemapPathScopeComponents::SPLIT_DEBUGINFO) {
+ prefer_remapped |= has_split_debuginfo;
+ }
+
+ prefer_remapped
+ }
+
+ pub fn should_prefer_remapped_for_split_debuginfo_paths(&self) -> bool {
+ let has_split_debuginfo = match self.split_debuginfo() {
+ SplitDebuginfo::Off => false,
+ SplitDebuginfo::Packed | SplitDebuginfo::Unpacked => true,
+ };
+
+ self.opts
+ .unstable_opts
+ .remap_path_scope
+ .contains(RemapPathScopeComponents::SPLIT_DEBUGINFO_PATH)
+ && has_split_debuginfo
+ }
}
// JUSTIFICATION: part of session construction
@@ -1337,6 +1395,7 @@ pub fn build_session(
target_override: Option<Target>,
cfg_version: &'static str,
ice_file: Option<PathBuf>,
+ using_internal_features: Arc<AtomicBool>,
expanded_args: Vec<String>,
) -> Session {
// FIXME: This is not general enough to make the warning lint completely override
@@ -1431,12 +1490,6 @@ pub fn build_session(
});
let print_fuel = AtomicU64::new(0);
- let cgu_reuse_tracker = if sopts.unstable_opts.query_dep_graph {
- CguReuseTracker::new()
- } else {
- CguReuseTracker::new_disabled()
- };
-
let prof = SelfProfilerRef::new(
self_profiler,
sopts.unstable_opts.time_passes.then(|| sopts.unstable_opts.time_passes_format),
@@ -1461,7 +1514,6 @@ pub fn build_session(
sysroot,
io,
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
- cgu_reuse_tracker,
prof,
perf_stats: PerfStats {
symbol_hash_time: Lock::new(Duration::from_secs(0)),
@@ -1480,6 +1532,7 @@ pub fn build_session(
target_features: Default::default(),
unstable_target_features: Default::default(),
cfg_version,
+ using_internal_features,
expanded_args,
};
@@ -1763,3 +1816,53 @@ fn mk_emitter(output: ErrorOutputType) -> Box<DynEmitter> {
};
emitter
}
+
+pub trait RemapFileNameExt {
+ type Output<'a>
+ where
+ Self: 'a;
+
+ fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_>;
+
+ fn for_codegen(&self, sess: &Session) -> Self::Output<'_>;
+}
+
+impl RemapFileNameExt for rustc_span::FileName {
+ type Output<'a> = rustc_span::FileNameDisplay<'a>;
+
+ fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_> {
+ if sess.opts.unstable_opts.remap_path_scope.contains(scopes) {
+ self.prefer_remapped_unconditionaly()
+ } else {
+ self.prefer_local()
+ }
+ }
+
+ fn for_codegen(&self, sess: &Session) -> Self::Output<'_> {
+ if sess.should_prefer_remapped_for_codegen() {
+ self.prefer_remapped_unconditionaly()
+ } else {
+ self.prefer_local()
+ }
+ }
+}
+
+impl RemapFileNameExt for rustc_span::RealFileName {
+ type Output<'a> = &'a Path;
+
+ fn for_scope(&self, sess: &Session, scopes: RemapPathScopeComponents) -> Self::Output<'_> {
+ if sess.opts.unstable_opts.remap_path_scope.contains(scopes) {
+ self.remapped_path_if_available()
+ } else {
+ self.local_path_if_available()
+ }
+ }
+
+ fn for_codegen(&self, sess: &Session) -> Self::Output<'_> {
+ if sess.should_prefer_remapped_for_codegen() {
+ self.remapped_path_if_available()
+ } else {
+ self.local_path_if_available()
+ }
+ }
+}
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index aea7c6c28..3ed044ad7 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -161,7 +161,9 @@ pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
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 == '_') {
+ if let Some(start) = chars.next()
+ && (start.is_ascii_alphabetic() || start == '_')
+ {
chars.all(|char| char.is_ascii_alphanumeric() || char == '_')
} else {
false
diff --git a/compiler/rustc_session/src/version.rs b/compiler/rustc_session/src/version.rs
new file mode 100644
index 000000000..1ad8620bf
--- /dev/null
+++ b/compiler/rustc_session/src/version.rs
@@ -0,0 +1,19 @@
+use std::fmt::{self, Display};
+
+#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(HashStable_Generic)]
+pub struct RustcVersion {
+ pub major: u16,
+ pub minor: u16,
+ pub patch: u16,
+}
+
+impl RustcVersion {
+ pub const CURRENT: Self = current_rustc_version!(env!("CFG_RELEASE"));
+}
+
+impl Display for RustcVersion {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
+ }
+}