summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /compiler/rustc_session/src
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+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/code_stats.rs5
-rw-r--r--compiler/rustc_session/src/config.rs98
-rw-r--r--compiler/rustc_session/src/cstore.rs18
-rw-r--r--compiler/rustc_session/src/errors.rs52
-rw-r--r--compiler/rustc_session/src/filesearch.rs7
-rw-r--r--compiler/rustc_session/src/options.rs63
-rw-r--r--compiler/rustc_session/src/output.rs8
-rw-r--r--compiler/rustc_session/src/parse.rs12
-rw-r--r--compiler/rustc_session/src/session.rs93
-rw-r--r--compiler/rustc_session/src/utils.rs2
10 files changed, 249 insertions, 109 deletions
diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index eede4d16e..1085bce44 100644
--- a/compiler/rustc_session/src/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
@@ -19,7 +19,7 @@ pub enum SizeKind {
Min,
}
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FieldInfo {
pub name: Symbol,
pub offset: u64,
@@ -33,6 +33,7 @@ pub enum DataTypeKind {
Union,
Enum,
Closure,
+ Generator,
}
#[derive(PartialEq, Eq, Hash, Debug)]
@@ -114,7 +115,7 @@ impl CodeStats {
let struct_like = match kind {
DataTypeKind::Struct | DataTypeKind::Closure => true,
- DataTypeKind::Enum | DataTypeKind::Union => false,
+ DataTypeKind::Enum | DataTypeKind::Union | DataTypeKind::Generator => false,
};
for (i, variant_info) in variants.into_iter().enumerate() {
let VariantInfo { ref name, kind: _, align: _, size, ref fields } = *variant_info;
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 7a20100fd..586454f76 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -32,9 +32,10 @@ use std::collections::btree_map::{
use std::collections::{BTreeMap, BTreeSet};
use std::fmt;
use std::hash::Hash;
-use std::iter::{self, FromIterator};
+use std::iter;
use std::path::{Path, PathBuf};
use std::str::{self, FromStr};
+use std::sync::LazyLock;
pub mod sigpipe;
@@ -554,6 +555,16 @@ pub enum PrintRequest {
SplitDebuginfo,
}
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum TraitSolver {
+ /// Classic trait solver in `rustc_trait_selection::traits::select`
+ Classic,
+ /// Chalk trait solver
+ Chalk,
+ /// Experimental trait solver in `rustc_trait_selection::solve`
+ Next,
+}
+
pub enum Input {
/// Load source code from a file.
File(PathBuf),
@@ -580,6 +591,24 @@ impl Input {
Input::Str { ref name, .. } => name.clone(),
}
}
+
+ pub fn opt_path(&self) -> Option<&Path> {
+ match self {
+ Input::File(file) => Some(file),
+ Input::Str { name, .. } => match name {
+ FileName::Real(real) => real.local_path(),
+ FileName::QuoteExpansion(_) => None,
+ FileName::Anon(_) => None,
+ FileName::MacroExpansion(_) => None,
+ FileName::ProcMacroSourceCode(_) => None,
+ FileName::CfgSpec(_) => None,
+ FileName::CliCrateAttr(_) => None,
+ FileName::Custom(_) => None,
+ FileName::DocTest(path, _) => Some(path),
+ FileName::InlineAsm(_) => None,
+ },
+ }
+ }
}
#[derive(Clone, Hash, Debug, HashStable_Generic)]
@@ -704,7 +733,7 @@ impl OutputFilenames {
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
- // actually built. We can't just take LLVM's host triple because they
+ // actually built. We can't just take LLVM's host triple because they
// normalize all ix86 architectures to i386.
//
// Instead of grabbing the host triple (for the current host), we grab (at
@@ -787,6 +816,12 @@ 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 {
@@ -875,18 +910,12 @@ pub struct PacRet {
pub key: PAuthKey,
}
-#[derive(Clone, Copy, Hash, Debug, PartialEq)]
+#[derive(Clone, Copy, Hash, Debug, PartialEq, Default)]
pub struct BranchProtection {
pub bti: bool,
pub pac_ret: Option<PacRet>,
}
-impl Default for BranchProtection {
- fn default() -> Self {
- BranchProtection { bti: false, pac_ret: None }
- }
-}
-
pub const fn default_lib_output() -> CrateType {
CrateType::Rlib
}
@@ -1260,7 +1289,7 @@ impl RustcOptGroup {
// The `opt` local module holds wrappers around the `getopts` API that
// adds extra rustc-specific metadata to each option; such metadata
-// is exposed by . The public
+// is exposed by . The public
// functions below ending with `_u` are the functions that return
// *unstable* options, i.e., options that are only enabled when the
// user also passes the `-Z unstable-options` debugging flag.
@@ -1312,7 +1341,12 @@ mod opt {
unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
}
}
-
+static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
+ format!(
+ "Specify which edition of the compiler to use when compiling code. \
+The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
+ )
+});
/// Returns the "short" subset of the rustc command line options,
/// including metadata for each option, such as whether the option is
/// part of the stable long-term interface for rustc.
@@ -1345,7 +1379,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
opt::opt_s(
"",
"edition",
- "Specify which edition of the compiler to use when compiling code.",
+ &*EDITION_STRING,
EDITION_NAME_LIST,
),
opt::multi_s(
@@ -1875,7 +1909,7 @@ fn parse_opt_level(
.into_iter()
.flat_map(|(i, s)| {
// NB: This can match a string without `=`.
- if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None }
+ if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
})
.max();
if max_o > max_c {
@@ -1912,7 +1946,7 @@ fn select_debuginfo(
.into_iter()
.flat_map(|(i, s)| {
// NB: This can match a string without `=`.
- if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
+ if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
})
.max();
if max_g > max_c {
@@ -2075,7 +2109,7 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
.map(|s| {
// Parse string of the form "[KIND[:MODIFIERS]=]lib[:new_name]",
// where KIND is one of "dylib", "framework", "static", "link-arg" and
- // where MODIFIERS are a comma separated list of supported modifiers
+ // where MODIFIERS are a comma separated list of supported modifiers
// (bundle, verbatim, whole-archive, as-needed). Each modifier is prefixed
// with either + or - to indicate whether it is enabled or disabled.
// The last value specified for a given modifier wins.
@@ -2443,6 +2477,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let pretty = parse_pretty(&unstable_opts, error_format);
+ // query-dep-graph is required if dump-dep-graph is given #106736
+ if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
+ early_error(error_format, "can't dump dependency graph without `-Z query-dep-graph`");
+ }
+
// Try to find a directory containing the Rust `src`, for more details see
// the doc comment on the `real_rust_source_base_dir` field.
let tmp_buf;
@@ -2475,12 +2514,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
early_error(error_format, &format!("Current directory is invalid: {e}"));
});
- let (path, remapped) =
- FilePathMapping::new(remap_path_prefix.clone()).map_prefix(working_dir.clone());
+ let remap = FilePathMapping::new(remap_path_prefix.clone());
+ let (path, remapped) = remap.map_prefix(&working_dir);
let working_dir = if remapped {
- RealFileName::Remapped { local_path: Some(working_dir), virtual_name: path }
+ RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) }
} else {
- RealFileName::LocalPath(path)
+ RealFileName::LocalPath(path.into_owned())
};
Options {
@@ -2761,7 +2800,7 @@ pub(crate) mod dep_tracking {
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel,
OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SplitDwarfKind,
- SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths,
+ SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
@@ -2861,6 +2900,7 @@ pub(crate) mod dep_tracking {
BranchProtection,
OomStrategy,
LanguageIdentifier,
+ TraitSolver,
);
impl<T1, T2> DepTrackingHash for (T1, T2)
@@ -2981,3 +3021,21 @@ pub enum ProcMacroExecutionStrategy {
/// Run the proc-macro code on a different thread.
CrossThread,
}
+
+/// Which format to use for `-Z dump-mono-stats`
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum DumpMonoStatsFormat {
+ /// Pretty-print a markdown table
+ Markdown,
+ /// Emit structured JSON
+ Json,
+}
+
+impl DumpMonoStatsFormat {
+ pub fn extension(self) -> &'static str {
+ match self {
+ Self::Markdown => "md",
+ Self::Json => "json",
+ }
+ }
+}
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 7d4a1e212..4ae9a3fae 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -6,9 +6,10 @@ use crate::search_paths::PathKind;
use crate::utils::NativeLibKind;
use crate::Session;
use rustc_ast as ast;
-use rustc_data_structures::sync::{self, MetadataRef};
-use rustc_hir::def_id::{CrateNum, DefId, StableCrateId, LOCAL_CRATE};
-use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
+use rustc_data_structures::sync::{self, MetadataRef, RwLock};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE};
+use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
+use rustc_index::vec::IndexVec;
use rustc_span::hygiene::{ExpnHash, ExpnId};
use rustc_span::symbol::Symbol;
use rustc_span::Span;
@@ -217,6 +218,7 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
/// during resolve)
pub trait CrateStore: std::fmt::Debug {
fn as_any(&self) -> &dyn Any;
+ fn untracked_as_any(&mut self) -> &mut dyn Any;
// Foreign definitions.
// This information is safe to access, since it's hashed as part of the DefPathHash, which incr.
@@ -226,7 +228,7 @@ pub trait CrateStore: std::fmt::Debug {
fn def_path_hash(&self, def: DefId) -> DefPathHash;
// This information is safe to access, since it's hashed as part of the StableCrateId, which
- // incr. comp. uses to identify a CrateNum.
+ // incr. comp. uses to identify a CrateNum.
fn crate_name(&self, cnum: CrateNum) -> Symbol;
fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId;
fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum;
@@ -249,3 +251,11 @@ pub trait CrateStore: std::fmt::Debug {
}
pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
+
+#[derive(Debug)]
+pub struct Untracked {
+ pub cstore: Box<CrateStoreDyn>,
+ /// Reference span for definitions.
+ pub source_span: IndexVec<LocalDefId, Span>,
+ pub definitions: RwLock<Definitions>,
+}
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index ee492f802..f5a72573d 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -116,6 +116,10 @@ pub struct StackProtectorNotSupportedForTarget<'a> {
}
#[derive(Diagnostic)]
+#[diag(session_branch_protection_requires_aarch64)]
+pub(crate) struct BranchProtectionRequiresAArch64;
+
+#[derive(Diagnostic)]
#[diag(session_split_debuginfo_unstable_platform)]
pub struct SplitDebugInfoUnstablePlatform {
pub debuginfo: SplitDebuginfo,
@@ -176,7 +180,7 @@ impl ExprParenthesesNeeded {
#[derive(Diagnostic)]
#[diag(session_skipping_const_checks)]
pub struct SkippingConstChecks {
- #[subdiagnostic(eager)]
+ #[subdiagnostic]
pub unleashed_features: Vec<UnleashedFeatureHelp>,
}
@@ -256,9 +260,11 @@ pub(crate) struct InvalidFloatLiteralSuffix {
#[derive(Diagnostic)]
#[diag(session_int_literal_too_large)]
+#[note]
pub(crate) struct IntLiteralTooLarge {
#[primary_span]
pub span: Span,
+ pub limit: String,
}
#[derive(Diagnostic)]
@@ -291,20 +297,33 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
}
- // Try to lowercase the prefix if it's a valid base prefix.
- fn fix_base_capitalisation(s: &str) -> Option<String> {
- if let Some(stripped) = s.strip_prefix('B') {
- Some(format!("0b{stripped}"))
- } else if let Some(stripped) = s.strip_prefix('O') {
- Some(format!("0o{stripped}"))
- } else if let Some(stripped) = s.strip_prefix('X') {
- Some(format!("0x{stripped}"))
+ // Try to lowercase the prefix if the prefix and suffix are valid.
+ fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> {
+ let mut chars = suffix.chars();
+
+ let base_char = chars.next().unwrap();
+ let base = match base_char {
+ 'B' => 2,
+ 'O' => 8,
+ 'X' => 16,
+ _ => return None,
+ };
+
+ // check that the suffix contains only base-appropriate characters
+ let valid = prefix == "0"
+ && chars
+ .filter(|c| *c != '_')
+ .take_while(|c| *c != 'i' && *c != 'u')
+ .all(|c| c.to_digit(base).is_some());
+
+ if valid {
+ Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
} else {
None
}
}
- let token::Lit { kind, suffix, .. } = lit;
+ let token::Lit { kind, symbol, suffix, .. } = lit;
match err {
// `LexerError` is an error, but it was already reported
// by lexer, so here we don't report it the second time.
@@ -320,7 +339,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
if looks_like_width_suffix(&['i', 'u'], suf) {
// If it looks like a width, try to be helpful.
sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
- } else if let Some(fixed) = fix_base_capitalisation(suf) {
+ } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
} else {
sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
@@ -344,8 +363,15 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
_ => unreachable!(),
};
}
- LitError::IntTooLarge => {
- sess.emit_err(IntLiteralTooLarge { span });
+ LitError::IntTooLarge(base) => {
+ let max = u128::MAX;
+ let limit = match base {
+ 2 => format!("{max:#b}"),
+ 8 => format!("{max:#o}"),
+ 16 => format!("{max:#x}"),
+ _ => format!("{max}"),
+ };
+ sess.emit_err(IntLiteralTooLarge { span, limit });
}
}
}
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 1b66773be..b6a328908 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -3,7 +3,6 @@
use smallvec::{smallvec, SmallVec};
use std::env;
use std::fs;
-use std::iter::FromIterator;
use std::path::{Path, PathBuf};
use crate::search_paths::{PathKind, SearchPath};
@@ -123,7 +122,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
let target = crate::config::host_triple();
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
- let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?));
+ let path = current_dll_path().and_then(|s| s.canonicalize().map_err(|e| e.to_string()));
if let Ok(dll) = path {
// use `parent` twice to chop off the file name and then also the
// directory containing the dll which should be either `lib` or `bin`.
@@ -156,7 +155,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
/// This function checks if sysroot is found using env::args().next(), and if it
/// is not found, finds sysroot from current rustc_driver dll.
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
- // Follow symlinks. If the resolved path is relative, make it absolute.
+ // Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: PathBuf) -> PathBuf {
let path = fs::canonicalize(&path).unwrap_or(path);
// See comments on this target function, but the gist is that
@@ -166,7 +165,7 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
}
fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
- let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?;
+ let dll = current_dll_path().map(|s| canonicalize(s))?;
// `dll` will be in one of the following two:
// - compiler's libdir: $sysroot/lib/*.dll
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 8e9198b79..7b5fd6cc2 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -368,7 +368,7 @@ mod desc {
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
- pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`";
+ pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `leak`, `memory`, `memtag`, `shadow-call-stack`, or `thread`";
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
pub const parse_cfguard: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -377,10 +377,13 @@ mod desc {
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
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`";
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_trait_solver: &str =
+ "one of the supported solver modes (`classic`, `chalk`, or `next`)";
pub const parse_lto: &str =
"either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
pub const parse_linker_plugin_lto: &str =
@@ -675,6 +678,7 @@ mod parse {
*slot |= match s {
"address" => SanitizerSet::ADDRESS,
"cfi" => SanitizerSet::CFI,
+ "kcfi" => SanitizerSet::KCFI,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,
@@ -819,6 +823,21 @@ mod parse {
true
}
+ pub(crate) fn parse_dump_mono_stats(slot: &mut DumpMonoStatsFormat, v: Option<&str>) -> bool {
+ match v {
+ None => true,
+ Some("json") => {
+ *slot = DumpMonoStatsFormat::Json;
+ true
+ }
+ Some("markdown") => {
+ *slot = DumpMonoStatsFormat::Markdown;
+ true
+ }
+ Some(_) => false,
+ }
+ }
+
pub(crate) fn parse_instrument_coverage(
slot: &mut Option<InstrumentCoverage>,
v: Option<&str>,
@@ -863,6 +882,18 @@ mod parse {
}
}
+ pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool {
+ match v {
+ Some("classic") => *slot = TraitSolver::Classic,
+ Some("chalk") => *slot = TraitSolver::Chalk,
+ Some("next") => *slot = TraitSolver::Next,
+ // default trait solver is subject to change..
+ Some("default") => *slot = TraitSolver::Classic,
+ _ => return false,
+ }
+ true
+ }
+
pub(crate) fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
if v.is_some() {
let mut bool_arg = None;
@@ -1210,10 +1241,9 @@ options! {
// tidy-alphabetical-start
allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
- "only allow the listed language features to be enabled in code (space separated)"),
+ "only allow the listed language features to be enabled in code (comma separated)"),
always_encode_mir: bool = (false, parse_bool, [TRACKED],
"encode MIR of all functions into the crate metadata (default: no)"),
- #[rustc_lint_opt_deny_field_access("use `Session::asm_comments` instead of this field")]
asm_comments: bool = (false, parse_bool, [TRACKED],
"generate comments into the assembly (may change behavior) (default: no)"),
assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1225,7 +1255,7 @@ options! {
binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
"include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
(default: no)"),
- box_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
+ box_noalias: bool = (true, parse_bool, [TRACKED],
"emit noalias metadata for box (default: yes)"),
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
"set options for branch target identification and pointer authentication on AArch64"),
@@ -1233,8 +1263,6 @@ options! {
"instrument control-flow architecture protection"),
cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED],
"the codegen unit partitioning strategy to use"),
- chalk: bool = (false, parse_bool, [TRACKED],
- "enable the experimental Chalk-based trait solving engine"),
codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
"the backend to use"),
combine_cgu: bool = (false, parse_bool, [TRACKED],
@@ -1293,6 +1321,11 @@ options! {
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."),
+ dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
+ parse_switch_with_opt_path, [UNTRACKED],
+ "output statistics about monomorphization collection"),
+ dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED],
+ "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"),
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],
@@ -1329,11 +1362,12 @@ 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)"),
- incremental_ignore_spans: bool = (false, parse_bool, [UNTRACKED],
+ 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],
@@ -1359,7 +1393,6 @@ options! {
`=except-unused-generics`
`=except-unused-functions`
`=off` (default)"),
- #[rustc_lint_opt_deny_field_access("use `Session::instrument_mcount` instead of this field")]
instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
@@ -1378,6 +1411,8 @@ 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`)"),
+ log_backtrace: Option<String> = (None, parse_opt_string, [TRACKED],
+ "add a backtrace along with logging"),
ls: bool = (false, parse_bool, [UNTRACKED],
"list the symbols defined by a library crate (default: no)"),
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
@@ -1388,7 +1423,6 @@ options! {
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking \
the same values as the target option of the same name"),
- #[rustc_lint_opt_deny_field_access("use `Session::meta_stats` instead of this field")]
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics (default: no)"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
@@ -1405,7 +1439,7 @@ options! {
"use line numbers relative to the function in mir pretty printing"),
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
"the size at which the `large_assignments` lint starts to be emitted"),
- mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
+ mutable_noalias: bool = (true, parse_bool, [TRACKED],
"emit noalias metadata for mutable references (default: yes)"),
nll_facts: bool = (false, parse_bool, [UNTRACKED],
"dump facts from NLL analysis into side files (default: no)"),
@@ -1417,6 +1451,8 @@ options! {
"run all passes except codegen; no output"),
no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
"omit DWARF address ranges that give faster lookups"),
+ no_jump_tables: bool = (false, parse_no_flag, [TRACKED],
+ "disable the jump tables and lookup tables that can be generated from a switch case lowering"),
no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
"disable the 'leak check' for subtyping; unsound, but useful for tests"),
no_link: bool = (false, parse_no_flag, [TRACKED],
@@ -1463,7 +1499,6 @@ options! {
See #77382 and #74551."),
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
"make rustc print the total optimization fuel used by a crate"),
- #[rustc_lint_opt_deny_field_access("use `Session::print_llvm_passes` instead of this field")]
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"print the LLVM optimization passes being run (default: no)"),
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
@@ -1537,7 +1572,7 @@ options! {
/// o/w tests have closure@path
span_free_formats: bool = (false, parse_bool, [UNTRACKED],
"exclude spans when debug-printing compiler state (default: no)"),
- split_dwarf_inlining: bool = (true, parse_bool, [TRACKED],
+ split_dwarf_inlining: bool = (false, parse_bool, [TRACKED],
"provide minimal debug info in the object/executable to facilitate online \
symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"),
split_dwarf_kind: SplitDwarfKind = (SplitDwarfKind::Split, parse_split_dwarf_kind, [TRACKED],
@@ -1577,10 +1612,8 @@ options! {
#[rustc_lint_opt_deny_field_access("use `Session::threads` instead of this field")]
threads: usize = (1, parse_threads, [UNTRACKED],
"use a thread pool with N threads"),
- #[rustc_lint_opt_deny_field_access("use `Session::time_llvm_passes` instead of this field")]
time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each LLVM pass (default: no)"),
- #[rustc_lint_opt_deny_field_access("use `Session::time_passes` instead of this field")]
time_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each rustc pass (default: no)"),
#[rustc_lint_opt_deny_field_access("use `Session::tls_model` instead of this field")]
@@ -1590,6 +1623,8 @@ options! {
"for every macro invocation, print its name and arguments (default: no)"),
track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
"tracks where in rustc a diagnostic was emitted"),
+ trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED],
+ "specify the trait solver mode used by rustc (default: classic)"),
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
// alongside query results and changes to translation options can affect diagnostics - so
// translation options should be tracked.
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index 8ee3057de..c3f0c4b58 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -29,9 +29,9 @@ pub fn out_filename(
out_filename
}
-/// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
+/// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
/// check this already -- however, the Linux linker will happily overwrite a
-/// read-only file. We should be consistent.
+/// read-only file. We should be consistent.
pub fn check_file_is_writeable(file: &Path, sess: &Session) {
if !is_writeable(file) {
sess.emit_fatal(FileIsNotWriteable { file });
@@ -45,7 +45,7 @@ fn is_writeable(p: &Path) -> bool {
}
}
-pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) -> Symbol {
+pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
let validate = |s: Symbol, span: Option<Span>| {
validate_crate_name(sess, s, span);
s
@@ -71,7 +71,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input)
if let Some((attr, s)) = attr_crate_name {
return validate(s, Some(attr.span));
}
- if let Input::File(ref path) = *input {
+ if let Input::File(ref path) = sess.io.input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with('-') {
sess.emit_err(CrateNameInvalid { s });
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index f9f4f2979..2aa8ca9e4 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -122,7 +122,7 @@ pub fn feature_err_issue<'a>(
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
-pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explain: &str) {
+pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &str) {
feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
}
@@ -134,8 +134,8 @@ pub fn feature_warn<'a>(sess: &'a ParseSess, feature: Symbol, span: Span, explai
/// Almost always, you want to use this for a language feature. If so, prefer `feature_warn`.
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
-pub fn feature_warn_issue<'a>(
- sess: &'a ParseSess,
+pub fn feature_warn_issue(
+ sess: &ParseSess,
feature: Symbol,
span: Span,
issue: GateIssue,
@@ -160,7 +160,7 @@ pub fn feature_warn_issue<'a>(
}
/// Adds the diagnostics for a feature to an existing error.
-pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, feature: Symbol) {
+pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language);
}
@@ -169,9 +169,9 @@ pub fn add_feature_diagnostics<'a>(err: &mut Diagnostic, sess: &'a ParseSess, fe
/// This variant allows you to control whether it is a library or language feature.
/// Almost always, you want to use this for a language feature. If so, prefer
/// `add_feature_diagnostics`.
-pub fn add_feature_diagnostics_for_issue<'a>(
+pub fn add_feature_diagnostics_for_issue(
err: &mut Diagnostic,
- sess: &'a ParseSess,
+ sess: &ParseSess,
feature: Symbol,
issue: GateIssue,
) {
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 4c049a8d6..95f199de6 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1,12 +1,13 @@
use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
+use crate::config::Input;
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
use crate::errors::{
- CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
- NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
- SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported, SkippingConstChecks,
- SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
+ BranchProtectionRequiresAArch64, CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers,
+ LinkerPluginToWindowsNotSupported, NotCircumventFeature, ProfileSampleUseFileDoesNotExist,
+ ProfileUseFileDoesNotExist, SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
+ SkippingConstChecks, SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
TargetRequiresUnwindTables, UnleashedFeatureHelp, UnstableVirtualFunctionElimination,
UnsupportedDwarfVersion,
};
@@ -137,6 +138,13 @@ pub struct Limits {
pub const_eval_limit: Limit,
}
+pub struct CompilerIO {
+ pub input: Input,
+ pub output_dir: Option<PathBuf>,
+ pub output_file: Option<PathBuf>,
+ pub temps_dir: Option<PathBuf>,
+}
+
/// Represents the data associated with a compilation
/// session for a single crate.
pub struct Session {
@@ -147,9 +155,8 @@ pub struct Session {
pub target_tlib_path: Lrc<SearchPath>,
pub parse_sess: ParseSess,
pub sysroot: PathBuf,
- /// The name of the root source file of the crate, in the local file system.
- /// `None` means that there is no source file.
- pub local_crate_source_file: Option<PathBuf>,
+ /// Input, input file path and output file path to this compilation process.
+ pub io: CompilerIO,
crate_types: OnceCell<Vec<CrateType>>,
/// The `stable_crate_id` is constructed out of the crate name and all the
@@ -197,7 +204,7 @@ pub struct Session {
pub ctfe_backtrace: Lock<CtfeBacktrace>,
/// This tracks where `-Zunleash-the-miri-inside-of-you` was used to get around a
- /// const check, optionally with the relevant feature gate. We use this to
+ /// const check, optionally with the relevant feature gate. We use this to
/// warn about unleashing, but with a single diagnostic instead of dozens that
/// drown everything else in noise.
miri_unleashed_features: Lock<Vec<(Span, Option<Symbol>)>>,
@@ -228,6 +235,11 @@ impl Session {
self.miri_unleashed_features.lock().push((span, feature_gate));
}
+ 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())
+ }
+
fn check_miri_unleashed_features(&self) {
let unleashed_features = self.miri_unleashed_features.lock();
if !unleashed_features.is_empty() {
@@ -590,7 +602,19 @@ impl Session {
pub fn warn(&self, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().warn(msg)
}
- /// Delay a span_bug() call until abort_if_errors()
+
+ /// Ensures that compilation cannot succeed.
+ ///
+ /// If this function has been called but no errors have been emitted and
+ /// compilation succeeds, it will cause an internal compiler error (ICE).
+ ///
+ /// This can be used in code paths that should never run on successful compilations.
+ /// For example, it can be used to create an [`ErrorGuaranteed`]
+ /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly).
+ ///
+ /// If no span is available, use [`DUMMY_SP`].
+ ///
+ /// [`DUMMY_SP`]: rustc_span::DUMMY_SP
#[track_caller]
pub fn delay_span_bug<S: Into<MultiSpan>>(
&self,
@@ -686,6 +710,10 @@ impl Session {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}
+ pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
+ self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
+ }
+
/// Check whether this compile session and crate type use static crt.
pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool {
if !self.target.crt_static_respected {
@@ -972,34 +1000,10 @@ impl Session {
self.opts.unstable_opts.verbose
}
- pub fn instrument_mcount(&self) -> bool {
- self.opts.unstable_opts.instrument_mcount
- }
-
- pub fn time_passes(&self) -> bool {
- self.opts.unstable_opts.time_passes
- }
-
- pub fn time_llvm_passes(&self) -> bool {
- self.opts.unstable_opts.time_llvm_passes
- }
-
- pub fn meta_stats(&self) -> bool {
- self.opts.unstable_opts.meta_stats
- }
-
- pub fn asm_comments(&self) -> bool {
- self.opts.unstable_opts.asm_comments
- }
-
pub fn verify_llvm_ir(&self) -> bool {
self.opts.unstable_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some()
}
- pub fn print_llvm_passes(&self) -> bool {
- self.opts.unstable_opts.print_llvm_passes
- }
-
pub fn binary_dep_depinfo(&self) -> bool {
self.opts.unstable_opts.binary_dep_depinfo
}
@@ -1306,7 +1310,7 @@ fn default_emitter(
#[allow(rustc::bad_opt_access)]
pub fn build_session(
sopts: config::Options,
- local_crate_source_file: Option<PathBuf>,
+ io: CompilerIO,
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -1319,7 +1323,7 @@ pub fn build_session(
let warnings_allow = sopts
.lint_opts
.iter()
- .rfind(|&&(ref key, _)| *key == "warnings")
+ .rfind(|&(key, _)| *key == "warnings")
.map_or(false, |&(_, level)| level == lint::Allow);
let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow);
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
@@ -1399,11 +1403,6 @@ pub fn build_session(
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
};
- let file_path_mapping = sopts.file_path_mapping();
-
- let local_crate_source_file =
- local_crate_source_file.map(|path| file_path_mapping.map_prefix(path).0);
-
let optimization_fuel = Lock::new(OptimizationFuel {
remaining: sopts.unstable_opts.fuel.as_ref().map_or(0, |&(_, i)| i),
out_of_fuel: false,
@@ -1435,7 +1434,7 @@ pub fn build_session(
target_tlib_path,
parse_sess,
sysroot,
- local_crate_source_file,
+ io,
crate_types: OnceCell::new(),
stable_crate_id: OnceCell::new(),
features: OnceCell::new(),
@@ -1544,6 +1543,14 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}
+ // LLVM CFI and KCFI are mutually exclusive
+ if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
+ sess.emit_err(CannotMixAndMatchSanitizers {
+ first: "cfi".to_string(),
+ second: "kcfi".to_string(),
+ });
+ }
+
if sess.opts.unstable_opts.stack_protector != StackProtector::None {
if !sess.target.options.supports_stack_protector {
sess.emit_warning(StackProtectorNotSupportedForTarget {
@@ -1553,6 +1560,10 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}
+ if sess.opts.unstable_opts.branch_protection.is_some() && sess.target.arch != "aarch64" {
+ sess.emit_err(BranchProtectionRequiresAArch64);
+ }
+
if let Some(dwarf_version) = sess.opts.unstable_opts.dwarf_version {
if dwarf_version > 5 {
sess.emit_err(UnsupportedDwarfVersion { dwarf_version });
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index e65b6891e..b996d36a3 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::profiling::VerboseTimingGuard;
use std::path::{Path, PathBuf};
impl Session {
- pub fn timer<'a>(&'a self, what: &'static str) -> VerboseTimingGuard<'a> {
+ pub fn timer(&self, what: &'static str) -> VerboseTimingGuard<'_> {
self.prof.verbose_generic_activity(what)
}
pub fn time<R>(&self, what: &'static str, f: impl FnOnce() -> R) -> R {