use crate::errors::{
CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
- SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
+ SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported, SkippingConstChecks,
SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
- TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
+ TargetRequiresUnwindTables, UnleashedFeatureHelp, UnstableVirtualFunctionElimination,
+ UnsupportedDwarfVersion,
};
use crate::parse::{add_feature_diagnostics, ParseSess};
use crate::search_paths::{PathKind, SearchPath};
use std::cell::{self, RefCell};
use std::env;
use std::fmt;
-use std::io::Write;
use std::ops::{Div, Mul};
use std::path::{Path, PathBuf};
use std::str::FromStr;
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
- // FIXME(#100717): needs eager translation/lists
- #[allow(rustc::untranslatable_diagnostic)]
- #[allow(rustc::diagnostic_outside_of_impl)]
- let mut diag = self.struct_warn("skipping const checks");
- for &(span, feature_gate) in unleashed_features.iter() {
- // FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
- if let Some(gate) = feature_gate {
- diag.span_help(span, &format!("skipping check for `{gate}` feature"));
- // The unleash flag must *not* be used to just "hack around" feature gates.
- must_err = true;
- } else {
- diag.span_help(span, "skipping check that does not even have a feature gate");
- }
- }
- diag.emit();
+ self.emit_warning(SkippingConstChecks {
+ unleashed_features: unleashed_features
+ .iter()
+ .map(|(span, gate)| {
+ gate.map(|gate| {
+ must_err = true;
+ UnleashedFeatureHelp::Named { span: *span, gate }
+ })
+ .unwrap_or(UnleashedFeatureHelp::Unnamed { span: *span })
+ })
+ .collect(),
+ });
+
// If we should err, make sure we did.
if must_err && self.has_errors().is_none() {
// We have skipped a feature gate, and not run into other errors... reject.
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_warn<S: Into<MultiSpan>>(
&self,
sp: S,
self.diagnostic().struct_span_warn(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_warn_with_expectation<S: Into<MultiSpan>>(
&self,
sp: S,
self.diagnostic().struct_span_warn_with_expectation(sp, msg, id)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
self.diagnostic().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)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
self.diagnostic().struct_warn_with_expectation(msg, id)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_allow<S: Into<MultiSpan>>(
&self,
sp: S,
self.diagnostic().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)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_expect(
&self,
msg: impl Into<DiagnosticMessage>,
self.diagnostic().struct_expect(msg, id)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_err<S: Into<MultiSpan>>(
&self,
sp: S,
self.diagnostic().struct_span_err(sp, msg)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
}
// FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_err(
&self,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.parse_sess.struct_err(msg)
}
+ #[track_caller]
#[rustc_lint_diagnostics]
pub fn struct_err_with_code(
&self,
self.diagnostic().struct_err_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_warn_with_code(
&self,
msg: impl Into<DiagnosticMessage>,
self.diagnostic().struct_warn_with_code(msg, code)
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn struct_span_fatal<S: Into<MultiSpan>>(
&self,
sp: S,
}
#[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.diagnostic().fatal(msg).raise()
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_err_or_warn<S: Into<MultiSpan>>(
&self,
is_warning: bool,
}
}
#[rustc_lint_diagnostics]
+ #[track_caller]
pub fn span_err<S: Into<MultiSpan>>(
&self,
sp: S,
pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
self.diagnostic().err(msg)
}
+ #[track_caller]
pub fn create_err<'a>(
&'a self,
err: impl IntoDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
self.parse_sess.create_err(err)
}
+ #[track_caller]
pub fn create_feature_err<'a>(
&'a self,
err: impl IntoDiagnostic<'a>,
add_feature_diagnostics(&mut err, &self.parse_sess, feature);
err
}
+ #[track_caller]
pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed {
self.parse_sess.emit_err(err)
}
+ #[track_caller]
pub fn create_warning<'a>(
&'a self,
err: impl IntoDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> {
self.parse_sess.create_warning(err)
}
+ #[track_caller]
pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) {
self.parse_sess.emit_warning(warning)
}
+ #[track_caller]
pub fn create_note<'a>(
&'a self,
note: impl IntoDiagnostic<'a, Noted>,
) -> DiagnosticBuilder<'a, Noted> {
self.parse_sess.create_note(note)
}
+ #[track_caller]
pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted {
self.parse_sess.emit_note(note)
}
+ #[track_caller]
pub fn create_fatal<'a>(
&'a self,
fatal: impl IntoDiagnostic<'a, !>,
) -> DiagnosticBuilder<'a, !> {
self.parse_sess.create_fatal(fatal)
}
+ #[track_caller]
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! {
self.parse_sess.emit_fatal(fatal)
}
}
#[allow(rustc::untranslatable_diagnostic)]
#[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)
}
pub fn note_without_error(&self, msg: impl Into<DiagnosticMessage>) {
self.diagnostic().note_without_error(msg)
}
+
+ #[track_caller]
pub fn span_note_without_error<S: Into<MultiSpan>>(
&self,
sp: S,
return config::Lto::Fat;
}
config::LtoCli::Thin => {
- return if self.opts.cli_forced_thinlto_off {
- config::Lto::Fat
- } else {
- config::Lto::Thin
- };
+ // The user explicitly asked for ThinLTO
+ return config::Lto::Thin;
}
}
// If processing command line options determined that we're incompatible
// with ThinLTO (e.g., `-C lto --emit llvm-ir`) then return that option.
- if self.opts.cli_forced_thinlto_off {
+ if self.opts.cli_forced_local_thinlto_off {
return config::Lto::No;
}
source_map: Lrc<SourceMap>,
bundle: Option<Lrc<FluentBundle>>,
fallback_bundle: LazyFallbackBundle,
- emitter_dest: Option<Box<dyn Write + Send>>,
) -> Box<dyn Emitter + sync::Send> {
let macro_backtrace = sopts.unstable_opts.macro_backtrace;
- match (sopts.error_format, emitter_dest) {
- (config::ErrorOutputType::HumanReadable(kind), dst) => {
+ let track_diagnostics = sopts.unstable_opts.track_diagnostics;
+ match sopts.error_format {
+ config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
if let HumanReadableErrorType::AnnotateSnippet(_) = kind {
);
Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
} else {
- let emitter = match dst {
- None => EmitterWriter::stderr(
- color_config,
- Some(source_map),
- bundle,
- fallback_bundle,
- short,
- sopts.unstable_opts.teach,
- sopts.diagnostic_width,
- macro_backtrace,
- ),
- Some(dst) => EmitterWriter::new(
- dst,
- Some(source_map),
- bundle,
- fallback_bundle,
- short,
- false, // no teach messages when writing to a buffer
- false, // no colors when writing to a buffer
- None, // no diagnostic width
- macro_backtrace,
- ),
- };
+ let emitter = EmitterWriter::stderr(
+ color_config,
+ Some(source_map),
+ bundle,
+ fallback_bundle,
+ short,
+ sopts.unstable_opts.teach,
+ sopts.diagnostic_width,
+ macro_backtrace,
+ track_diagnostics,
+ );
Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing))
}
}
- (config::ErrorOutputType::Json { pretty, json_rendered }, None) => Box::new(
+ config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(
JsonEmitter::stderr(
Some(registry),
source_map,
json_rendered,
sopts.diagnostic_width,
macro_backtrace,
- )
- .ui_testing(sopts.unstable_opts.ui_testing),
- ),
- (config::ErrorOutputType::Json { pretty, json_rendered }, Some(dst)) => Box::new(
- JsonEmitter::new(
- dst,
- Some(registry),
- source_map,
- bundle,
- fallback_bundle,
- pretty,
- json_rendered,
- sopts.diagnostic_width,
- macro_backtrace,
+ track_diagnostics,
)
.ui_testing(sopts.unstable_opts.ui_testing),
),
}
}
-pub enum DiagnosticOutput {
- Default,
- Raw(Box<dyn Write + Send>),
-}
-
// JUSTIFICATION: literally session construction
#[allow(rustc::bad_opt_access)]
pub fn build_session(
local_crate_source_file: Option<PathBuf>,
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry,
- diagnostics_output: DiagnosticOutput,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>,
let cap_lints_allow = sopts.lint_cap.map_or(false, |cap| cap == lint::Allow);
let can_emit_warnings = !(warnings_allow || cap_lints_allow);
- let write_dest = match diagnostics_output {
- DiagnosticOutput::Default => None,
- DiagnosticOutput::Raw(write) => Some(write),
- };
-
let sysroot = match &sopts.maybe_sysroot {
Some(sysroot) => sysroot.clone(),
- None => filesearch::get_or_default_sysroot(),
+ None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
};
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
rustc_errors::DEFAULT_LOCALE_RESOURCES,
sopts.unstable_opts.translate_directionality_markers,
);
- let emitter =
- default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle, write_dest);
+ let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
let span_diagnostic = rustc_errors::Handler::with_emitter_and_flags(
emitter,
false,
None,
false,
+ false,
))
}
- config::ErrorOutputType::Json { pretty, json_rendered } => {
- Box::new(JsonEmitter::basic(pretty, json_rendered, None, fallback_bundle, None, false))
- }
+ config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic(
+ pretty,
+ json_rendered,
+ None,
+ fallback_bundle,
+ None,
+ false,
+ false,
+ )),
};
rustc_errors::Handler::with_emitter(true, None, emitter)
}