summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src/session.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session/src/session.rs')
-rw-r--r--compiler/rustc_session/src/session.rs303
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()
+ });
}
}