summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session')
-rw-r--r--compiler/rustc_session/Cargo.toml1
-rw-r--r--compiler/rustc_session/messages.ftl7
-rw-r--r--compiler/rustc_session/src/code_stats.rs6
-rw-r--r--compiler/rustc_session/src/config.rs150
-rw-r--r--compiler/rustc_session/src/cstore.rs2
-rw-r--r--compiler/rustc_session/src/errors.rs19
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/options.rs16
-rw-r--r--compiler/rustc_session/src/output.rs13
-rw-r--r--compiler/rustc_session/src/parse.rs35
-rw-r--r--compiler/rustc_session/src/session.rs154
-rw-r--r--compiler/rustc_session/src/utils.rs1
12 files changed, 209 insertions, 196 deletions
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 1291d1454..e26d25d9a 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -4,7 +4,6 @@ version = "0.0.0"
edition = "2021"
[dependencies]
-atty = "0.2.13"
bitflags = "1.2.1"
getopts = "0.2"
rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 4897bd8d5..b07c6db59 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -26,6 +26,8 @@ session_feature_gate_error = {$explain}
session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
+session_file_write_fail = failed to write `{$path}` due to error `{$err}`
+
session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target
@@ -43,6 +45,7 @@ session_int_literal_too_large = integer literal is too large
.note = value exceeds limit of `{$limit}`
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
+session_invalid_character_in_create_name_help = you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name
session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
.label = invalid suffix `{$suffix}`
@@ -86,7 +89,9 @@ session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-genera
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
-session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`
+session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
+
+session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs
index cabe1c96b..df81e1f83 100644
--- a/compiler/rustc_session/src/code_stats.rs
+++ b/compiler/rustc_session/src/code_stats.rs
@@ -227,10 +227,8 @@ impl CodeStats {
}
pub fn print_vtable_sizes(&self, crate_name: &str) {
- let mut infos = std::mem::take(&mut *self.vtable_sizes.lock())
- .into_iter()
- .map(|(_did, stats)| stats)
- .collect::<Vec<_>>();
+ let mut infos =
+ std::mem::take(&mut *self.vtable_sizes.lock()).into_values().collect::<Vec<_>>();
// Primary sort: cost % in reverse order (from largest to smallest)
// Secondary sort: trait_name
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f97cb3440..f00472f18 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3,6 +3,7 @@
pub use crate::options::*;
+use crate::errors::FileWriteFail;
use crate::search_paths::SearchPath;
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{lint, HashStableContext};
@@ -11,7 +12,7 @@ use crate::{EarlyErrorHandler, Session};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
use rustc_target::abi::Align;
-use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
+use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
use crate::parse::{CrateCheckConfig, CrateConfig};
@@ -31,6 +32,7 @@ use std::collections::btree_map::{
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::OsStr;
use std::fmt;
+use std::fs;
use std::hash::Hash;
use std::iter;
use std::path::{Path, PathBuf};
@@ -277,11 +279,11 @@ impl LinkSelfContained {
// 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("+") {
+ if let Some(component_to_enable) = component.strip_prefix('+') {
self.explicitly_set = None;
self.components.insert(component_to_enable.parse()?);
Ok(())
- } else if let Some(component_to_disable) = component.strip_prefix("-") {
+ } else if let Some(component_to_disable) = component.strip_prefix('-') {
self.explicitly_set = None;
self.components.remove(component_to_disable.parse()?);
Ok(())
@@ -710,8 +712,14 @@ impl ExternEntry {
}
}
+#[derive(Clone, PartialEq, Debug)]
+pub struct PrintRequest {
+ pub kind: PrintKind,
+ pub out: OutFileName,
+}
+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum PrintRequest {
+pub enum PrintKind {
FileNames,
Sysroot,
TargetLibdir,
@@ -826,9 +834,10 @@ impl OutFileName {
}
pub fn is_tty(&self) -> bool {
+ use std::io::IsTerminal;
match *self {
OutFileName::Real(_) => false,
- OutFileName::Stdout => atty::is(atty::Stream::Stdout),
+ OutFileName::Stdout => std::io::stdout().is_terminal(),
}
}
@@ -855,6 +864,17 @@ impl OutFileName {
OutFileName::Stdout => outputs.temp_path(flavor, codegen_unit_name),
}
}
+
+ pub fn overwrite(&self, content: &str, sess: &Session) {
+ match self {
+ OutFileName::Stdout => print!("{content}"),
+ OutFileName::Real(path) => {
+ if let Err(e) = fs::write(path, content) {
+ sess.emit_fatal(FileWriteFail { path, err: e.to_string() });
+ }
+ }
+ }
+ }
}
#[derive(Clone, Hash, Debug, HashStable_Generic)]
@@ -1173,6 +1193,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
let os = &sess.target.os;
let env = &sess.target.env;
let abi = &sess.target.abi;
+ let relocation_model = sess.target.relocation_model.desc_symbol();
let vendor = &sess.target.vendor;
let min_atomic_width = sess.target.min_atomic_width();
let max_atomic_width = sess.target.max_atomic_width();
@@ -1198,6 +1219,9 @@ fn default_configuration(sess: &Session) -> CrateConfig {
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
ret.insert((sym::target_env, Some(Symbol::intern(env))));
ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
+ if sess.is_nightly_build() {
+ ret.insert((sym::relocation_model, Some(relocation_model)));
+ }
ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
if sess.target.has_thread_local {
ret.insert((sym::target_thread_local, None));
@@ -1395,6 +1419,8 @@ impl CrateCheckConfig {
.into_iter()
.map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));
+ let relocation_model_values = RelocModel::all();
+
// Unknown possible values:
// - `feature`
// - `target_feature`
@@ -1433,6 +1459,10 @@ impl CrateCheckConfig {
.entry(sym::target_has_atomic_equal_alignment)
.or_insert_with(no_values)
.extend(atomic_values);
+ self.expecteds
+ .entry(sym::relocation_model)
+ .or_insert_with(empty_values)
+ .extend(relocation_model_values);
// Target specific values
{
@@ -1519,9 +1549,8 @@ pub(super) fn build_target_config(
);
let (target, target_warnings) = target_result.unwrap_or_else(|e| {
handler.early_error(format!(
- "Error loading target specification: {}. \
- Run `rustc --print target-list` for a list of built-in targets",
- e
+ "Error loading target specification: {e}. \
+ Run `rustc --print target-list` for a list of built-in targets"
))
});
for warning in target_warnings.warning_messages() {
@@ -1958,8 +1987,7 @@ pub fn parse_crate_edition(handler: &EarlyErrorHandler, matches: &getopts::Match
let is_nightly = nightly_options::match_is_nightly_build(matches);
let msg = if !is_nightly {
format!(
- "the crate requires edition {}, but the latest edition supported by this Rust version is {}",
- edition, LATEST_STABLE_EDITION
+ "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
)
} else {
format!("edition {edition} is unstable and only available with -Z unstable-options")
@@ -2005,13 +2033,7 @@ fn parse_output_types(
if !unstable_opts.parse_only {
for list in matches.opt_strs("emit") {
for output_type in list.split(',') {
- let (shorthand, path) = match output_type.split_once('=') {
- None => (output_type, None),
- Some((shorthand, "-")) => (shorthand, Some(OutFileName::Stdout)),
- Some((shorthand, path)) => {
- (shorthand, Some(OutFileName::Real(PathBuf::from(path))))
- }
- };
+ let (shorthand, path) = split_out_file_name(output_type);
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
handler.early_error(format!(
"unknown emission type: `{shorthand}` - expected one of: {display}",
@@ -2028,6 +2050,14 @@ fn parse_output_types(
OutputTypes(output_types)
}
+fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
+ match arg.split_once('=') {
+ None => (arg, None),
+ Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
+ Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
+ }
+}
+
fn should_override_cgus_and_disable_thinlto(
handler: &EarlyErrorHandler,
output_types: &OutputTypes,
@@ -2091,41 +2121,55 @@ fn collect_print_requests(
) -> Vec<PrintRequest> {
let mut prints = Vec::<PrintRequest>::new();
if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
- prints.push(PrintRequest::TargetCPUs);
+ prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout });
cg.target_cpu = None;
};
if cg.target_feature == "help" {
- prints.push(PrintRequest::TargetFeatures);
+ prints.push(PrintRequest { kind: PrintKind::TargetFeatures, out: OutFileName::Stdout });
cg.target_feature = String::new();
}
- const PRINT_REQUESTS: &[(&str, PrintRequest)] = &[
- ("crate-name", PrintRequest::CrateName),
- ("file-names", PrintRequest::FileNames),
- ("sysroot", PrintRequest::Sysroot),
- ("target-libdir", PrintRequest::TargetLibdir),
- ("cfg", PrintRequest::Cfg),
- ("calling-conventions", PrintRequest::CallingConventions),
- ("target-list", PrintRequest::TargetList),
- ("target-cpus", PrintRequest::TargetCPUs),
- ("target-features", PrintRequest::TargetFeatures),
- ("relocation-models", PrintRequest::RelocationModels),
- ("code-models", PrintRequest::CodeModels),
- ("tls-models", PrintRequest::TlsModels),
- ("native-static-libs", PrintRequest::NativeStaticLibs),
- ("stack-protector-strategies", PrintRequest::StackProtectorStrategies),
- ("target-spec-json", PrintRequest::TargetSpec),
- ("all-target-specs-json", PrintRequest::AllTargetSpecs),
- ("link-args", PrintRequest::LinkArgs),
- ("split-debuginfo", PrintRequest::SplitDebuginfo),
- ("deployment-target", PrintRequest::DeploymentTarget),
+ const PRINT_KINDS: &[(&str, PrintKind)] = &[
+ ("crate-name", PrintKind::CrateName),
+ ("file-names", PrintKind::FileNames),
+ ("sysroot", PrintKind::Sysroot),
+ ("target-libdir", PrintKind::TargetLibdir),
+ ("cfg", PrintKind::Cfg),
+ ("calling-conventions", PrintKind::CallingConventions),
+ ("target-list", PrintKind::TargetList),
+ ("target-cpus", PrintKind::TargetCPUs),
+ ("target-features", PrintKind::TargetFeatures),
+ ("relocation-models", PrintKind::RelocationModels),
+ ("code-models", PrintKind::CodeModels),
+ ("tls-models", PrintKind::TlsModels),
+ ("native-static-libs", PrintKind::NativeStaticLibs),
+ ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
+ ("target-spec-json", PrintKind::TargetSpec),
+ ("all-target-specs-json", PrintKind::AllTargetSpecs),
+ ("link-args", PrintKind::LinkArgs),
+ ("split-debuginfo", PrintKind::SplitDebuginfo),
+ ("deployment-target", PrintKind::DeploymentTarget),
];
+ // We disallow reusing the same path in multiple prints, such as `--print
+ // cfg=output.txt --print link-args=output.txt`, because outputs are printed
+ // by disparate pieces of the compiler, and keeping track of which files
+ // need to be overwritten vs appended to is annoying.
+ let mut printed_paths = FxHashSet::default();
+
prints.extend(matches.opt_strs("print").into_iter().map(|req| {
- match PRINT_REQUESTS.iter().find(|&&(name, _)| name == req) {
- Some((_, PrintRequest::TargetSpec)) => {
+ let (req, out) = split_out_file_name(&req);
+
+ if out.is_some() && !unstable_opts.unstable_options {
+ handler.early_error(
+ "the `-Z unstable-options` flag must also be passed to \
+ enable the path print option",
+ );
+ }
+ let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) {
+ Some((_, PrintKind::TargetSpec)) => {
if unstable_opts.unstable_options {
- PrintRequest::TargetSpec
+ PrintKind::TargetSpec
} else {
handler.early_error(
"the `-Z unstable-options` flag must also be passed to \
@@ -2133,9 +2177,9 @@ fn collect_print_requests(
);
}
}
- Some((_, PrintRequest::AllTargetSpecs)) => {
+ Some((_, PrintKind::AllTargetSpecs)) => {
if unstable_opts.unstable_options {
- PrintRequest::AllTargetSpecs
+ PrintKind::AllTargetSpecs
} else {
handler.early_error(
"the `-Z unstable-options` flag must also be passed to \
@@ -2143,16 +2187,28 @@ fn collect_print_requests(
);
}
}
- Some(&(_, print_request)) => print_request,
+ Some(&(_, print_kind)) => print_kind,
None => {
let prints =
- PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
+ PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
handler.early_error(format!(
"unknown print request `{req}`. Valid print requests are: {prints}"
));
}
+ };
+
+ let out = out.unwrap_or(OutFileName::Stdout);
+ if let OutFileName::Real(path) = &out {
+ if !printed_paths.insert(path.clone()) {
+ handler.early_error(format!(
+ "cannot print multiple outputs to the same path: {}",
+ path.display(),
+ ));
+ }
}
+
+ PrintRequest { kind, out }
}));
prints
@@ -2524,6 +2580,8 @@ pub fn build_session_options(
let error_format = parse_error_format(handler, matches, color, json_rendered);
+ handler.abort_if_error_and_set_error_format(error_format);
+
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
handler.early_error("`--diagnostic-width` must be an positive integer");
});
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index dc475e8c6..c53a355b5 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -13,6 +13,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
use rustc_span::hygiene::{ExpnHash, ExpnId};
use rustc_span::symbol::Symbol;
use rustc_span::Span;
+use rustc_target::spec::abi::Abi;
use rustc_target::spec::Target;
use std::any::Any;
@@ -147,6 +148,7 @@ pub enum DllCallingConvention {
pub struct ForeignModule {
pub foreign_items: Vec<DefId>,
pub def_id: DefId,
+ pub abi: Abi,
}
#[derive(Copy, Clone, Debug, HashStable_Generic)]
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 4a3e668da..78940462b 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -115,6 +115,10 @@ pub struct CannotEnableCrtStaticLinux;
pub struct SanitizerCfiRequiresLto;
#[derive(Diagnostic)]
+#[diag(session_sanitizer_cfi_requires_single_codegen_unit)]
+pub struct SanitizerCfiRequiresSingleCodegenUnit;
+
+#[derive(Diagnostic)]
#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)]
pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi;
@@ -164,6 +168,13 @@ pub struct FileIsNotWriteable<'a> {
}
#[derive(Diagnostic)]
+#[diag(session_file_write_fail)]
+pub(crate) struct FileWriteFail<'a> {
+ pub path: &'a std::path::Path,
+ pub err: String,
+}
+
+#[derive(Diagnostic)]
#[diag(session_crate_name_does_not_match)]
pub struct CrateNameDoesNotMatch {
#[primary_span]
@@ -192,6 +203,14 @@ pub struct InvalidCharacterInCrateName {
pub span: Option<Span>,
pub character: char,
pub crate_name: Symbol,
+ #[subdiagnostic]
+ pub crate_name_help: Option<InvalidCrateNameHelp>,
+}
+
+#[derive(Subdiagnostic)]
+pub enum InvalidCrateNameHelp {
+ #[help(session_invalid_character_in_create_name_help)]
+ AddCrateName,
}
#[derive(Subdiagnostic)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index d57aa820f..a270817f3 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -10,6 +10,7 @@
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
+#![cfg_attr(not(bootstrap), allow(internal_features))]
#[macro_use]
extern crate rustc_macros;
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 7840a0ecf..055ab2d9c 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -330,8 +330,7 @@ fn build_options<O: Default>(
match value {
None => handler.early_error(
format!(
- "{0} option `{1}` requires {2} ({3} {1}=<value>)",
- outputname, key, type_desc, prefix
+ "{outputname} option `{key}` requires {type_desc} ({prefix} {key}=<value>)"
),
),
Some(value) => handler.early_error(
@@ -1145,7 +1144,7 @@ mod parse {
}
// 2. Parse a list of enabled and disabled components.
- for comp in s.split(",") {
+ for comp in s.split(',') {
if slot.handle_cli_component(comp).is_err() {
return false;
}
@@ -1433,8 +1432,6 @@ options! {
dep_tasks: bool = (false, parse_bool, [UNTRACKED],
"print tasks that execute and the color their dep node gets (requires debug build) \
(default: no)"),
- diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
- "set the current output width for diagnostic truncation"),
dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
"emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \
(default: no)"),
@@ -1583,9 +1580,6 @@ 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`)"),
- lower_impl_trait_in_trait_to_assoc_ty: bool = (false, parse_bool, [TRACKED],
- "modify the lowering strategy for `impl Trait` in traits so that they are lowered to \
- generic associated types"),
ls: bool = (false, parse_bool, [UNTRACKED],
"list the symbols defined by a library crate (default: no)"),
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
@@ -1671,6 +1665,9 @@ options! {
"use a more precise version of drop elaboration for matches on enums (default: yes). \
This results in better codegen, but has caused miscompilations on some tier 2 platforms. \
See #77382 and #74551."),
+ #[rustc_lint_opt_deny_field_access("use `Session::print_codegen_stats` instead of this field")]
+ print_codegen_stats: bool = (false, parse_bool, [UNTRACKED],
+ "print codegen statistics (default: no)"),
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
"make rustc print the total optimization fuel used by a crate"),
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
@@ -1878,10 +1875,13 @@ written to standard error output)"),
Requires `-Clto[=[fat,yes]]`"),
wasi_exec_model: Option<WasiExecModel> = (None, parse_wasi_exec_model, [TRACKED],
"whether to build a wasi command or reactor"),
+ write_long_types_to_disk: bool = (true, parse_bool, [UNTRACKED],
+ "whether long type names should be written to files instead of being printed in errors"),
// tidy-alphabetical-end
// If you add a new option, please update:
// - compiler/rustc_interface/src/tests.rs
+ // - src/doc/unstable-book/src/compiler-flags
}
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index 2088744bc..c0884fb21 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -2,7 +2,7 @@
use crate::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
use crate::errors::{
CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable,
- InvalidCharacterInCrateName,
+ InvalidCharacterInCrateName, InvalidCrateNameHelp,
};
use crate::Session;
use rustc_ast::{self as ast, attr};
@@ -101,7 +101,16 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
continue;
}
err_count += 1;
- sess.emit_err(InvalidCharacterInCrateName { span: sp, character: c, crate_name: s });
+ sess.emit_err(InvalidCharacterInCrateName {
+ span: sp,
+ character: c,
+ crate_name: s,
+ crate_name_help: if sp.is_none() {
+ Some(InvalidCrateNameHelp::AddCrateName)
+ } else {
+ None
+ },
+ });
}
}
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 194f7201f..1cf63e9b7 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -8,8 +8,8 @@ use crate::lint::{
};
use rustc_ast::node_id::NodeId;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc};
-use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
+use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
+use rustc_errors::{emitter::SilentEmitter, Handler};
use rustc_errors::{
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, Noted, StashKey,
@@ -117,6 +117,7 @@ pub fn feature_err_issue(
/// Construct a future incompatibility diagnostic for a feature gate.
///
/// This diagnostic is only a warning and *does not cause compilation to fail*.
+#[track_caller]
pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'static str) {
feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
}
@@ -129,6 +130,7 @@ pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'st
/// 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)]
+#[track_caller]
pub fn feature_warn_issue(
sess: &ParseSess,
feature: Symbol,
@@ -202,8 +204,6 @@ pub struct ParseSess {
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
pub gated_spans: GatedSpans,
pub symbol_gallery: SymbolGallery,
- /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
- pub reached_eof: AtomicBool,
/// Environment variables accessed during the build and their values when they exist.
pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
/// File paths accessed during the build.
@@ -222,14 +222,7 @@ impl ParseSess {
pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self {
let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
let sm = Lrc::new(SourceMap::new(file_path_mapping));
- let handler = Handler::with_tty_emitter(
- ColorConfig::Auto,
- true,
- None,
- Some(sm.clone()),
- None,
- fallback_bundle,
- );
+ let handler = Handler::with_tty_emitter(Some(sm.clone()), fallback_bundle);
ParseSess::with_span_handler(handler, sm)
}
@@ -247,7 +240,6 @@ impl ParseSess {
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
gated_spans: GatedSpans::default(),
symbol_gallery: SymbolGallery::default(),
- reached_eof: AtomicBool::new(false),
env_depinfo: Default::default(),
file_depinfo: Default::default(),
assume_incomplete_release: false,
@@ -259,13 +251,9 @@ impl ParseSess {
pub fn with_silent_emitter(fatal_note: Option<String>) -> Self {
let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
- let fatal_handler =
- Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle);
- let handler = Handler::with_emitter(
- false,
- None,
- Box::new(SilentEmitter { fatal_handler, fatal_note }),
- );
+ let fatal_handler = Handler::with_tty_emitter(None, fallback_bundle).disable_warnings();
+ let handler = Handler::with_emitter(Box::new(SilentEmitter { fatal_handler, fatal_note }))
+ .disable_warnings();
ParseSess::with_span_handler(handler, sm)
}
@@ -351,6 +339,7 @@ impl ParseSess {
self.create_warning(warning).emit()
}
+ #[track_caller]
pub fn create_note<'a>(
&'a self,
note: impl IntoDiagnostic<'a, Noted>,
@@ -358,10 +347,12 @@ impl ParseSess {
note.into_diagnostic(&self.span_diagnostic)
}
+ #[track_caller]
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
self.create_note(note).emit()
}
+ #[track_caller]
pub fn create_fatal<'a>(
&'a self,
fatal: impl IntoDiagnostic<'a, !>,
@@ -369,6 +360,7 @@ impl ParseSess {
fatal.into_diagnostic(&self.span_diagnostic)
}
+ #[track_caller]
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! {
self.create_fatal(fatal).emit()
}
@@ -383,16 +375,19 @@ impl ParseSess {
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.span_diagnostic.struct_warn(msg)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
self.span_diagnostic.struct_fatal(msg)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_diagnostic<G: EmissionGuarantee>(
&self,
msg: impl Into<DiagnosticMessage>,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 5be122ffb..086ce4e69 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -17,7 +17,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::jobserver::{self, Client};
use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
use rustc_data_structures::sync::{
- self, AtomicU64, AtomicUsize, Lock, Lrc, OnceCell, OneThread, Ordering, Ordering::SeqCst,
+ self, AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
};
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
@@ -152,16 +152,6 @@ pub struct Session {
/// 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
- /// `-C metadata` arguments passed to the compiler. Its value forms a unique
- /// global identifier for the crate. It is used to allow multiple crates
- /// with the same name to coexist. See the
- /// `rustc_symbol_mangling` crate for more information.
- pub stable_crate_id: OnceCell<StableCrateId>,
-
- features: OnceCell<rustc_feature::Features>,
-
incr_comp_session: OneThread<RefCell<IncrCompSession>>,
/// Used for incremental compilation tests. Will only be populated if
/// `-Zquery-dep-graph` is specified.
@@ -310,55 +300,11 @@ impl Session {
self.parse_sess.span_diagnostic.emit_future_breakage_report(diags);
}
- pub fn local_stable_crate_id(&self) -> StableCrateId {
- self.stable_crate_id.get().copied().unwrap()
- }
-
- pub fn crate_types(&self) -> &[CrateType] {
- self.crate_types.get().unwrap().as_slice()
- }
-
/// Returns true if the crate is a testing one.
pub fn is_test_crate(&self) -> bool {
self.opts.test
}
- pub fn needs_crate_hash(&self) -> bool {
- // Why is the crate hash needed for these configurations?
- // - debug_assertions: for the "fingerprint the result" check in
- // `rustc_query_system::query::plumbing::execute_job`.
- // - incremental: for query lookups.
- // - needs_metadata: for putting into crate metadata.
- // - instrument_coverage: for putting into coverage data (see
- // `hash_mir_source`).
- cfg!(debug_assertions)
- || self.opts.incremental.is_some()
- || self.needs_metadata()
- || self.instrument_coverage()
- }
-
- pub fn metadata_kind(&self) -> MetadataKind {
- self.crate_types()
- .iter()
- .map(|ty| match *ty {
- CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => {
- MetadataKind::None
- }
- CrateType::Rlib => MetadataKind::Uncompressed,
- CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed,
- })
- .max()
- .unwrap_or(MetadataKind::None)
- }
-
- pub fn needs_metadata(&self) -> bool {
- self.metadata_kind() != MetadataKind::None
- }
-
- pub fn init_crate_types(&self, crate_types: Vec<CrateType>) {
- self.crate_types.set(crate_types).expect("`crate_types` was initialized twice")
- }
-
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_warn<S: Into<MultiSpan>>(
@@ -677,7 +623,7 @@ impl Session {
pub fn delay_span_bug<S: Into<MultiSpan>>(
&self,
sp: S,
- msg: impl Into<DiagnosticMessage>,
+ msg: impl Into<String>,
) -> ErrorGuaranteed {
self.diagnostic().delay_span_bug(sp, msg)
}
@@ -757,21 +703,6 @@ impl Session {
self.opts.cg.instrument_coverage() == InstrumentCoverage::ExceptUnusedFunctions
}
- /// Gets the features enabled for the current compilation session.
- /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
- /// dependency tracking. Use tcx.features() instead.
- #[inline]
- pub fn features_untracked(&self) -> &rustc_feature::Features {
- self.features.get().unwrap()
- }
-
- pub fn init_features(&self, features: rustc_feature::Features) {
- match self.features.set(features) {
- Ok(()) => {}
- Err(_) => panic!("`features` was initialized twice"),
- }
- }
-
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
}
@@ -995,18 +926,18 @@ impl Session {
}
/// Are we allowed to use features from the Rust 2018 edition?
- pub fn rust_2018(&self) -> bool {
- self.edition().rust_2018()
+ pub fn at_least_rust_2018(&self) -> bool {
+ self.edition().at_least_rust_2018()
}
/// Are we allowed to use features from the Rust 2021 edition?
- pub fn rust_2021(&self) -> bool {
- self.edition().rust_2021()
+ pub fn at_least_rust_2021(&self) -> bool {
+ self.edition().at_least_rust_2021()
}
/// Are we allowed to use features from the Rust 2024 edition?
- pub fn rust_2024(&self) -> bool {
- self.edition().rust_2024()
+ pub fn at_least_rust_2024(&self) -> bool {
+ self.edition().at_least_rust_2024()
}
/// Returns `true` if we should use the PLT for shared library calls.
@@ -1057,6 +988,10 @@ impl Session {
self.opts.unstable_opts.verbose
}
+ pub fn print_llvm_stats(&self) -> bool {
+ self.opts.unstable_opts.print_codegen_stats
+ }
+
pub fn verify_llvm_ir(&self) -> bool {
self.opts.unstable_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some()
}
@@ -1346,18 +1281,15 @@ fn default_emitter(
);
Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
} else {
- let emitter = EmitterWriter::stderr(
- color_config,
- Some(source_map),
- bundle,
- fallback_bundle,
- short,
- sopts.unstable_opts.teach,
- sopts.diagnostic_width,
- macro_backtrace,
- track_diagnostics,
- terminal_url,
- );
+ let emitter = EmitterWriter::stderr(color_config, fallback_bundle)
+ .fluent_bundle(bundle)
+ .sm(Some(source_map))
+ .short_message(short)
+ .teach(sopts.unstable_opts.teach)
+ .diagnostic_width(sopts.diagnostic_width)
+ .macro_backtrace(macro_backtrace)
+ .track_diagnostics(track_diagnostics)
+ .terminal_url(terminal_url);
Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
}
}
@@ -1392,6 +1324,7 @@ pub fn build_session(
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>,
cfg_version: &'static str,
+ ice_file: Option<PathBuf>,
) -> Session {
// FIXME: This is not general enough to make the warning lint completely override
// normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -1420,7 +1353,7 @@ pub fn build_session(
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| {
if target_cfg.is_like_msvc {
- SourceFileHashAlgorithm::Sha1
+ SourceFileHashAlgorithm::Sha256
} else {
SourceFileHashAlgorithm::Md5
}
@@ -1437,10 +1370,11 @@ pub fn build_session(
);
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
- let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
- emitter,
- sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings),
- );
+ let mut span_diagnostic = rustc_errors::Handler::with_emitter(emitter)
+ .with_flags(sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings));
+ if let Some(ice_file) = ice_file {
+ span_diagnostic = span_diagnostic.with_ice_file(ice_file);
+ }
let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.unstable_opts.self_profile
{
@@ -1513,9 +1447,6 @@ pub fn build_session(
parse_sess,
sysroot,
io,
- crate_types: OnceCell::new(),
- stable_crate_id: OnceCell::new(),
- features: OnceCell::new(),
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
cgu_reuse_tracker,
prof,
@@ -1616,13 +1547,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
// LLVM CFI requires LTO.
if sess.is_sanitizer_cfi_enabled()
- && !(sess.lto() == config::Lto::Fat
- || sess.lto() == config::Lto::Thin
- || sess.opts.cg.linker_plugin_lto.enabled())
+ && !(sess.lto() == config::Lto::Fat || sess.opts.cg.linker_plugin_lto.enabled())
{
sess.emit_err(errors::SanitizerCfiRequiresLto);
}
+ // LLVM CFI using rustc LTO requires a single codegen unit.
+ if sess.is_sanitizer_cfi_enabled()
+ && sess.lto() == config::Lto::Fat
+ && !(sess.codegen_units().as_usize() == 1)
+ {
+ sess.emit_err(errors::SanitizerCfiRequiresSingleCodegenUnit);
+ }
+
// LLVM CFI is incompatible with LLVM KCFI.
if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
sess.emit_err(errors::CannotMixAndMatchSanitizers {
@@ -1731,7 +1668,7 @@ pub struct EarlyErrorHandler {
impl EarlyErrorHandler {
pub fn new(output: ErrorOutputType) -> Self {
let emitter = mk_emitter(output);
- Self { handler: rustc_errors::Handler::with_emitter(true, None, emitter) }
+ Self { handler: rustc_errors::Handler::with_emitter(emitter) }
}
pub fn abort_if_errors(&self) {
@@ -1745,7 +1682,7 @@ impl EarlyErrorHandler {
self.handler.abort_if_errors();
let emitter = mk_emitter(output);
- self.handler = Handler::with_emitter(true, None, emitter);
+ self.handler = Handler::with_emitter(emitter);
}
#[allow(rustc::untranslatable_diagnostic)]
@@ -1788,18 +1725,7 @@ fn mk_emitter(output: ErrorOutputType) -> Box<dyn Emitter + sync::Send + 'static
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
- Box::new(EmitterWriter::stderr(
- color_config,
- None,
- None,
- fallback_bundle,
- short,
- false,
- None,
- false,
- false,
- TerminalUrl::No,
- ))
+ Box::new(EmitterWriter::stderr(color_config, fallback_bundle).short_message(short))
}
config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic(
pretty,
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 1d15e2c28..71f2591fe 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -7,6 +7,7 @@ impl Session {
pub fn timer(&self, what: &'static str) -> VerboseTimingGuard<'_> {
self.prof.verbose_generic_activity(what)
}
+ /// Used by `-Z self-profile`.
pub fn time<R>(&self, what: &'static str, f: impl FnOnce() -> R) -> R {
self.prof.verbose_generic_activity(what).run(f)
}