diff options
Diffstat (limited to 'compiler/rustc_session/src/session.rs')
-rw-r--r-- | compiler/rustc_session/src/session.rs | 303 |
1 files changed, 155 insertions, 148 deletions
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 80a549b30..7f168572f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,7 +1,7 @@ use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use crate::config::{ - self, CrateType, InstrumentCoverage, OptLevel, OutFileName, OutputType, + self, CrateType, FunctionReturn, InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents, SwitchWithOptPath, }; use crate::config::{ErrorOutputType, Input}; @@ -10,23 +10,21 @@ use crate::parse::{add_feature_diagnostics, ParseSess}; use crate::search_paths::{PathKind, SearchPath}; use crate::{filesearch, lint}; -pub use rustc_ast::attr::MarkedAttrs; -pub use rustc_ast::Attribute; use rustc_data_structures::flock; 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::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{ - AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst, + AtomicU64, DynSend, DynSync, Lock, Lrc, OneThread, Ordering::SeqCst, }; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter; use rustc_errors::emitter::{DynEmitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ - error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - ErrorGuaranteed, FluentBundle, Handler, IntoDiagnostic, LazyFallbackBundle, MultiSpan, Noted, - TerminalUrl, + error_code, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticId, + DiagnosticMessage, ErrorGuaranteed, FluentBundle, IntoDiagnostic, LazyFallbackBundle, + MultiSpan, Noted, TerminalUrl, }; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; @@ -39,6 +37,7 @@ use rustc_target::spec::{ DebuginfoKind, SanitizerSet, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel, }; +use std::any::Any; use std::cell::{self, RefCell}; use std::env; use std::fmt; @@ -46,9 +45,8 @@ use std::ops::{Div, Mul}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::{atomic::AtomicBool, Arc}; -use std::time::Duration; -pub struct OptimizationFuel { +struct OptimizationFuel { /// If `-zfuel=crate=n` is specified, initially set to `n`, otherwise `0`. remaining: u64, /// We're rejecting all further optimizations. @@ -139,6 +137,8 @@ pub struct CompilerIO { pub temps_dir: Option<PathBuf>, } +pub trait LintStoreMarker: Any + DynSync + DynSend {} + /// Represents the data associated with a compilation /// session for a single crate. pub struct Session { @@ -157,9 +157,6 @@ pub struct Session { /// Used by `-Z self-profile`. pub prof: SelfProfilerRef, - /// Some measurements that are being gathered during compilation. - pub perf_stats: PerfStats, - /// Data about code being compiled, gathered during compilation. pub code_stats: CodeStats, @@ -173,6 +170,12 @@ pub struct Session { /// false positives about a job server in our environment. pub jobserver: Client, + /// This only ever stores a `LintStore` but we don't want a dependency on that type here. + pub lint_store: Option<Lrc<dyn LintStoreMarker>>, + + /// Should be set if any lints are registered in `lint_store`. + pub registered_lints: bool, + /// Cap lint level specified by a driver specifically. pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>, @@ -215,17 +218,6 @@ pub struct Session { pub expanded_args: Vec<String>, } -pub struct PerfStats { - /// The accumulated time spent on computing symbol hashes. - pub symbol_hash_time: Lock<Duration>, - /// Total number of values canonicalized queries constructed. - pub queries_canonicalized: AtomicUsize, - /// Number of times this query is invoked. - pub normalize_generic_arg_after_erasing_regions: AtomicUsize, - /// Number of times this query is invoked. - pub normalize_projection_ty: AtomicUsize, -} - #[derive(PartialEq, Eq, PartialOrd, Ord)] pub enum MetadataKind { None, @@ -297,7 +289,7 @@ impl Session { /// Invoked all the way at the end to finish off diagnostics printing. pub fn finish_diagnostics(&self, registry: &Registry) { self.check_miri_unleashed_features(); - self.diagnostic().print_error_count(registry); + self.dcx().print_error_count(registry); self.emit_future_breakage(); } @@ -306,11 +298,11 @@ impl Session { return; } - let diags = self.diagnostic().take_future_breakage_diagnostics(); + let diags = self.dcx().take_future_breakage_diagnostics(); if diags.is_empty() { return; } - self.parse_sess.span_diagnostic.emit_future_breakage_report(diags); + self.dcx().emit_future_breakage_report(diags); } /// Returns true if the crate is a testing one. @@ -325,7 +317,7 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_span_warn(sp, msg) + self.dcx().struct_span_warn(sp, msg) } #[rustc_lint_diagnostics] #[track_caller] @@ -335,7 +327,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, id: lint::LintExpectationId, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_span_warn_with_expectation(sp, msg, id) + self.dcx().struct_span_warn_with_expectation(sp, msg, id) } #[rustc_lint_diagnostics] #[track_caller] @@ -345,12 +337,12 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_span_warn_with_code(sp, msg, code) + self.dcx().struct_span_warn_with_code(sp, msg, code) } #[rustc_lint_diagnostics] #[track_caller] pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_warn(msg) + self.dcx().struct_warn(msg) } #[rustc_lint_diagnostics] #[track_caller] @@ -359,7 +351,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, id: lint::LintExpectationId, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_warn_with_expectation(msg, id) + self.dcx().struct_warn_with_expectation(msg, id) } #[rustc_lint_diagnostics] #[track_caller] @@ -368,12 +360,12 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_span_allow(sp, msg) + self.dcx().struct_span_allow(sp, msg) } #[rustc_lint_diagnostics] #[track_caller] pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_allow(msg) + self.dcx().struct_allow(msg) } #[rustc_lint_diagnostics] #[track_caller] @@ -382,7 +374,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, id: lint::LintExpectationId, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_expect(msg, id) + self.dcx().struct_expect(msg, id) } #[rustc_lint_diagnostics] #[track_caller] @@ -391,7 +383,7 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - self.diagnostic().struct_span_err(sp, msg) + self.dcx().struct_span_err(sp, msg) } #[rustc_lint_diagnostics] #[track_caller] @@ -401,7 +393,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - self.diagnostic().struct_span_err_with_code(sp, msg, code) + self.dcx().struct_span_err_with_code(sp, msg, code) } // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] @@ -419,7 +411,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - self.diagnostic().struct_err_with_code(msg, code) + self.dcx().struct_err_with_code(msg, code) } #[rustc_lint_diagnostics] #[track_caller] @@ -428,7 +420,7 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_warn_with_code(msg, code) + self.dcx().struct_warn_with_code(msg, code) } #[rustc_lint_diagnostics] #[track_caller] @@ -437,7 +429,7 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, !> { - self.diagnostic().struct_span_fatal(sp, msg) + self.dcx().struct_span_fatal(sp, msg) } #[rustc_lint_diagnostics] pub fn struct_span_fatal_with_code<S: Into<MultiSpan>>( @@ -446,17 +438,17 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> DiagnosticBuilder<'_, !> { - self.diagnostic().struct_span_fatal_with_code(sp, msg, code) + self.dcx().struct_span_fatal_with_code(sp, msg, code) } #[rustc_lint_diagnostics] pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> { - self.diagnostic().struct_fatal(msg) + self.dcx().struct_fatal(msg) } #[rustc_lint_diagnostics] #[track_caller] pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) -> ! { - self.diagnostic().span_fatal(sp, msg) + self.dcx().span_fatal(sp, msg) } #[rustc_lint_diagnostics] pub fn span_fatal_with_code<S: Into<MultiSpan>>( @@ -465,11 +457,11 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) -> ! { - self.diagnostic().span_fatal_with_code(sp, msg, code) + self.dcx().span_fatal_with_code(sp, msg, code) } #[rustc_lint_diagnostics] pub fn fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! { - self.diagnostic().fatal(msg).raise() + self.dcx().fatal(msg) } #[rustc_lint_diagnostics] #[track_caller] @@ -478,7 +470,7 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, ) -> ErrorGuaranteed { - self.diagnostic().span_err(sp, msg) + self.dcx().span_err(sp, msg) } #[rustc_lint_diagnostics] pub fn span_err_with_code<S: Into<MultiSpan>>( @@ -486,14 +478,14 @@ impl Session { sp: S, msg: impl Into<DiagnosticMessage>, code: DiagnosticId, - ) { - self.diagnostic().span_err_with_code(sp, msg, code) + ) -> ErrorGuaranteed { + self.dcx().span_err_with_code(sp, msg, code) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed { - self.diagnostic().err(msg) + self.dcx().err(msg) } #[track_caller] pub fn create_err<'a>( @@ -554,23 +546,23 @@ impl Session { } #[inline] pub fn err_count(&self) -> usize { - self.diagnostic().err_count() + self.dcx().err_count() } pub fn has_errors(&self) -> Option<ErrorGuaranteed> { - self.diagnostic().has_errors() + self.dcx().has_errors() } - pub fn has_errors_or_delayed_span_bugs(&self) -> Option<ErrorGuaranteed> { - self.diagnostic().has_errors_or_delayed_span_bugs() + pub fn has_errors_or_span_delayed_bugs(&self) -> Option<ErrorGuaranteed> { + self.dcx().has_errors_or_span_delayed_bugs() } pub fn is_compilation_going_to_fail(&self) -> Option<ErrorGuaranteed> { - self.diagnostic().is_compilation_going_to_fail() + self.dcx().is_compilation_going_to_fail() } pub fn abort_if_errors(&self) { - self.diagnostic().abort_if_errors(); + self.dcx().abort_if_errors(); } pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> { - if let Some(reported) = self.diagnostic().has_errors_or_lint_errors() { - let _ = self.diagnostic().emit_stashed_diagnostics(); + if let Some(reported) = self.dcx().has_errors_or_lint_errors() { + let _ = self.dcx().emit_stashed_diagnostics(); Err(reported) } else { Ok(()) @@ -586,7 +578,7 @@ impl Session { if self.err_count() == old_count { Ok(result) } else { - Err(self.delay_span_bug( + Err(self.span_delayed_bug( rustc_span::DUMMY_SP, "`self.err_count()` changed but an error was not emitted", )) @@ -598,7 +590,7 @@ impl Session { #[allow(rustc::diagnostic_outside_of_impl)] #[track_caller] pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { - self.diagnostic().span_warn(sp, msg) + self.dcx().span_warn(sp, msg) } #[rustc_lint_diagnostics] @@ -610,14 +602,14 @@ impl Session { msg: impl Into<DiagnosticMessage>, code: DiagnosticId, ) { - self.diagnostic().span_warn_with_code(sp, msg, code) + self.dcx().span_warn_with_code(sp, msg, code) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn warn(&self, msg: impl Into<DiagnosticMessage>) { - self.diagnostic().warn(msg) + self.dcx().warn(msg) } /// Ensures that compilation cannot succeed. @@ -627,24 +619,28 @@ impl Session { /// /// 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). + /// (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 + /// + /// Note: this function used to be called `delay_span_bug`. It was renamed + /// to match similar functions like `span_err`, `span_warn`, etc. #[track_caller] - pub fn delay_span_bug<S: Into<MultiSpan>>( + pub fn span_delayed_bug<S: Into<MultiSpan>>( &self, sp: S, - msg: impl Into<String>, + msg: impl Into<DiagnosticMessage>, ) -> ErrorGuaranteed { - self.diagnostic().delay_span_bug(sp, msg) + self.dcx().span_delayed_bug(sp, msg) } /// Used for code paths of expensive computations that should only take place when /// warnings or errors are emitted. If no messages are emitted ("good path"), then /// it's likely a bug. - pub fn delay_good_path_bug(&self, msg: impl Into<DiagnosticMessage>) { + pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { if self.opts.unstable_opts.print_type_sizes || self.opts.unstable_opts.query_dep_graph || self.opts.unstable_opts.dump_mir.is_some() @@ -655,41 +651,34 @@ impl Session { return; } - self.diagnostic().delay_good_path_bug(msg) + self.dcx().good_path_delayed_bug(msg) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) { - self.diagnostic().note_without_error(msg) + pub fn note(&self, msg: impl Into<DiagnosticMessage>) { + self.dcx().note(msg) } #[track_caller] #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn span_note_without_error<S: Into<MultiSpan>>( - &self, - sp: S, - msg: impl Into<DiagnosticMessage>, - ) { - self.diagnostic().span_note_without_error(sp, msg) + pub fn span_note<S: Into<MultiSpan>>(&self, sp: S, msg: impl Into<DiagnosticMessage>) { + self.dcx().span_note(sp, msg) } #[rustc_lint_diagnostics] #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub fn struct_note_without_error( - &self, - msg: impl Into<DiagnosticMessage>, - ) -> DiagnosticBuilder<'_, ()> { - self.diagnostic().struct_note_without_error(msg) + pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { + self.dcx().struct_note(msg) } #[inline] - pub fn diagnostic(&self) -> &rustc_errors::Handler { - &self.parse_sess.span_diagnostic + pub fn dcx(&self) -> &DiagCtxt { + &self.parse_sess.dcx } #[inline] @@ -813,7 +802,7 @@ impl Session { /// Returns a list of directories where target-specific tool binaries are located. pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> { - let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, &config::host_triple()); + let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple()); let p = PathBuf::from_iter([ Path::new(&self.sysroot), Path::new(&rustlib_path), @@ -822,12 +811,7 @@ impl Session { if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } } - pub fn init_incr_comp_session( - &self, - session_dir: PathBuf, - lock_file: flock::Lock, - load_dep_graph: bool, - ) { + pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) { let mut incr_comp_session = self.incr_comp_session.borrow_mut(); if let IncrCompSession::NotInitialized = *incr_comp_session { @@ -836,7 +820,7 @@ impl Session { } *incr_comp_session = - IncrCompSession::Active { session_directory: session_dir, lock_file, load_dep_graph }; + IncrCompSession::Active { session_directory: session_dir, _lock_file: lock_file }; } pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) { @@ -883,25 +867,6 @@ impl Session { self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir()) } - pub fn print_perf_stats(&self) { - eprintln!( - "Total time spent computing symbol hashes: {}", - duration_to_secs_str(*self.perf_stats.symbol_hash_time.lock()) - ); - eprintln!( - "Total queries canonicalized: {}", - self.perf_stats.queries_canonicalized.load(Ordering::Relaxed) - ); - eprintln!( - "normalize_generic_arg_after_erasing_regions: {}", - self.perf_stats.normalize_generic_arg_after_erasing_regions.load(Ordering::Relaxed) - ); - eprintln!( - "normalize_projection_ty: {}", - self.perf_stats.normalize_projection_ty.load(Ordering::Relaxed) - ); - } - /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. /// This expends fuel if applicable, and records fuel if applicable. pub fn consider_optimizing( @@ -916,9 +881,9 @@ impl Session { let mut fuel = self.optimization_fuel.lock(); ret = fuel.remaining != 0; if fuel.remaining == 0 && !fuel.out_of_fuel { - if self.diagnostic().can_emit_warnings() { + if self.dcx().can_emit_warnings() { // We only call `msg` in case we can actually emit warnings. - // Otherwise, this could cause a `delay_good_path_bug` to + // Otherwise, this could cause a `good_path_delayed_bug` to // trigger (issue #79546). self.emit_warning(errors::OptimisationFuelExhausted { msg: msg() }); } @@ -996,6 +961,14 @@ impl Session { termize::dimensions().map_or(default_column_width, |(w, _)| w) } } + + /// Whether the default visibility of symbols should be "hidden" rather than "default". + pub fn default_hidden_visibility(&self) -> bool { + self.opts + .unstable_opts + .default_hidden_visibility + .unwrap_or(self.target.options.default_hidden_visibility) + } } // JUSTIFICATION: defn of the suggested wrapper fns @@ -1248,7 +1221,7 @@ impl Session { } pub fn teach(&self, code: &DiagnosticId) -> bool { - self.opts.unstable_opts.teach && self.diagnostic().must_teach(code) + self.opts.unstable_opts.teach && self.dcx().must_teach(code) } pub fn edition(&self) -> Edition { @@ -1384,7 +1357,7 @@ fn default_emitter( // JUSTIFICATION: literally session construction #[allow(rustc::bad_opt_access)] pub fn build_session( - handler: &EarlyErrorHandler, + early_dcx: EarlyDiagCtxt, sopts: config::Options, io: CompilerIO, bundle: Option<Lrc<rustc_errors::FluentBundle>>, @@ -1414,12 +1387,13 @@ pub fn build_session( None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"), }; - let target_cfg = config::build_target_config(handler, &sopts, target_override, &sysroot); + let target_cfg = config::build_target_config(&early_dcx, &sopts, target_override, &sysroot); let host_triple = TargetTriple::from_triple(config::host_triple()); - let (host, target_warnings) = Target::search(&host_triple, &sysroot) - .unwrap_or_else(|e| handler.early_error(format!("Error loading host specification: {e}"))); + let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| { + early_dcx.early_error(format!("Error loading host specification: {e}")) + }); for warning in target_warnings.warning_messages() { - handler.early_warn(warning) + early_dcx.early_warn(warning) } let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); @@ -1442,12 +1416,16 @@ pub fn build_session( ); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); - let mut span_diagnostic = rustc_errors::Handler::with_emitter(emitter) - .with_flags(sopts.unstable_opts.diagnostic_handler_flags(can_emit_warnings)); + let mut dcx = DiagCtxt::with_emitter(emitter) + .with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings)); if let Some(ice_file) = ice_file { - span_diagnostic = span_diagnostic.with_ice_file(ice_file); + dcx = dcx.with_ice_file(ice_file); } + // Now that the proper handler has been constructed, drop early_dcx to + // prevent accidental use. + drop(early_dcx); + let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.unstable_opts.self_profile { let directory = @@ -1462,7 +1440,7 @@ pub fn build_session( match profiler { Ok(profiler) => Some(Arc::new(profiler)), Err(e) => { - handler.early_warn(format!("failed to create profiler: {e}")); + dcx.emit_warning(errors::FailedToCreateProfiler { err: e.to_string() }); None } } @@ -1470,7 +1448,7 @@ pub fn build_session( None }; - let mut parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map); + let mut parse_sess = ParseSess::with_dcx(dcx, source_map); parse_sess.assume_incomplete_release = sopts.unstable_opts.assume_incomplete_release; let host_triple = config::host_triple(); @@ -1515,16 +1493,12 @@ pub fn build_session( io, incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), prof, - perf_stats: PerfStats { - symbol_hash_time: Lock::new(Duration::from_secs(0)), - queries_canonicalized: AtomicUsize::new(0), - normalize_generic_arg_after_erasing_regions: AtomicUsize::new(0), - normalize_projection_ty: AtomicUsize::new(0), - }, code_stats: Default::default(), optimization_fuel, print_fuel, jobserver: jobserver::client(), + lint_store: None, + registered_lints: false, driver_lint_caps, ctfe_backtrace, miri_unleashed_features: Lock::new(Default::default()), @@ -1707,17 +1681,41 @@ fn validate_commandline_args_with_session_available(sess: &Session) { sess.emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list }); } } + + if sess.opts.unstable_opts.function_return != FunctionReturn::default() { + if sess.target.arch != "x86" && sess.target.arch != "x86_64" { + sess.emit_err(errors::FunctionReturnRequiresX86OrX8664); + } + } + + // The code model check applies to `thunk` and `thunk-extern`, but not `thunk-inline`, so it is + // kept as a `match` to force a change if new ones are added, even if we currently only support + // `thunk-extern` like Clang. + match sess.opts.unstable_opts.function_return { + FunctionReturn::Keep => (), + FunctionReturn::ThunkExtern => { + // FIXME: In principle, the inherited base LLVM target code model could be large, + // but this only checks whether we were passed one explicitly (like Clang does). + if let Some(code_model) = sess.code_model() + && code_model == CodeModel::Large + { + sess.emit_err(errors::FunctionReturnThunkExternRequiresNonLargeCodeModel); + } + } + } } /// Holds data on the current incremental compilation session, if there is one. #[derive(Debug)] -pub enum IncrCompSession { +enum IncrCompSession { /// This is the state the session will be in until the incr. comp. dir is /// needed. NotInitialized, /// This is the state during which the session directory is private and can - /// be modified. - Active { session_directory: PathBuf, lock_file: flock::Lock, load_dep_graph: bool }, + /// be modified. `_lock_file` is never directly used, but its presence + /// alone has an effect, because the file will unlock when the session is + /// dropped. + Active { session_directory: PathBuf, _lock_file: flock::Lock }, /// This is the state after the session directory has been finalized. In this /// state, the contents of the directory must not be modified any more. Finalized { session_directory: PathBuf }, @@ -1727,69 +1725,78 @@ pub enum IncrCompSession { InvalidBecauseOfErrors { session_directory: PathBuf }, } -/// A wrapper around an [`Handler`] that is used for early error emissions. -pub struct EarlyErrorHandler { - handler: Handler, +/// A wrapper around an [`DiagCtxt`] that is used for early error emissions. +pub struct EarlyDiagCtxt { + dcx: DiagCtxt, } -impl EarlyErrorHandler { +impl EarlyDiagCtxt { pub fn new(output: ErrorOutputType) -> Self { let emitter = mk_emitter(output); - Self { handler: rustc_errors::Handler::with_emitter(emitter) } + Self { dcx: DiagCtxt::with_emitter(emitter) } } pub fn abort_if_errors(&self) { - self.handler.abort_if_errors() + self.dcx.abort_if_errors() } - /// Swap out the underlying handler once we acquire the user's preference on error emission + /// Swap out the underlying dcx once we acquire the user's preference on error emission /// format. Any errors prior to that will cause an abort and all stashed diagnostics of the - /// previous handler will be emitted. + /// previous dcx will be emitted. pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) { - self.handler.abort_if_errors(); + self.dcx.abort_if_errors(); let emitter = mk_emitter(output); - self.handler = Handler::with_emitter(emitter); + self.dcx = DiagCtxt::with_emitter(emitter); } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_note(&self, msg: impl Into<DiagnosticMessage>) { - self.handler.struct_note_without_error(msg).emit() + self.dcx.struct_note(msg).emit() } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_help(&self, msg: impl Into<DiagnosticMessage>) { - self.handler.struct_help(msg).emit() + self.dcx.struct_help(msg).emit() } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] #[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"] pub fn early_error_no_abort(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed { - self.handler.struct_err(msg).emit() + self.dcx.struct_err(msg).emit() } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_error(&self, msg: impl Into<DiagnosticMessage>) -> ! { - self.handler.struct_fatal(msg).emit() + self.dcx.struct_fatal(msg).emit() } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - pub(crate) fn early_struct_error( + pub fn early_struct_error( &self, msg: impl Into<DiagnosticMessage>, ) -> DiagnosticBuilder<'_, !> { - self.handler.struct_fatal(msg) + self.dcx.struct_fatal(msg) } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_warn(&self, msg: impl Into<DiagnosticMessage>) { - self.handler.struct_warn(msg).emit() + self.dcx.struct_warn(msg).emit() + } + + pub fn initialize_checked_jobserver(&self) { + // initialize jobserver before getting `jobserver::client` and `build_session`. + jobserver::initialize_checked(|err| { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + self.dcx.struct_warn(err).note("the build environment is likely misconfigured").emit() + }); } } |