diff options
Diffstat (limited to 'compiler/rustc_session/src')
-rw-r--r-- | compiler/rustc_session/src/code_stats.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_session/src/config.rs | 150 | ||||
-rw-r--r-- | compiler/rustc_session/src/cstore.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_session/src/errors.rs | 19 | ||||
-rw-r--r-- | compiler/rustc_session/src/lib.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_session/src/options.rs | 16 | ||||
-rw-r--r-- | compiler/rustc_session/src/output.rs | 13 | ||||
-rw-r--r-- | compiler/rustc_session/src/parse.rs | 35 | ||||
-rw-r--r-- | compiler/rustc_session/src/session.rs | 154 | ||||
-rw-r--r-- | compiler/rustc_session/src/utils.rs | 1 |
10 files changed, 203 insertions, 194 deletions
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) } |