1
Fork 0

Rollup merge of #119171 - nnethercote:cleanup-errors-4, r=compiler-errors

Cleanup error handlers: round 4

More `rustc_errors` cleanups. A sequel to #118933.

r? `@compiler-errors`
This commit is contained in:
Michael Goulet 2023-12-22 21:41:03 -05:00 committed by GitHub
commit e0d7a72c46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 611 additions and 946 deletions

View file

@ -1,5 +1,5 @@
use rustc_errors::{ use rustc_errors::{
struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan, struct_span_err, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, MultiSpan,
}; };
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
@ -12,7 +12,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
place: &str, place: &str,
borrow_place: &str, borrow_place: &str,
value_place: &str, value_place: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow { self.infcx.tcx.sess.create_err(crate::session_diagnostics::MoveBorrow {
place, place,
span, span,
@ -28,7 +28,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
desc: &str, desc: &str,
borrow_span: Span, borrow_span: Span,
borrow_desc: &str, borrow_desc: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
span, span,
@ -50,7 +50,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
old_loan_span: Span, old_loan_span: Span,
old_opt_via: &str, old_opt_via: &str,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
@ -97,7 +97,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
desc: &str, desc: &str,
old_loan_span: Span, old_loan_span: Span,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
new_loan_span, new_loan_span,
@ -130,7 +130,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
noun_old: &str, noun_old: &str,
old_opt_via: &str, old_opt_via: &str,
previous_end_span: Option<Span>, previous_end_span: Option<Span>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
new_loan_span, new_loan_span,
@ -162,7 +162,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
old_opt_via: &str, old_opt_via: &str,
previous_end_span: Option<Span>, previous_end_span: Option<Span>,
second_borrow_desc: &str, second_borrow_desc: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
new_loan_span, new_loan_span,
@ -194,7 +194,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
kind_old: &str, kind_old: &str,
msg_old: &str, msg_old: &str,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
@ -235,7 +235,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
span: Span, span: Span,
borrow_span: Span, borrow_span: Span,
desc: &str, desc: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
span, span,
@ -254,16 +254,12 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
span: Span, span: Span,
desc: &str, desc: &str,
is_arg: bool, is_arg: bool,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc) struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
} }
pub(crate) fn cannot_assign( pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'tcx> {
&self,
span: Span,
desc: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
struct_span_err!(self, span, E0594, "cannot assign to {}", desc) struct_span_err!(self, span, E0594, "cannot assign to {}", desc)
} }
@ -271,7 +267,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
move_from_span: Span, move_from_span: Span,
move_from_desc: &str, move_from_desc: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc) struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc)
} }
@ -283,7 +279,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
move_from_span: Span, move_from_span: Span,
ty: Ty<'_>, ty: Ty<'_>,
is_index: Option<bool>, is_index: Option<bool>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let type_name = match (&ty.kind(), is_index) { let type_name = match (&ty.kind(), is_index) {
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
(&ty::Slice(_), _) => "slice", (&ty::Slice(_), _) => "slice",
@ -305,7 +301,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
move_from_span: Span, move_from_span: Span,
container_ty: Ty<'_>, container_ty: Ty<'_>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
move_from_span, move_from_span,
@ -323,7 +319,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
verb: &str, verb: &str,
optional_adverb_for_moved: &str, optional_adverb_for_moved: &str,
moved_path: Option<String>, moved_path: Option<String>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default();
struct_span_err!( struct_span_err!(
@ -342,7 +338,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
span: Span, span: Span,
path: &str, path: &str,
reason: &str, reason: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,) struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,)
} }
@ -353,7 +349,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
immutable_place: &str, immutable_place: &str,
immutable_section: &str, immutable_section: &str,
action: &str, action: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
mutate_span, mutate_span,
@ -372,7 +368,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
span: Span, span: Span,
yield_span: Span, yield_span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
@ -387,7 +383,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn cannot_borrow_across_destructor( pub(crate) fn cannot_borrow_across_destructor(
&self, &self,
borrow_span: Span, borrow_span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!( struct_span_err!(
self, self,
borrow_span, borrow_span,
@ -400,7 +396,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
span: Span, span: Span,
path: &str, path: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!(self, span, E0597, "{} does not live long enough", path,) struct_span_err!(self, span, E0597, "{} does not live long enough", path,)
} }
@ -410,7 +406,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
return_kind: &str, return_kind: &str,
reference_desc: &str, reference_desc: &str,
path_desc: &str, path_desc: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
span, span,
@ -436,7 +432,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
borrowed_path: &str, borrowed_path: &str,
capture_span: Span, capture_span: Span,
scope: &str, scope: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self, self,
closure_span, closure_span,
@ -452,14 +448,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
pub(crate) fn thread_local_value_does_not_live_long_enough( pub(crate) fn thread_local_value_does_not_live_long_enough(
&self, &self,
span: Span, span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",) struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",)
} }
pub(crate) fn temporary_value_borrowed_for_too_long( pub(crate) fn temporary_value_borrowed_for_too_long(
&self, &self,
span: Span, span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",) struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
} }
@ -470,7 +466,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
sp: S, sp: S,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
code: DiagnosticId, code: DiagnosticId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code) self.infcx.tcx.sess.struct_span_err_with_code(sp, msg, code)
} }
} }
@ -479,7 +475,7 @@ pub(crate) fn borrowed_data_escapes_closure<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
escape_span: Span, escape_span: Span,
escapes_from: &str, escapes_from: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
struct_span_err!( struct_span_err!(
tcx.sess, tcx.sess,
escape_span, escape_span,

View file

@ -1,7 +1,7 @@
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::DiagnosticBuilder;
use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_infer::infer::region_constraints::Constraint; use rustc_infer::infer::region_constraints::Constraint;
@ -147,11 +147,7 @@ impl<'tcx> ToUniverseInfo<'tcx> for ! {
trait TypeOpInfo<'tcx> { trait TypeOpInfo<'tcx> {
/// Returns an error to be reported if rerunning the type op fails to /// Returns an error to be reported if rerunning the type op fails to
/// recover the error's cause. /// recover the error's cause.
fn fallback_error( fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
&self,
tcx: TyCtxt<'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
fn base_universe(&self) -> ty::UniverseIndex; fn base_universe(&self) -> ty::UniverseIndex;
@ -161,7 +157,7 @@ trait TypeOpInfo<'tcx> {
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; ) -> Option<DiagnosticBuilder<'tcx>>;
#[instrument(level = "debug", skip(self, mbcx))] #[instrument(level = "debug", skip(self, mbcx))]
fn report_error( fn report_error(
@ -224,11 +220,7 @@ struct PredicateQuery<'tcx> {
} }
impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
fn fallback_error( fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
tcx.sess.create_err(HigherRankedLifetimeError { tcx.sess.create_err(HigherRankedLifetimeError {
cause: Some(HigherRankedErrorCause::CouldNotProve { cause: Some(HigherRankedErrorCause::CouldNotProve {
predicate: self.canonical_query.value.value.predicate.to_string(), predicate: self.canonical_query.value.value.predicate.to_string(),
@ -247,7 +239,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -265,11 +257,7 @@ impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
where where
T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx,
{ {
fn fallback_error( fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
tcx.sess.create_err(HigherRankedLifetimeError { tcx.sess.create_err(HigherRankedLifetimeError {
cause: Some(HigherRankedErrorCause::CouldNotNormalize { cause: Some(HigherRankedErrorCause::CouldNotNormalize {
value: self.canonical_query.value.value.value.to_string(), value: self.canonical_query.value.value.value.to_string(),
@ -288,7 +276,7 @@ where
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -312,11 +300,7 @@ struct AscribeUserTypeQuery<'tcx> {
} }
impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
fn fallback_error( fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
// FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
// and is only the fallback when the nice error fails. Consider improving this some more. // and is only the fallback when the nice error fails. Consider improving this some more.
tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span })
@ -332,7 +316,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -342,11 +326,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
} }
impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
fn fallback_error( fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
// FIXME: This error message isn't great, but it doesn't show up in the existing UI tests, // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
// and is only the fallback when the nice error fails. Consider improving this some more. // and is only the fallback when the nice error fails. Consider improving this some more.
tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span }) tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span })
@ -362,7 +342,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
_cause: ObligationCause<'tcx>, _cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
try_extract_error_from_region_constraints( try_extract_error_from_region_constraints(
mbcx.infcx, mbcx.infcx,
placeholder_region, placeholder_region,
@ -383,7 +363,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
// We generally shouldn't have errors here because the query was // We generally shouldn't have errors here because the query was
// already run, but there's no point using `span_delayed_bug` // already run, but there's no point using `span_delayed_bug`
// when we're going to emit an error here anyway. // when we're going to emit an error here anyway.
@ -407,7 +387,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
region_constraints: &RegionConstraintData<'tcx>, region_constraints: &RegionConstraintData<'tcx>,
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let placeholder_universe = match placeholder_region.kind() { let placeholder_universe = match placeholder_region.kind() {
ty::RePlaceholder(p) => p.universe, ty::RePlaceholder(p) => p.universe,
ty::ReVar(vid) => universe_of_region(vid), ty::ReVar(vid) => universe_of_region(vid),

View file

@ -2,9 +2,7 @@ use either::Either;
use hir::PatField; use hir::PatField;
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{ use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
@ -324,7 +322,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&mut self, &mut self,
mpi: MovePathIndex, mpi: MovePathIndex,
move_span: Span, move_span: Span,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'_>,
in_pattern: &mut bool, in_pattern: &mut bool,
move_spans: UseSpans<'_>, move_spans: UseSpans<'_>,
) { ) {
@ -483,7 +481,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
span: Span, span: Span,
use_spans: UseSpans<'tcx>, use_spans: UseSpans<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
// We need all statements in the body where the binding was assigned to to later find all // We need all statements in the body where the binding was assigned to to later find all
// the branching code paths where the binding *wasn't* assigned to. // the branching code paths where the binding *wasn't* assigned to.
let inits = &self.move_data.init_path_map[mpi]; let inits = &self.move_data.init_path_map[mpi];
@ -873,7 +871,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location, location: Location,
(place, _span): (Place<'tcx>, Span), (place, _span): (Place<'tcx>, Span),
borrow: &BorrowData<'tcx>, borrow: &BorrowData<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.args_or_use(); let borrow_span = borrow_spans.args_or_use();
@ -921,7 +919,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
gen_borrow_kind: BorrowKind, gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData<'tcx>, issued_borrow: &BorrowData<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_spans = self.retrieve_borrow_spans(issued_borrow);
let issued_span = issued_spans.args_or_use(); let issued_span = issued_spans.args_or_use();
@ -2025,7 +2023,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
drop_span: Span, drop_span: Span,
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
explanation: BorrowExplanation<'tcx>, explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
debug!( debug!(
"report_local_value_does_not_live_long_enough(\ "report_local_value_does_not_live_long_enough(\
{:?}, {:?}, {:?}, {:?}, {:?}\ {:?}, {:?}, {:?}, {:?}, {:?}\
@ -2200,7 +2198,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&mut self, &mut self,
drop_span: Span, drop_span: Span,
borrow_span: Span, borrow_span: Span,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
debug!( debug!(
"report_thread_local_value_does_not_live_long_enough(\ "report_thread_local_value_does_not_live_long_enough(\
{:?}, {:?}\ {:?}, {:?}\
@ -2228,7 +2226,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
proper_span: Span, proper_span: Span,
explanation: BorrowExplanation<'tcx>, explanation: BorrowExplanation<'tcx>,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation explanation
{ {
@ -2395,7 +2393,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return_span: Span, return_span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
opt_place_desc: Option<&String>, opt_place_desc: Option<&String>,
) -> Option<DiagnosticBuilder<'cx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'cx>> {
let return_kind = match category { let return_kind = match category {
ConstraintCategory::Return(_) => "return", ConstraintCategory::Return(_) => "return",
ConstraintCategory::Yield => "yield", ConstraintCategory::Yield => "yield",
@ -2490,7 +2488,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
constraint_span: Span, constraint_span: Span,
captured_var: &str, captured_var: &str,
scope: &str, scope: &str,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let args_span = use_span.args_or_use(); let args_span = use_span.args_or_use();
@ -2593,7 +2591,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
upvar_span: Span, upvar_span: Span,
upvar_name: Symbol, upvar_name: Symbol,
escape_span: Span, escape_span: Span,
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'cx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id());

View file

@ -1,4 +1,4 @@
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
@ -288,7 +288,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&mut self, &mut self,
place: Place<'tcx>, place: Place<'tcx>,
span: Span, span: Span,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
let description = if place.projection.len() == 1 { let description = if place.projection.len() == 1 {
format!("static item {}", self.describe_any_place(place.as_ref())) format!("static item {}", self.describe_any_place(place.as_ref()))
} else { } else {
@ -310,7 +310,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
deref_target_place: Place<'tcx>, deref_target_place: Place<'tcx>,
span: Span, span: Span,
use_spans: Option<UseSpans<'tcx>>, use_spans: Option<UseSpans<'tcx>>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
// Inspect the type of the content behind the // Inspect the type of the content behind the
// borrow to provide feedback about why this // borrow to provide feedback about why this
// was a move rather than a copy. // was a move rather than a copy.

View file

@ -1,5 +1,5 @@
use hir::ExprKind; use hir::ExprKind;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::Node; use rustc_hir::Node;
@ -711,7 +711,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn construct_mut_suggestion_for_local_binding_patterns( fn construct_mut_suggestion_for_local_binding_patterns(
&self, &self,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'_>,
local: Local, local: Local,
) { ) {
let local_decl = &self.body.local_decls[local]; let local_decl = &self.body.local_decls[local];
@ -1025,7 +1025,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn suggest_using_iter_mut(&self, err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>) { fn suggest_using_iter_mut(&self, err: &mut DiagnosticBuilder<'_>) {
let source = self.body.source; let source = self.body.source;
let hir = self.infcx.tcx.hir(); let hir = self.infcx.tcx.hir();
if let InstanceDef::Item(def_id) = source.instance if let InstanceDef::Item(def_id) = source.instance
@ -1067,12 +1067,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn suggest_make_local_mut( fn suggest_make_local_mut(&self, err: &mut DiagnosticBuilder<'_>, local: Local, name: Symbol) {
&self,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
local: Local,
name: Symbol,
) {
let local_decl = &self.body.local_decls[local]; let local_decl = &self.body.local_decls[local];
let (pointer_sigil, pointer_desc) = let (pointer_sigil, pointer_desc) =

View file

@ -3,7 +3,7 @@
//! Error reporting machinery for lifetime errors. //! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res::Def; use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -202,7 +202,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// and the span which bounded to the trait for adding 'static lifetime suggestion // and the span which bounded to the trait for adding 'static lifetime suggestion
fn suggest_static_lifetime_for_gat_from_hrtb( fn suggest_static_lifetime_for_gat_from_hrtb(
&self, &self,
diag: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, diag: &mut DiagnosticBuilder<'_>,
lower_bound: RegionVid, lower_bound: RegionVid,
) { ) {
let mut suggestions = vec![]; let mut suggestions = vec![];
@ -573,7 +573,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&self, &self,
errci: &ErrorConstraintInfo<'tcx>, errci: &ErrorConstraintInfo<'tcx>,
kind: ReturnConstraint, kind: ReturnConstraint,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
@ -645,7 +645,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn report_escaping_data_error( fn report_escaping_data_error(
&self, &self,
errci: &ErrorConstraintInfo<'tcx>, errci: &ErrorConstraintInfo<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { span, category, .. } = errci; let ErrorConstraintInfo { span, category, .. } = errci;
let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
@ -744,10 +744,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it /// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
/// | is returning data with lifetime `'b` /// | is returning data with lifetime `'b`
/// ``` /// ```
fn report_general_error( fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> DiagnosticBuilder<'tcx> {
&self,
errci: &ErrorConstraintInfo<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let ErrorConstraintInfo { let ErrorConstraintInfo {
fr, fr,
fr_is_local, fr_is_local,

View file

@ -2407,8 +2407,8 @@ mod error {
/// when errors in the map are being re-added to the error buffer so that errors with the /// when errors in the map are being re-added to the error buffer so that errors with the
/// same primary span come out in a consistent order. /// same primary span come out in a consistent order.
buffered_move_errors: buffered_move_errors:
BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorGuaranteed>)>, BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>)>,
buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)>, buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx>, usize)>,
/// Diagnostics to be reported buffer. /// Diagnostics to be reported buffer.
buffered: Vec<Diagnostic>, buffered: Vec<Diagnostic>,
/// Set to Some if we emit an error during borrowck /// Set to Some if we emit an error during borrowck
@ -2426,7 +2426,7 @@ mod error {
} }
} }
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) {
if let None = self.tainted_by_errors { if let None = self.tainted_by_errors {
self.tainted_by_errors = Some(self.tcx.sess.span_delayed_bug( self.tainted_by_errors = Some(self.tcx.sess.span_delayed_bug(
t.span.clone_ignoring_labels(), t.span.clone_ignoring_labels(),
@ -2446,7 +2446,7 @@ mod error {
} }
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) {
self.errors.buffer_error(t); self.errors.buffer_error(t);
} }
@ -2457,7 +2457,7 @@ mod error {
pub fn buffer_move_error( pub fn buffer_move_error(
&mut self, &mut self,
move_out_indices: Vec<MoveOutIndex>, move_out_indices: Vec<MoveOutIndex>,
place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorGuaranteed>), place_and_err: (PlaceRef<'tcx>, DiagnosticBuilder<'tcx>),
) -> bool { ) -> bool {
if let Some((_, diag)) = if let Some((_, diag)) =
self.errors.buffered_move_errors.insert(move_out_indices, place_and_err) self.errors.buffered_move_errors.insert(move_out_indices, place_and_err)
@ -2473,16 +2473,11 @@ mod error {
pub fn get_buffered_mut_error( pub fn get_buffered_mut_error(
&mut self, &mut self,
span: Span, span: Span,
) -> Option<(DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)> { ) -> Option<(DiagnosticBuilder<'tcx>, usize)> {
self.errors.buffered_mut_errors.remove(&span) self.errors.buffered_mut_errors.remove(&span)
} }
pub fn buffer_mut_error( pub fn buffer_mut_error(&mut self, span: Span, t: DiagnosticBuilder<'tcx>, count: usize) {
&mut self,
span: Span,
t: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
count: usize,
) {
self.errors.buffered_mut_errors.insert(span, (t, count)); self.errors.buffered_mut_errors.insert(span, (t, count));
} }
@ -2517,7 +2512,7 @@ mod error {
pub fn has_move_error( pub fn has_move_error(
&self, &self,
move_out_indices: &[MoveOutIndex], move_out_indices: &[MoveOutIndex],
) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'cx, ErrorGuaranteed>)> { ) -> Option<&(PlaceRef<'tcx>, DiagnosticBuilder<'cx>)> {
self.errors.buffered_move_errors.get(move_out_indices) self.errors.buffered_move_errors.get(move_out_indices)
} }
} }

View file

@ -8,9 +8,7 @@ use rustc_ast::{
FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait,
}; };
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{ use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan, PResult, SingleLabelManySpans};
Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult, SingleLabelManySpans,
};
use rustc_expand::base::{self, *}; use rustc_expand::base::{self, *};
use rustc_parse_format as parse; use rustc_parse_format as parse;
use rustc_span::symbol::{Ident, Symbol}; use rustc_span::symbol::{Ident, Symbol};
@ -726,7 +724,7 @@ fn report_redundant_format_arguments<'a>(
args: &FormatArguments, args: &FormatArguments,
used: &[bool], used: &[bool],
placeholders: Vec<(Span, &str)>, placeholders: Vec<(Span, &str)>,
) -> Option<DiagnosticBuilder<'a, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'a>> {
let mut fmt_arg_indices = vec![]; let mut fmt_arg_indices = vec![];
let mut args_spans = vec![]; let mut args_spans = vec![];
let mut fmt_spans = vec![]; let mut fmt_spans = vec![];
@ -885,7 +883,6 @@ fn report_invalid_references(
highlight: SingleLabelManySpans { highlight: SingleLabelManySpans {
spans: args.explicit_args().iter().map(|arg| arg.expr.span).collect(), spans: args.explicit_args().iter().map(|arg| arg.expr.span).collect(),
label: "", label: "",
kind: rustc_errors::LabelKind::Label,
}, },
}); });
// Point out `{:.*}` placeholders: those take an extra argument. // Point out `{:.*}` placeholders: those take an extra argument.

View file

@ -5,7 +5,7 @@ use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, attr, GenericParamKind}; use rustc_ast::{self as ast, attr, GenericParamKind};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::Applicability; use rustc_errors::{Applicability, DiagnosticBuilder, Level};
use rustc_expand::base::*; use rustc_expand::base::*;
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span}; use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span};
@ -391,15 +391,14 @@ pub fn expand_test_or_bench(
fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) { fn not_testable_error(cx: &ExtCtxt<'_>, attr_sp: Span, item: Option<&ast::Item>) {
let dcx = cx.sess.dcx(); let dcx = cx.sess.dcx();
let msg = "the `#[test]` attribute may only be used on a non-associated function"; let msg = "the `#[test]` attribute may only be used on a non-associated function";
let mut err = match item.map(|i| &i.kind) { let level = match item.map(|i| &i.kind) {
// These were a warning before #92959 and need to continue being that to avoid breaking // These were a warning before #92959 and need to continue being that to avoid breaking
// stable user code (#94508). // stable user code (#94508).
Some(ast::ItemKind::MacCall(_)) => dcx.struct_span_warn(attr_sp, msg), Some(ast::ItemKind::MacCall(_)) => Level::Warning(None),
// `.forget_guarantee()` needed to get these two arms to match types. Because of how _ => Level::Error { lint: false },
// locally close the `.emit()` call is I'm comfortable with it, but if it can be
// reworked in the future to not need it, it'd be nice.
_ => dcx.struct_span_err(attr_sp, msg).forget_guarantee(),
}; };
let mut err = DiagnosticBuilder::<()>::new(dcx, level, msg);
err.set_span(attr_sp);
if let Some(item) = item { if let Some(item) = item {
err.span_label( err.span_label(
item.span, item.span,

View file

@ -179,7 +179,7 @@ pub(crate) fn compile_fn(
let early_dcx = rustc_session::EarlyDiagCtxt::new( let early_dcx = rustc_session::EarlyDiagCtxt::new(
rustc_session::config::ErrorOutputType::default(), rustc_session::config::ErrorOutputType::default(),
); );
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"backend implementation limit exceeded while compiling {name}", "backend implementation limit exceeded while compiling {name}",
name = codegened_func.symbol_name name = codegened_func.symbol_name
)); ));

View file

@ -102,7 +102,7 @@ pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>);
impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> { impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> {
fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> { fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(dcx, level); let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(dcx, level);
let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); let (message, _) = diag.messages().first().expect("`LlvmError` with no message");
let message = dcx.eagerly_translate_to_string(message.clone(), diag.args()); let message = dcx.eagerly_translate_to_string(message.clone(), diag.args());
let mut diag = let mut diag =

View file

@ -15,7 +15,7 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter; use rustc_errors::emitter::Emitter;
use rustc_errors::{translation::Translate, DiagCtxt, DiagnosticId, FatalError, Level}; use rustc_errors::{translation::Translate, DiagCtxt, DiagnosticId, FatalError, Level};
use rustc_errors::{DiagnosticMessage, Style}; use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Style};
use rustc_fs_util::link_or_copy; use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{ use rustc_incremental::{
@ -986,7 +986,7 @@ pub struct CguMessage;
type DiagnosticArgName<'source> = Cow<'source, str>; type DiagnosticArgName<'source> = Cow<'source, str>;
struct Diagnostic { struct Diagnostic {
msg: Vec<(DiagnosticMessage, Style)>, msgs: Vec<(DiagnosticMessage, Style)>,
args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>, args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>,
code: Option<DiagnosticId>, code: Option<DiagnosticId>,
lvl: Level, lvl: Level,
@ -1799,14 +1799,14 @@ impl Emitter for SharedEmitter {
let args: FxHashMap<Cow<'_, str>, rustc_errors::DiagnosticArgValue<'_>> = let args: FxHashMap<Cow<'_, str>, rustc_errors::DiagnosticArgValue<'_>> =
diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect(); diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
msg: diag.message.clone(), msgs: diag.messages.clone(),
args: args.clone(), args: args.clone(),
code: diag.code.clone(), code: diag.code.clone(),
lvl: diag.level(), lvl: diag.level(),
}))); })));
for child in &diag.children { for child in &diag.children {
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
msg: child.message.clone(), msgs: child.messages.clone(),
args: args.clone(), args: args.clone(),
code: None, code: None,
lvl: child.level, lvl: child.level,
@ -1838,7 +1838,7 @@ impl SharedEmitterMain {
match message { match message {
Ok(SharedEmitterMessage::Diagnostic(diag)) => { Ok(SharedEmitterMessage::Diagnostic(diag)) => {
let dcx = sess.dcx(); let dcx = sess.dcx();
let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msg); let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msgs);
if let Some(code) = diag.code { if let Some(code) = diag.code {
d.code(code); d.code(code);
} }
@ -1846,14 +1846,14 @@ impl SharedEmitterMain {
dcx.emit_diagnostic(d); dcx.emit_diagnostic(d);
} }
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => { Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string(); let err_level = match level {
Level::Error { lint: false } => rustc_errors::Level::Error { lint: false },
let mut err = match level { Level::Warning(_) => rustc_errors::Level::Warning(None),
Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(), Level::Note => rustc_errors::Level::Note,
Level::Warning(_) => sess.struct_warn(msg),
Level::Note => sess.struct_note(msg),
_ => bug!("Invalid inline asm diagnostic level"), _ => bug!("Invalid inline asm diagnostic level"),
}; };
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), err_level, msg);
// If the cookie is 0 then we don't have span information. // If the cookie is 0 then we don't have span information.
if cookie != 0 { if cookie != 0 {

View file

@ -6,7 +6,7 @@ use rustc_middle::mir::AssertKind;
use rustc_middle::query::TyCtxtAt; use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{layout::LayoutError, ConstInt}; use rustc_middle::ty::{layout::LayoutError, ConstInt};
use rustc_span::{ErrorGuaranteed, Span, Symbol, DUMMY_SP}; use rustc_span::{Span, Symbol, DUMMY_SP};
use super::{CompileTimeInterpreter, InterpCx}; use super::{CompileTimeInterpreter, InterpCx};
use crate::errors::{self, FrameNote, ReportErrorExt}; use crate::errors::{self, FrameNote, ReportErrorExt};
@ -133,7 +133,7 @@ pub(super) fn report<'tcx, C, F, E>(
where where
C: FnOnce() -> (Span, Vec<FrameNote>), C: FnOnce() -> (Span, Vec<FrameNote>),
F: FnOnce(Span, Vec<FrameNote>) -> E, F: FnOnce(Span, Vec<FrameNote>) -> E,
E: IntoDiagnostic<'tcx, ErrorGuaranteed>, E: IntoDiagnostic<'tcx>,
{ {
// Special handling for certain errors // Special handling for certain errors
match error { match error {

View file

@ -2,7 +2,7 @@
use hir::def_id::LocalDefId; use hir::def_id::LocalDefId;
use hir::{ConstContext, LangItem}; use hir::{ConstContext, LangItem};
use rustc_errors::{error_code, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{error_code, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -48,11 +48,7 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug {
DiagnosticImportance::Primary DiagnosticImportance::Primary
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
} }
#[derive(Debug)] #[derive(Debug)]
@ -66,11 +62,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
} }
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err( feature_err(
&ccx.tcx.sess.parse_sess, &ccx.tcx.sess.parse_sess,
sym::const_fn_floating_point_arithmetic, sym::const_fn_floating_point_arithmetic,
@ -84,11 +76,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
#[derive(Debug)] #[derive(Debug)]
pub struct FnCallIndirect; pub struct FnCallIndirect;
impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::UnallowedFnPointerCall { span, kind: ccx.const_kind() }) ccx.tcx.sess.create_err(errors::UnallowedFnPointerCall { span, kind: ccx.const_kind() })
} }
} }
@ -105,11 +93,7 @@ pub struct FnCallNonConst<'tcx> {
} }
impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
_: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self; let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
let ConstCx { tcx, param_env, .. } = *ccx; let ConstCx { tcx, param_env, .. } = *ccx;
@ -331,11 +315,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>); pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let FnCallUnstable(def_id, feature) = *self; let FnCallUnstable(def_id, feature) = *self;
let mut err = ccx let mut err = ccx
@ -366,11 +346,7 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
} }
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let msg = format!("{:#}s are not allowed in {}s", self.0, ccx.const_kind()); let msg = format!("{:#}s are not allowed in {}s", self.0, ccx.const_kind());
if let hir::CoroutineKind::Async(hir::CoroutineSource::Block) = self.0 { if let hir::CoroutineKind::Async(hir::CoroutineSource::Block) = self.0 {
ccx.tcx.sess.create_feature_err( ccx.tcx.sess.create_feature_err(
@ -386,11 +362,7 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
#[derive(Debug)] #[derive(Debug)]
pub struct HeapAllocation; pub struct HeapAllocation;
impl<'tcx> NonConstOp<'tcx> for HeapAllocation { impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::UnallowedHeapAllocations { ccx.tcx.sess.create_err(errors::UnallowedHeapAllocations {
span, span,
kind: ccx.const_kind(), kind: ccx.const_kind(),
@ -402,11 +374,7 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
#[derive(Debug)] #[derive(Debug)]
pub struct InlineAsm; pub struct InlineAsm;
impl<'tcx> NonConstOp<'tcx> for InlineAsm { impl<'tcx> NonConstOp<'tcx> for InlineAsm {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::UnallowedInlineAsm { span, kind: ccx.const_kind() }) ccx.tcx.sess.create_err(errors::UnallowedInlineAsm { span, kind: ccx.const_kind() })
} }
} }
@ -417,11 +385,7 @@ pub struct LiveDrop<'tcx> {
pub dropped_ty: Ty<'tcx>, pub dropped_ty: Ty<'tcx>,
} }
impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> { impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::LiveDrop { ccx.tcx.sess.create_err(errors::LiveDrop {
span, span,
dropped_ty: self.dropped_ty, dropped_ty: self.dropped_ty,
@ -444,11 +408,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
// not additionally emit a feature gate error if activating the feature gate won't work. // not additionally emit a feature gate error if activating the feature gate won't work.
DiagnosticImportance::Secondary DiagnosticImportance::Secondary
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx ccx.tcx
.sess .sess
.create_feature_err(errors::InteriorMutabilityBorrow { span }, sym::const_refs_to_cell) .create_feature_err(errors::InteriorMutabilityBorrow { span }, sym::const_refs_to_cell)
@ -461,11 +421,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
/// it in the future for static items. /// it in the future for static items.
pub struct CellBorrow; pub struct CellBorrow;
impl<'tcx> NonConstOp<'tcx> for CellBorrow { impl<'tcx> NonConstOp<'tcx> for CellBorrow {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
// FIXME: Maybe a more elegant solution to this if else case // FIXME: Maybe a more elegant solution to this if else case
if let hir::ConstContext::Static(_) = ccx.const_kind() { if let hir::ConstContext::Static(_) = ccx.const_kind() {
ccx.tcx.sess.create_err(errors::InteriorMutableDataRefer { ccx.tcx.sess.create_err(errors::InteriorMutableDataRefer {
@ -502,11 +458,7 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
DiagnosticImportance::Secondary DiagnosticImportance::Secondary
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
match self.0 { match self.0 {
hir::BorrowKind::Raw => ccx.tcx.sess.create_err(errors::UnallowedMutableRefsRaw { hir::BorrowKind::Raw => ccx.tcx.sess.create_err(errors::UnallowedMutableRefsRaw {
span, span,
@ -530,11 +482,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
Status::Unstable(sym::const_mut_refs) Status::Unstable(sym::const_mut_refs)
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let kind = ccx.const_kind(); let kind = ccx.const_kind();
match self.0 { match self.0 {
hir::BorrowKind::Raw => ccx.tcx.sess.create_feature_err( hir::BorrowKind::Raw => ccx.tcx.sess.create_feature_err(
@ -561,11 +509,7 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
DiagnosticImportance::Secondary DiagnosticImportance::Secondary
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_feature_err( ccx.tcx.sess.create_feature_err(
errors::MutDerefErr { span, kind: ccx.const_kind() }, errors::MutDerefErr { span, kind: ccx.const_kind() },
sym::const_mut_refs, sym::const_mut_refs,
@ -577,11 +521,7 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
#[derive(Debug)] #[derive(Debug)]
pub struct PanicNonStr; pub struct PanicNonStr;
impl<'tcx> NonConstOp<'tcx> for PanicNonStr { impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::PanicNonStrErr { span }) ccx.tcx.sess.create_err(errors::PanicNonStrErr { span })
} }
} }
@ -592,11 +532,7 @@ impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
#[derive(Debug)] #[derive(Debug)]
pub struct RawPtrComparison; pub struct RawPtrComparison;
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison { impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
// FIXME(const_trait_impl): revert to span_bug? // FIXME(const_trait_impl): revert to span_bug?
ccx.tcx.sess.create_err(errors::RawPtrComparisonErr { span }) ccx.tcx.sess.create_err(errors::RawPtrComparisonErr { span })
} }
@ -609,11 +545,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
Status::Unstable(sym::const_mut_refs) Status::Unstable(sym::const_mut_refs)
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err( feature_err(
&ccx.tcx.sess.parse_sess, &ccx.tcx.sess.parse_sess,
sym::const_mut_refs, sym::const_mut_refs,
@ -629,11 +561,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
#[derive(Debug)] #[derive(Debug)]
pub struct RawPtrToIntCast; pub struct RawPtrToIntCast;
impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast { impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::RawPtrToIntErr { span }) ccx.tcx.sess.create_err(errors::RawPtrToIntErr { span })
} }
} }
@ -650,11 +578,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
} }
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::StaticAccessErr { ccx.tcx.sess.create_err(errors::StaticAccessErr {
span, span,
kind: ccx.const_kind(), kind: ccx.const_kind(),
@ -667,11 +591,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
#[derive(Debug)] #[derive(Debug)]
pub struct ThreadLocalAccess; pub struct ThreadLocalAccess;
impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess { impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
ccx.tcx.sess.create_err(errors::NonConstOpErr { span }) ccx.tcx.sess.create_err(errors::NonConstOpErr { span })
} }
} }
@ -696,11 +616,7 @@ pub mod ty {
} }
} }
fn build_error( fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
feature_err( feature_err(
&ccx.tcx.sess.parse_sess, &ccx.tcx.sess.parse_sess,
sym::const_mut_refs, sym::const_mut_refs,

View file

@ -28,7 +28,7 @@ pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<Stri
for arg in at_args { for arg in at_args {
match arg_expand(arg.clone()) { match arg_expand(arg.clone()) {
Ok(arg) => args.extend(arg), Ok(arg) => args.extend(arg),
Err(err) => early_dcx.early_error(format!("Failed to load argument file: {err}")), Err(err) => early_dcx.early_fatal(format!("Failed to load argument file: {err}")),
} }
} }
args args

View file

@ -345,7 +345,7 @@ fn run_compiler(
Ok(None) => match matches.free.len() { Ok(None) => match matches.free.len() {
0 => false, // no input: we will exit early 0 => false, // no input: we will exit early
1 => panic!("make_input should have provided valid inputs"), 1 => panic!("make_input should have provided valid inputs"),
_ => default_early_dcx.early_error(format!( _ => default_early_dcx.early_fatal(format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)", "multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0], matches.free[1], matches.free[0], matches.free[1],
)), )),
@ -376,7 +376,7 @@ fn run_compiler(
} }
if !has_input { if !has_input {
early_dcx.early_error("no input filename given"); // this is fatal early_dcx.early_fatal("no input filename given"); // this is fatal
} }
if !sess.opts.unstable_opts.ls.is_empty() { if !sess.opts.unstable_opts.ls.is_empty() {
@ -505,9 +505,8 @@ fn make_input(
if io::stdin().read_to_string(&mut src).is_err() { if io::stdin().read_to_string(&mut src).is_err() {
// Immediately stop compilation if there was an issue reading // Immediately stop compilation if there was an issue reading
// the input (for example if the input stream is not UTF-8). // the input (for example if the input stream is not UTF-8).
let reported = early_dcx.early_error_no_abort( let reported = early_dcx
"couldn't read from stdin, as it did not contain valid UTF-8", .early_err("couldn't read from stdin, as it did not contain valid UTF-8");
);
return Err(reported); return Err(reported);
} }
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
@ -567,7 +566,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
} }
} }
Err(InvalidErrorCode) => { Err(InvalidErrorCode) => {
early_dcx.early_error(format!("{code} is not a valid error code")); early_dcx.early_fatal(format!("{code} is not a valid error code"));
} }
} }
} }
@ -685,7 +684,7 @@ fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dy
safe_println!("{}", String::from_utf8(v).unwrap()); safe_println!("{}", String::from_utf8(v).unwrap());
} }
Input::Str { .. } => { Input::Str { .. } => {
early_dcx.early_error("cannot list metadata for stdin"); early_dcx.early_fatal("cannot list metadata for stdin");
} }
} }
} }
@ -839,7 +838,7 @@ fn print_crate_info(
println_info!("deployment_target={}", format!("{major}.{minor}")) println_info!("deployment_target={}", format!("{major}.{minor}"))
} else { } else {
early_dcx early_dcx
.early_error("only Apple targets currently support deployment version info") .early_fatal("only Apple targets currently support deployment version info")
} }
} }
} }
@ -1182,7 +1181,7 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")), .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
_ => None, _ => None,
}; };
early_dcx.early_error(msg.unwrap_or_else(|| e.to_string())); early_dcx.early_fatal(msg.unwrap_or_else(|| e.to_string()));
}); });
// For all options we just parsed, we check a few aspects: // For all options we just parsed, we check a few aspects:
@ -1333,7 +1332,7 @@ pub fn install_ice_hook(
{ {
// the error code is already going to be reported when the panic unwinds up the stack // the error code is already going to be reported when the panic unwinds up the stack
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
let _ = early_dcx.early_error_no_abort(msg.clone()); let _ = early_dcx.early_err(msg.clone());
return; return;
} }
}; };
@ -1481,7 +1480,7 @@ pub fn init_rustc_env_logger(early_dcx: &EarlyDiagCtxt) {
/// the values directly rather than having to set an environment variable. /// the values directly rather than having to set an environment variable.
pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) { pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) {
if let Err(error) = rustc_log::init_logger(cfg) { if let Err(error) = rustc_log::init_logger(cfg) {
early_dcx.early_error(error.to_string()); early_dcx.early_fatal(error.to_string());
} }
} }
@ -1500,7 +1499,7 @@ pub fn main() -> ! {
.enumerate() .enumerate()
.map(|(i, arg)| { .map(|(i, arg)| {
arg.into_string().unwrap_or_else(|arg| { arg.into_string().unwrap_or_else(|arg| {
early_dcx.early_error(format!("argument {i} is not valid Unicode: {arg:?}")) early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}"))
}) })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -60,7 +60,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
self.emit_messages_default( self.emit_messages_default(
&diag.level, &diag.level,
&diag.message, &diag.messages,
&fluent_args, &fluent_args,
&diag.code, &diag.code,
&primary_span, &primary_span,

View file

@ -103,7 +103,7 @@ pub struct Diagnostic {
// outside of what methods in this crate themselves allow. // outside of what methods in this crate themselves allow.
pub(crate) level: Level, pub(crate) level: Level,
pub message: Vec<(DiagnosticMessage, Style)>, pub messages: Vec<(DiagnosticMessage, Style)>,
pub code: Option<DiagnosticId>, pub code: Option<DiagnosticId>,
pub span: MultiSpan, pub span: MultiSpan,
pub children: Vec<SubDiagnostic>, pub children: Vec<SubDiagnostic>,
@ -161,9 +161,8 @@ pub enum DiagnosticId {
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct SubDiagnostic { pub struct SubDiagnostic {
pub level: Level, pub level: Level,
pub message: Vec<(DiagnosticMessage, Style)>, pub messages: Vec<(DiagnosticMessage, Style)>,
pub span: MultiSpan, pub span: MultiSpan,
pub render_span: Option<MultiSpan>,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -216,14 +215,14 @@ impl StringPart {
impl Diagnostic { impl Diagnostic {
#[track_caller] #[track_caller]
pub fn new<M: Into<DiagnosticMessage>>(level: Level, message: M) -> Self { pub fn new<M: Into<DiagnosticMessage>>(level: Level, message: M) -> Self {
Diagnostic::new_with_code(level, None, message) Diagnostic::new_with_messages(level, vec![(message.into(), Style::NoStyle)])
} }
#[track_caller] #[track_caller]
pub fn new_with_messages(level: Level, messages: Vec<(DiagnosticMessage, Style)>) -> Self { pub fn new_with_messages(level: Level, messages: Vec<(DiagnosticMessage, Style)>) -> Self {
Diagnostic { Diagnostic {
level, level,
message: messages, messages,
code: None, code: None,
span: MultiSpan::new(), span: MultiSpan::new(),
children: vec![], children: vec![],
@ -235,26 +234,6 @@ impl Diagnostic {
} }
} }
#[track_caller]
pub(crate) fn new_with_code<M: Into<DiagnosticMessage>>(
level: Level,
code: Option<DiagnosticId>,
message: M,
) -> Self {
Diagnostic {
level,
message: vec![(message.into(), Style::NoStyle)],
code,
span: MultiSpan::new(),
children: vec![],
suggestions: Ok(vec![]),
args: Default::default(),
sort_span: DUMMY_SP,
is_lint: false,
emitted_at: DiagnosticLocation::caller(),
}
}
#[inline(always)] #[inline(always)]
pub fn level(&self) -> Level { pub fn level(&self) -> Level {
self.level self.level
@ -445,7 +424,7 @@ impl Diagnostic {
/// Add a note attached to this diagnostic. /// Add a note attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Note, msg, MultiSpan::new(), None); self.sub(Level::Note, msg, MultiSpan::new());
self self
} }
@ -453,14 +432,14 @@ impl Diagnostic {
&mut self, &mut self,
msg: Vec<(M, Style)>, msg: Vec<(M, Style)>,
) -> &mut Self { ) -> &mut Self {
self.sub_with_highlights(Level::Note, msg, MultiSpan::new(), None); self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
self self
} }
/// Prints the span with a note above it. /// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span. /// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::OnceNote, msg, MultiSpan::new(), None); self.sub(Level::OnceNote, msg, MultiSpan::new());
self self
} }
@ -472,7 +451,7 @@ impl Diagnostic {
sp: S, sp: S,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self { ) -> &mut Self {
self.sub(Level::Note, msg, sp.into(), None); self.sub(Level::Note, msg, sp.into());
self self
} }
@ -483,14 +462,14 @@ impl Diagnostic {
sp: S, sp: S,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self { ) -> &mut Self {
self.sub(Level::OnceNote, msg, sp.into(), None); self.sub(Level::OnceNote, msg, sp.into());
self self
} }
/// Add a warning attached to this diagnostic. /// Add a warning attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Warning(None), msg, MultiSpan::new(), None); self.sub(Level::Warning(None), msg, MultiSpan::new());
self self
} }
@ -502,27 +481,27 @@ impl Diagnostic {
sp: S, sp: S,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self { ) -> &mut Self {
self.sub(Level::Warning(None), msg, sp.into(), None); self.sub(Level::Warning(None), msg, sp.into());
self self
} }
/// Add a help message attached to this diagnostic. /// Add a help message attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Help, msg, MultiSpan::new(), None); self.sub(Level::Help, msg, MultiSpan::new());
self self
} }
/// Prints the span with a help above it. /// Prints the span with a help above it.
/// This is like [`Diagnostic::help()`], but it gets its own span. /// This is like [`Diagnostic::help()`], but it gets its own span.
pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::OnceHelp, msg, MultiSpan::new(), None); self.sub(Level::OnceHelp, msg, MultiSpan::new());
self self
} }
/// Add a help message attached to this diagnostic with a customizable highlighted message. /// Add a help message attached to this diagnostic with a customizable highlighted message.
pub fn highlighted_help(&mut self, msg: Vec<(String, Style)>) -> &mut Self { pub fn highlighted_help(&mut self, msg: Vec<(String, Style)>) -> &mut Self {
self.sub_with_highlights(Level::Help, msg, MultiSpan::new(), None); self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
self self
} }
@ -534,7 +513,7 @@ impl Diagnostic {
sp: S, sp: S,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self { ) -> &mut Self {
self.sub(Level::Help, msg, sp.into(), None); self.sub(Level::Help, msg, sp.into());
self self
} }
@ -925,7 +904,7 @@ impl Diagnostic {
} }
pub fn set_primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self { pub fn set_primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
self.message[0] = (msg.into(), Style::NoStyle); self.messages[0] = (msg.into(), Style::NoStyle);
self self
} }
@ -952,8 +931,8 @@ impl Diagnostic {
self.args = args; self.args = args;
} }
pub fn styled_message(&self) -> &[(DiagnosticMessage, Style)] { pub fn messages(&self) -> &[(DiagnosticMessage, Style)] {
&self.message &self.messages
} }
/// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by
@ -964,7 +943,7 @@ impl Diagnostic {
attr: impl Into<SubdiagnosticMessage>, attr: impl Into<SubdiagnosticMessage>,
) -> DiagnosticMessage { ) -> DiagnosticMessage {
let msg = let msg =
self.message.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages"); self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages");
msg.with_subdiagnostic_message(attr.into()) msg.with_subdiagnostic_message(attr.into())
} }
@ -972,21 +951,14 @@ impl Diagnostic {
/// public methods above. /// public methods above.
/// ///
/// Used by `proc_macro_server` for implementing `server::Diagnostic`. /// Used by `proc_macro_server` for implementing `server::Diagnostic`.
pub fn sub( pub fn sub(&mut self, level: Level, message: impl Into<SubdiagnosticMessage>, span: MultiSpan) {
&mut self,
level: Level,
message: impl Into<SubdiagnosticMessage>,
span: MultiSpan,
render_span: Option<MultiSpan>,
) {
let sub = SubDiagnostic { let sub = SubDiagnostic {
level, level,
message: vec![( messages: vec![(
self.subdiagnostic_message_to_diagnostic_message(message), self.subdiagnostic_message_to_diagnostic_message(message),
Style::NoStyle, Style::NoStyle,
)], )],
span, span,
render_span,
}; };
self.children.push(sub); self.children.push(sub);
} }
@ -996,15 +968,14 @@ impl Diagnostic {
fn sub_with_highlights<M: Into<SubdiagnosticMessage>>( fn sub_with_highlights<M: Into<SubdiagnosticMessage>>(
&mut self, &mut self,
level: Level, level: Level,
message: Vec<(M, Style)>, messages: Vec<(M, Style)>,
span: MultiSpan, span: MultiSpan,
render_span: Option<MultiSpan>,
) { ) {
let message = message let messages = messages
.into_iter() .into_iter()
.map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1)) .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1))
.collect(); .collect();
let sub = SubDiagnostic { level, message, span, render_span }; let sub = SubDiagnostic { level, messages, span };
self.children.push(sub); self.children.push(sub);
} }
@ -1022,7 +993,7 @@ impl Diagnostic {
) { ) {
( (
&self.level, &self.level,
&self.message, &self.messages,
self.args().collect(), self.args().collect(),
&self.code, &self.code,
&self.span, &self.span,

View file

@ -15,7 +15,7 @@ use std::ops::{Deref, DerefMut};
use std::panic; use std::panic;
use std::thread::panicking; use std::thread::panicking;
/// Trait implemented by error types. This should not be implemented manually. Instead, use /// Trait implemented by error types. This is rarely implemented manually. Instead, use
/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic]. /// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic].
#[rustc_diagnostic_item = "IntoDiagnostic"] #[rustc_diagnostic_item = "IntoDiagnostic"]
pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> { pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
@ -43,24 +43,7 @@ where
/// extending `DiagCtxtFlags`. /// extending `DiagCtxtFlags`.
#[must_use] #[must_use]
#[derive(Clone)] #[derive(Clone)]
pub struct DiagnosticBuilder<'a, G: EmissionGuarantee> { pub struct DiagnosticBuilder<'a, G: EmissionGuarantee = ErrorGuaranteed> {
inner: DiagnosticBuilderInner<'a>,
_marker: PhantomData<G>,
}
/// This type exists only for `DiagnosticBuilder::forget_guarantee`, because it:
/// 1. lacks the `G` parameter and therefore `DiagnosticBuilder<G1>` can be
/// converted into `DiagnosticBuilder<G2>` while reusing the `inner` field
/// 2. can implement the `Drop` "bomb" instead of `DiagnosticBuilder`, as it
/// contains all of the data (`state` + `diagnostic`) of `DiagnosticBuilder`
///
/// The `diagnostic` field is not `Copy` and can't be moved out of whichever
/// type implements the `Drop` "bomb", but because of the above two facts, that
/// never needs to happen - instead, the whole `inner: DiagnosticBuilderInner`
/// can be moved out of a `DiagnosticBuilder` and into another.
#[must_use]
#[derive(Clone)]
struct DiagnosticBuilderInner<'a> {
state: DiagnosticBuilderState<'a>, state: DiagnosticBuilderState<'a>,
/// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a /// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a
@ -68,6 +51,8 @@ struct DiagnosticBuilderInner<'a> {
/// In theory, return value optimization (RVO) should avoid unnecessary /// In theory, return value optimization (RVO) should avoid unnecessary
/// copying. In practice, it does not (at the time of writing). /// copying. In practice, it does not (at the time of writing).
diagnostic: Box<Diagnostic>, diagnostic: Box<Diagnostic>,
_marker: PhantomData<G>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -83,7 +68,7 @@ enum DiagnosticBuilderState<'a> {
/// assumed that `.emit()` was previously called, to end up in this state. /// assumed that `.emit()` was previously called, to end up in this state.
/// ///
/// While this is also used by `.cancel()`, this state is only observed by /// While this is also used by `.cancel()`, this state is only observed by
/// the `Drop` `impl` of `DiagnosticBuilderInner`, as `.cancel()` takes /// the `Drop` `impl` of `DiagnosticBuilder`, because `.cancel()` takes
/// `self` by-value specifically to prevent any attempts to `.emit()`. /// `self` by-value specifically to prevent any attempts to `.emit()`.
/// ///
// FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`, // FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`,
@ -115,12 +100,11 @@ pub trait EmissionGuarantee: Sized {
impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Most `emit_producing_guarantee` functions use this as a starting point. /// Most `emit_producing_guarantee` functions use this as a starting point.
fn emit_producing_nothing(&mut self) { fn emit_producing_nothing(&mut self) {
match self.inner.state { match self.state {
// First `.emit()` call, the `&DiagCtxt` is still available. // First `.emit()` call, the `&DiagCtxt` is still available.
DiagnosticBuilderState::Emittable(dcx) => { DiagnosticBuilderState::Emittable(dcx) => {
self.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
dcx.emit_diagnostic_without_consuming(&mut self.diagnostic);
dcx.emit_diagnostic_without_consuming(&mut self.inner.diagnostic);
} }
// `.emit()` was previously called, disallowed from repeating it. // `.emit()` was previously called, disallowed from repeating it.
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
@ -128,34 +112,24 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
} }
} }
impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
/// Discard the guarantee `.emit()` would return, in favor of having the
/// type `DiagnosticBuilder<'a, ()>`. This may be necessary whenever there
/// is a common codepath handling both errors and warnings.
pub fn forget_guarantee(self) -> DiagnosticBuilder<'a, ()> {
DiagnosticBuilder { inner: self.inner, _marker: PhantomData }
}
}
// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`. // FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
impl EmissionGuarantee for ErrorGuaranteed { impl EmissionGuarantee for ErrorGuaranteed {
fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult { fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
// Contrast this with `emit_producing_nothing`. // Contrast this with `emit_producing_nothing`.
match db.inner.state { match db.state {
// First `.emit()` call, the `&DiagCtxt` is still available. // First `.emit()` call, the `&DiagCtxt` is still available.
DiagnosticBuilderState::Emittable(dcx) => { DiagnosticBuilderState::Emittable(dcx) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; db.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
let guar = dcx.emit_diagnostic_without_consuming(&mut db.diagnostic);
let guar = dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
// Only allow a guarantee if the `level` wasn't switched to a // Only allow a guarantee if the `level` wasn't switched to a
// non-error - the field isn't `pub`, but the whole `Diagnostic` // non-error - the field isn't `pub`, but the whole `Diagnostic`
// can be overwritten with a new one, thanks to `DerefMut`. // can be overwritten with a new one, thanks to `DerefMut`.
assert!( assert!(
db.inner.diagnostic.is_error(), db.diagnostic.is_error(),
"emitted non-error ({:?}) diagnostic \ "emitted non-error ({:?}) diagnostic \
from `DiagnosticBuilder<ErrorGuaranteed>`", from `DiagnosticBuilder<ErrorGuaranteed>`",
db.inner.diagnostic.level, db.diagnostic.level,
); );
guar.unwrap() guar.unwrap()
} }
@ -167,10 +141,10 @@ impl EmissionGuarantee for ErrorGuaranteed {
// non-error - the field isn't `pub`, but the whole `Diagnostic` // non-error - the field isn't `pub`, but the whole `Diagnostic`
// can be overwritten with a new one, thanks to `DerefMut`. // can be overwritten with a new one, thanks to `DerefMut`.
assert!( assert!(
db.inner.diagnostic.is_error(), db.diagnostic.is_error(),
"`DiagnosticBuilder<ErrorGuaranteed>`'s diagnostic \ "`DiagnosticBuilder<ErrorGuaranteed>`'s diagnostic \
became non-error ({:?}), after original `.emit()`", became non-error ({:?}), after original `.emit()`",
db.inner.diagnostic.level, db.diagnostic.level,
); );
#[allow(deprecated)] #[allow(deprecated)]
ErrorGuaranteed::unchecked_claim_error_was_emitted() ErrorGuaranteed::unchecked_claim_error_was_emitted()
@ -238,7 +212,7 @@ macro_rules! forward {
$(#[$attrs])* $(#[$attrs])*
#[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")]
pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
self.inner.diagnostic.$n($($name),*); self.diagnostic.$n($($name),*);
self self
} }
}; };
@ -248,13 +222,13 @@ impl<G: EmissionGuarantee> Deref for DiagnosticBuilder<'_, G> {
type Target = Diagnostic; type Target = Diagnostic;
fn deref(&self) -> &Diagnostic { fn deref(&self) -> &Diagnostic {
&self.inner.diagnostic &self.diagnostic
} }
} }
impl<G: EmissionGuarantee> DerefMut for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> DerefMut for DiagnosticBuilder<'_, G> {
fn deref_mut(&mut self) -> &mut Diagnostic { fn deref_mut(&mut self) -> &mut Diagnostic {
&mut self.inner.diagnostic &mut self.diagnostic
} }
} }
@ -271,10 +245,8 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
pub(crate) fn new_diagnostic(dcx: &'a DiagCtxt, diagnostic: Diagnostic) -> Self { pub(crate) fn new_diagnostic(dcx: &'a DiagCtxt, diagnostic: Diagnostic) -> Self {
debug!("Created new diagnostic"); debug!("Created new diagnostic");
Self { Self {
inner: DiagnosticBuilderInner {
state: DiagnosticBuilderState::Emittable(dcx), state: DiagnosticBuilderState::Emittable(dcx),
diagnostic: Box::new(diagnostic), diagnostic: Box::new(diagnostic),
},
_marker: PhantomData, _marker: PhantomData,
} }
} }
@ -306,7 +278,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// which may be expected to *guarantee* the emission of an error, either /// which may be expected to *guarantee* the emission of an error, either
/// at the time of the call, or through a prior `.emit()` call. /// at the time of the call, or through a prior `.emit()` call.
pub fn cancel(mut self) { pub fn cancel(mut self) {
self.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; self.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
drop(self); drop(self);
} }
@ -324,7 +296,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Converts the builder to a `Diagnostic` for later emission, /// Converts the builder to a `Diagnostic` for later emission,
/// unless dcx has disabled such buffering, or `.emit()` was called. /// unless dcx has disabled such buffering, or `.emit()` was called.
pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> { pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a DiagCtxt)> {
let dcx = match self.inner.state { let dcx = match self.state {
// No `.emit()` calls, the `&DiagCtxt` is still available. // No `.emit()` calls, the `&DiagCtxt` is still available.
DiagnosticBuilderState::Emittable(dcx) => dcx, DiagnosticBuilderState::Emittable(dcx) => dcx,
// `.emit()` was previously called, nothing we can do. // `.emit()` was previously called, nothing we can do.
@ -342,7 +314,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
// Take the `Diagnostic` by replacing it with a dummy. // Take the `Diagnostic` by replacing it with a dummy.
let dummy = Diagnostic::new(Level::Allow, DiagnosticMessage::from("")); let dummy = Diagnostic::new(Level::Allow, DiagnosticMessage::from(""));
let diagnostic = std::mem::replace(&mut *self.inner.diagnostic, dummy); let diagnostic = std::mem::replace(&mut *self.diagnostic, dummy);
// Disable the ICE on `Drop`. // Disable the ICE on `Drop`.
self.cancel(); self.cancel();
@ -356,7 +328,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Retrieves the [`DiagCtxt`] if available /// Retrieves the [`DiagCtxt`] if available
pub fn dcx(&self) -> Option<&DiagCtxt> { pub fn dcx(&self) -> Option<&DiagCtxt> {
match self.inner.state { match self.state {
DiagnosticBuilderState::Emittable(dcx) => Some(dcx), DiagnosticBuilderState::Emittable(dcx) => Some(dcx),
DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => None, DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => None,
} }
@ -544,13 +516,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.diagnostic.fmt(f) self.diagnostic.fmt(f)
} }
} }
/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled /// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled
/// or we emit a bug. /// or we emit a bug.
impl Drop for DiagnosticBuilderInner<'_> { impl<G: EmissionGuarantee> Drop for DiagnosticBuilder<'_, G> {
fn drop(&mut self) { fn drop(&mut self) {
match self.state { match self.state {
// No `.emit()` or `.cancel()` calls. // No `.emit()` or `.cancel()` calls.

View file

@ -312,25 +312,13 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for TargetDataLayoutErrors<'_>
pub struct SingleLabelManySpans { pub struct SingleLabelManySpans {
pub spans: Vec<Span>, pub spans: Vec<Span>,
pub label: &'static str, pub label: &'static str,
pub kind: LabelKind,
} }
impl AddToDiagnostic for SingleLabelManySpans { impl AddToDiagnostic for SingleLabelManySpans {
fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) { fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) {
match self.kind { diag.span_labels(self.spans, self.label);
LabelKind::Note => diag.span_note(self.spans, self.label),
LabelKind::Label => diag.span_labels(self.spans, self.label),
LabelKind::Help => diag.span_help(self.spans, self.label),
};
} }
} }
/// The kind of label to attach when using [`SingleLabelManySpans`]
pub enum LabelKind {
Note,
Label,
Help,
}
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[label(errors_expected_lifetime_parameter)] #[label(errors_expected_lifetime_parameter)]
pub struct ExpectedLifetimeParameter { pub struct ExpectedLifetimeParameter {

View file

@ -350,9 +350,8 @@ pub trait Emitter: Translate {
children.push(SubDiagnostic { children.push(SubDiagnostic {
level: Level::Note, level: Level::Note,
message: vec![(DiagnosticMessage::from(msg), Style::NoStyle)], messages: vec![(DiagnosticMessage::from(msg), Style::NoStyle)],
span: MultiSpan::new(), span: MultiSpan::new(),
render_span: None,
}); });
} }
} }
@ -533,7 +532,7 @@ impl Emitter for EmitterWriter {
self.emit_messages_default( self.emit_messages_default(
&diag.level, &diag.level,
&diag.message, &diag.messages,
&fluent_args, &fluent_args,
&diag.code, &diag.code,
&primary_span, &primary_span,
@ -1228,10 +1227,10 @@ impl EmitterWriter {
/// Adds a left margin to every line but the first, given a padding length and the label being /// Adds a left margin to every line but the first, given a padding length and the label being
/// displayed, keeping the provided highlighting. /// displayed, keeping the provided highlighting.
fn msg_to_buffer( fn msgs_to_buffer(
&self, &self,
buffer: &mut StyledBuffer, buffer: &mut StyledBuffer,
msg: &[(DiagnosticMessage, Style)], msgs: &[(DiagnosticMessage, Style)],
args: &FluentArgs<'_>, args: &FluentArgs<'_>,
padding: usize, padding: usize,
label: &str, label: &str,
@ -1267,7 +1266,7 @@ impl EmitterWriter {
// Provided the following diagnostic message: // Provided the following diagnostic message:
// //
// let msg = vec![ // let msgs = vec![
// (" // ("
// ("highlighted multiline\nstring to\nsee how it ", Style::NoStyle), // ("highlighted multiline\nstring to\nsee how it ", Style::NoStyle),
// ("looks", Style::Highlight), // ("looks", Style::Highlight),
@ -1284,7 +1283,7 @@ impl EmitterWriter {
// see how it *looks* with // see how it *looks* with
// very *weird* formats // very *weird* formats
// see? // see?
for (text, style) in msg.iter() { for (text, style) in msgs.iter() {
let text = self.translate_message(text, args).map_err(Report::new).unwrap(); let text = self.translate_message(text, args).map_err(Report::new).unwrap();
let text = &normalize_whitespace(&text); let text = &normalize_whitespace(&text);
let lines = text.split('\n').collect::<Vec<_>>(); let lines = text.split('\n').collect::<Vec<_>>();
@ -1303,10 +1302,10 @@ impl EmitterWriter {
} }
#[instrument(level = "trace", skip(self, args), ret)] #[instrument(level = "trace", skip(self, args), ret)]
fn emit_message_default( fn emit_messages_default_inner(
&mut self, &mut self,
msp: &MultiSpan, msp: &MultiSpan,
msg: &[(DiagnosticMessage, Style)], msgs: &[(DiagnosticMessage, Style)],
args: &FluentArgs<'_>, args: &FluentArgs<'_>,
code: &Option<DiagnosticId>, code: &Option<DiagnosticId>,
level: &Level, level: &Level,
@ -1327,7 +1326,7 @@ impl EmitterWriter {
buffer.append(0, level.to_str(), Style::MainHeaderMsg); buffer.append(0, level.to_str(), Style::MainHeaderMsg);
buffer.append(0, ": ", Style::NoStyle); buffer.append(0, ": ", Style::NoStyle);
} }
self.msg_to_buffer(&mut buffer, msg, args, max_line_num_len, "note", None); self.msgs_to_buffer(&mut buffer, msgs, args, max_line_num_len, "note", None);
} else { } else {
let mut label_width = 0; let mut label_width = 0;
// The failure note level itself does not provide any useful diagnostic information // The failure note level itself does not provide any useful diagnostic information
@ -1360,7 +1359,7 @@ impl EmitterWriter {
buffer.append(0, ": ", header_style); buffer.append(0, ": ", header_style);
label_width += 2; label_width += 2;
} }
for (text, _) in msg.iter() { for (text, _) in msgs.iter() {
let text = self.translate_message(text, args).map_err(Report::new).unwrap(); let text = self.translate_message(text, args).map_err(Report::new).unwrap();
// Account for newlines to align output to its label. // Account for newlines to align output to its label.
for (line, text) in normalize_whitespace(&text).lines().enumerate() { for (line, text) in normalize_whitespace(&text).lines().enumerate() {
@ -1747,7 +1746,7 @@ impl EmitterWriter {
buffer.append(0, level.to_str(), Style::Level(*level)); buffer.append(0, level.to_str(), Style::Level(*level));
buffer.append(0, ": ", Style::HeaderMsg); buffer.append(0, ": ", Style::HeaderMsg);
self.msg_to_buffer( self.msgs_to_buffer(
&mut buffer, &mut buffer,
&[(suggestion.msg.to_owned(), Style::NoStyle)], &[(suggestion.msg.to_owned(), Style::NoStyle)],
args, args,
@ -2074,7 +2073,7 @@ impl EmitterWriter {
fn emit_messages_default( fn emit_messages_default(
&mut self, &mut self,
level: &Level, level: &Level,
message: &[(DiagnosticMessage, Style)], messages: &[(DiagnosticMessage, Style)],
args: &FluentArgs<'_>, args: &FluentArgs<'_>,
code: &Option<DiagnosticId>, code: &Option<DiagnosticId>,
span: &MultiSpan, span: &MultiSpan,
@ -2089,9 +2088,9 @@ impl EmitterWriter {
num_decimal_digits(n) num_decimal_digits(n)
}; };
match self.emit_message_default( match self.emit_messages_default_inner(
span, span,
message, messages,
args, args,
code, code,
level, level,
@ -2118,10 +2117,10 @@ impl EmitterWriter {
} }
if !self.short_message { if !self.short_message {
for child in children { for child in children {
let span = child.render_span.as_ref().unwrap_or(&child.span); let span = &child.span;
if let Err(err) = self.emit_message_default( if let Err(err) = self.emit_messages_default_inner(
span, span,
&child.message, &child.messages,
args, args,
&None, &None,
&child.level, &child.level,
@ -2138,7 +2137,7 @@ impl EmitterWriter {
// do not display this suggestion, it is meant only for tools // do not display this suggestion, it is meant only for tools
} }
SuggestionStyle::HideCodeAlways => { SuggestionStyle::HideCodeAlways => {
if let Err(e) = self.emit_message_default( if let Err(e) = self.emit_messages_default_inner(
&MultiSpan::new(), &MultiSpan::new(),
&[(sugg.msg.to_owned(), Style::HeaderMsg)], &[(sugg.msg.to_owned(), Style::HeaderMsg)],
args, args,

View file

@ -398,7 +398,7 @@ impl Diagnostic {
let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
let output = String::from_utf8(output).unwrap(); let output = String::from_utf8(output).unwrap();
let translated_message = je.translate_messages(&diag.message, &args); let translated_message = je.translate_messages(&diag.messages, &args);
Diagnostic { Diagnostic {
message: translated_message.to_string(), message: translated_message.to_string(),
code: DiagnosticCode::map_opt_string(diag.code.clone(), je), code: DiagnosticCode::map_opt_string(diag.code.clone(), je),
@ -419,16 +419,12 @@ impl Diagnostic {
args: &FluentArgs<'_>, args: &FluentArgs<'_>,
je: &JsonEmitter, je: &JsonEmitter,
) -> Diagnostic { ) -> Diagnostic {
let translated_message = je.translate_messages(&diag.message, args); let translated_message = je.translate_messages(&diag.messages, args);
Diagnostic { Diagnostic {
message: translated_message.to_string(), message: translated_message.to_string(),
code: None, code: None,
level: diag.level.to_str(), level: diag.level.to_str(),
spans: diag spans: DiagnosticSpan::from_multispan(&diag.span, args, je),
.render_span
.as_ref()
.map(|sp| DiagnosticSpan::from_multispan(sp, args, je))
.unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, args, je)),
children: vec![], children: vec![],
rendered: None, rendered: None,
} }

View file

@ -27,26 +27,42 @@ extern crate tracing;
extern crate self as rustc_errors; extern crate self as rustc_errors;
pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{
BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
};
pub use diagnostic_impls::{
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, SingleLabelManySpans,
};
pub use emitter::ColorConfig; pub use emitter::ColorConfig;
pub use rustc_error_messages::{
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
};
pub use rustc_lint_defs::{pluralize, Applicability};
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
pub use rustc_span::ErrorGuaranteed;
pub use snippet::Style;
use rustc_lint_defs::LintExpectationId; // Used by external projects such as `rust-gpu`.
use Level::*; // See https://github.com/rust-lang/rust/pull/115393.
pub use termcolor::{Color, ColorSpec, WriteColor};
use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
use emitter::{is_case_difference, DynEmitter, Emitter, EmitterWriter}; use emitter::{is_case_difference, DynEmitter, Emitter, EmitterWriter};
use registry::Registry; use registry::Registry;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::sync::{Lock, Lrc};
use rustc_data_structures::AtomicRef; use rustc_data_structures::AtomicRef;
pub use rustc_error_messages::{ use rustc_lint_defs::LintExpectationId;
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
};
pub use rustc_lint_defs::{pluralize, Applicability};
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
pub use rustc_span::ErrorGuaranteed;
use rustc_span::{Loc, Span, DUMMY_SP}; use rustc_span::{Loc, Span, DUMMY_SP};
use std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow; use std::borrow::Cow;
use std::error::Report; use std::error::Report;
use std::fmt; use std::fmt;
@ -56,9 +72,7 @@ use std::num::NonZeroUsize;
use std::panic; use std::panic;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
// Used by external projects such as `rust-gpu`. use Level::*;
// See https://github.com/rust-lang/rust/pull/115393.
pub use termcolor::{Color, ColorSpec, WriteColor};
pub mod annotate_snippet_emitter_writer; pub mod annotate_snippet_emitter_writer;
mod diagnostic; mod diagnostic;
@ -76,10 +90,7 @@ mod styled_buffer;
mod tests; mod tests;
pub mod translation; pub mod translation;
pub use diagnostic_builder::IntoDiagnostic; pub type PErr<'a> = DiagnosticBuilder<'a>;
pub use snippet::Style;
pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>;
pub type PResult<'a, T> = Result<T, PErr<'a>>; pub type PResult<'a, T> = Result<T, PErr<'a>>;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" } rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
@ -163,7 +174,7 @@ pub struct SubstitutionPart {
/// Used to translate between `Span`s and byte positions within a single output line in highlighted /// Used to translate between `Span`s and byte positions within a single output line in highlighted
/// code of structured suggestions. /// code of structured suggestions.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct SubstitutionHighlight { pub(crate) struct SubstitutionHighlight {
start: usize, start: usize,
end: usize, end: usize,
} }
@ -190,7 +201,7 @@ impl SubstitutionPart {
impl CodeSuggestion { impl CodeSuggestion {
/// Returns the assembled code suggestions, whether they should be shown with an underline /// Returns the assembled code suggestions, whether they should be shown with an underline
/// and whether the substitution only differs in capitalization. /// and whether the substitution only differs in capitalization.
pub fn splice_lines( pub(crate) fn splice_lines(
&self, &self,
sm: &SourceMap, sm: &SourceMap,
) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, bool)> { ) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, bool)> {
@ -387,8 +398,6 @@ impl CodeSuggestion {
} }
} }
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
/// Signifies that the compiler died with an explicit call to `.bug` /// Signifies that the compiler died with an explicit call to `.bug`
/// or `.span_bug` rather than a failed assertion, etc. /// or `.span_bug` rather than a failed assertion, etc.
pub struct ExplicitBug; pub struct ExplicitBug;
@ -397,20 +406,7 @@ pub struct ExplicitBug;
/// rather than a failed assertion, etc. /// rather than a failed assertion, etc.
pub struct DelayedBugPanic; pub struct DelayedBugPanic;
use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline}; /// A `DiagCtxt` deals with errors and other compiler output.
pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort};
pub use diagnostic_impls::{
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, LabelKind,
SingleLabelManySpans,
};
use std::backtrace::{Backtrace, BacktraceStatus};
/// A handler deals with errors and other compiler output.
/// Certain errors (fatal, bug, unimpl) may cause immediate exit, /// Certain errors (fatal, bug, unimpl) may cause immediate exit,
/// others log errors for later reporting. /// others log errors for later reporting.
pub struct DiagCtxt { pub struct DiagCtxt {
@ -447,7 +443,7 @@ struct DiagCtxtInner {
emitted_diagnostic_codes: FxIndexSet<DiagnosticId>, emitted_diagnostic_codes: FxIndexSet<DiagnosticId>,
/// This set contains a hash of every diagnostic that has been emitted by /// This set contains a hash of every diagnostic that has been emitted by
/// this handler. These hashes is used to avoid emitting the same error /// this `DiagCtxt`. These hashes is used to avoid emitting the same error
/// twice. /// twice.
emitted_diagnostics: FxHashSet<Hash128>, emitted_diagnostics: FxHashSet<Hash128>,
@ -677,7 +673,7 @@ impl DiagCtxt {
let key = (span.with_parent(None), key); let key = (span.with_parent(None), key);
if diag.is_error() { if diag.is_error() {
if matches!(diag.level, Level::Error { lint: true }) { if matches!(diag.level, Error { lint: true }) {
inner.lint_err_count += 1; inner.lint_err_count += 1;
} else { } else {
inner.err_count += 1; inner.err_count += 1;
@ -701,7 +697,7 @@ impl DiagCtxt {
let key = (span.with_parent(None), key); let key = (span.with_parent(None), key);
let diag = inner.stashed_diagnostics.remove(&key)?; let diag = inner.stashed_diagnostics.remove(&key)?;
if diag.is_error() { if diag.is_error() {
if matches!(diag.level, Level::Error { lint: true }) { if matches!(diag.level, Error { lint: true }) {
inner.lint_err_count -= 1; inner.lint_err_count -= 1;
} else { } else {
inner.err_count -= 1; inner.err_count -= 1;
@ -740,37 +736,6 @@ impl DiagCtxt {
result result
} }
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
/// The `id` is used for lint emissions which should also fulfill a lint expectation.
///
/// Attempting to `.emit()` the builder will only emit if either:
/// * `can_emit_warnings` is `true`
/// * `is_force_warn` was set in `DiagnosticId::Lint`
#[track_caller]
pub fn struct_span_warn_with_expectation(
&self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>,
id: LintExpectationId,
) -> DiagnosticBuilder<'_, ()> {
let mut result = self.struct_warn_with_expectation(msg, id);
result.set_span(span);
result
}
/// Construct a builder at the `Allow` level at the given `span` and with the `msg`.
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_allow(
&self,
span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ()> {
let mut result = self.struct_allow(msg);
result.set_span(span);
result
}
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
/// Also include a code. /// Also include a code.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
@ -794,29 +759,14 @@ impl DiagCtxt {
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { pub fn struct_warn(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Warning(None), msg) DiagnosticBuilder::new(self, Warning(None), msg)
}
/// Construct a builder at the `Warning` level with the `msg`. The `id` is used for
/// lint emissions which should also fulfill a lint expectation.
///
/// Attempting to `.emit()` the builder will only emit if either:
/// * `can_emit_warnings` is `true`
/// * `is_force_warn` was set in `DiagnosticId::Lint`
#[track_caller]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
id: LintExpectationId,
) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Warning(Some(id)), msg)
} }
/// Construct a builder at the `Allow` level with the `msg`. /// Construct a builder at the `Allow` level with the `msg`.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Allow, msg) DiagnosticBuilder::new(self, Allow, msg)
} }
/// Construct a builder at the `Expect` level with the `msg`. /// Construct a builder at the `Expect` level with the `msg`.
@ -827,7 +777,7 @@ impl DiagCtxt {
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
id: LintExpectationId, id: LintExpectationId,
) -> DiagnosticBuilder<'_, ()> { ) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Expect(id), msg) DiagnosticBuilder::new(self, Expect(id), msg)
} }
/// Construct a builder at the `Error` level at the given `span` and with the `msg`. /// Construct a builder at the `Error` level at the given `span` and with the `msg`.
@ -837,7 +787,7 @@ impl DiagCtxt {
&self, &self,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let mut result = self.struct_err(msg); let mut result = self.struct_err(msg);
result.set_span(span); result.set_span(span);
result result
@ -851,7 +801,7 @@ impl DiagCtxt {
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
code: DiagnosticId, code: DiagnosticId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let mut result = self.struct_span_err(span, msg); let mut result = self.struct_span_err(span, msg);
result.code(code); result.code(code);
result result
@ -861,18 +811,8 @@ impl DiagCtxt {
// FIXME: This method should be removed (every error should have an associated error code). // FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_err( pub fn struct_err(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_> {
&self, DiagnosticBuilder::new(self, Error { lint: false }, msg)
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
DiagnosticBuilder::new(self, Level::Error { lint: false }, msg)
}
/// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors.
#[doc(hidden)]
#[track_caller]
pub fn struct_err_lint(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Error { lint: true }, msg)
} }
/// Construct a builder at the `Error` level with the `msg` and the `code`. /// Construct a builder at the `Error` level with the `msg` and the `code`.
@ -882,7 +822,7 @@ impl DiagCtxt {
&self, &self,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
code: DiagnosticId, code: DiagnosticId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let mut result = self.struct_err(msg); let mut result = self.struct_err(msg);
result.code(code); result.code(code);
result result
@ -935,7 +875,7 @@ impl DiagCtxt {
&self, &self,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, FatalAbort> { ) -> DiagnosticBuilder<'_, FatalAbort> {
DiagnosticBuilder::new(self, Level::Fatal, msg) DiagnosticBuilder::new(self, Fatal, msg)
} }
/// Construct a builder at the `Fatal` level with the `msg`, that doesn't abort. /// Construct a builder at the `Fatal` level with the `msg`, that doesn't abort.
@ -945,27 +885,27 @@ impl DiagCtxt {
&self, &self,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, FatalError> { ) -> DiagnosticBuilder<'_, FatalError> {
DiagnosticBuilder::new(self, Level::Fatal, msg) DiagnosticBuilder::new(self, Fatal, msg)
} }
/// Construct a builder at the `Help` level with the `msg`. /// Construct a builder at the `Help` level with the `msg`.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn struct_help(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { pub fn struct_help(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Help, msg) DiagnosticBuilder::new(self, Help, msg)
} }
/// Construct a builder at the `Note` level with the `msg`. /// Construct a builder at the `Note` level with the `msg`.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { pub fn struct_note(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
DiagnosticBuilder::new(self, Level::Note, msg) DiagnosticBuilder::new(self, Note, msg)
} }
/// Construct a builder at the `Bug` level with the `msg`. /// Construct a builder at the `Bug` level with the `msg`.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_bug(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, BugAbort> { pub fn struct_bug(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, BugAbort> {
DiagnosticBuilder::new(self, Level::Bug, msg) DiagnosticBuilder::new(self, Bug, msg)
} }
/// Construct a builder at the `Bug` level at the given `span` with the `msg`. /// Construct a builder at the `Bug` level at the given `span` with the `msg`.
@ -1037,7 +977,7 @@ impl DiagCtxt {
} }
pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! { pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
self.inner.borrow_mut().span_bug(span, msg) self.struct_span_bug(span, msg).emit()
} }
/// For documentation on this, see `Session::span_delayed_bug`. /// For documentation on this, see `Session::span_delayed_bug`.
@ -1050,20 +990,14 @@ impl DiagCtxt {
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
let mut inner = self.inner.borrow_mut(); let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug();
if treat_next_err_as_bug {
// This is technically `self.treat_err_as_bug()` but `span_delayed_bug` is called before
// incrementing `err_count` by one, so we need to +1 the comparing.
// FIXME: Would be nice to increment err_count in a more coherent way.
if inner.flags.treat_err_as_bug.is_some_and(|c| {
inner.err_count + inner.lint_err_count + inner.delayed_bug_count() + 1 >= c.get()
}) {
// FIXME: don't abort here if report_delayed_bugs is off // FIXME: don't abort here if report_delayed_bugs is off
inner.span_bug(sp, msg); self.span_bug(sp, msg);
} }
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); let mut diagnostic = Diagnostic::new(DelayedBug, msg);
diagnostic.set_span(sp); diagnostic.set_span(sp);
inner.emit_diagnostic(diagnostic).unwrap() self.emit_diagnostic(diagnostic).unwrap()
} }
// FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
@ -1071,7 +1005,7 @@ impl DiagCtxt {
pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) { pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
let mut inner = self.inner.borrow_mut(); let mut inner = self.inner.borrow_mut();
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); let mut diagnostic = Diagnostic::new(DelayedBug, msg);
if inner.flags.report_delayed_bugs { if inner.flags.report_delayed_bugs {
inner.emit_diagnostic_without_consuming(&mut diagnostic); inner.emit_diagnostic_without_consuming(&mut diagnostic);
} }
@ -1184,10 +1118,9 @@ impl DiagCtxt {
match (errors.len(), warnings.len()) { match (errors.len(), warnings.len()) {
(0, 0) => return, (0, 0) => return,
(0, _) => inner.emitter.emit_diagnostic(&Diagnostic::new( (0, _) => inner
Level::Warning(None), .emitter
DiagnosticMessage::Str(warnings), .emit_diagnostic(&Diagnostic::new(Warning(None), DiagnosticMessage::Str(warnings))),
)),
(_, 0) => { (_, 0) => {
inner.emit_diagnostic(Diagnostic::new(Fatal, errors)); inner.emit_diagnostic(Diagnostic::new(Fatal, errors));
} }
@ -1219,14 +1152,12 @@ impl DiagCtxt {
if error_codes.len() > 9 { "..." } else { "." } if error_codes.len() > 9 { "..." } else { "." }
)); ));
inner.failure_note(format!( inner.failure_note(format!(
"For more information about an error, try \ "For more information about an error, try `rustc --explain {}`.",
`rustc --explain {}`.",
&error_codes[0] &error_codes[0]
)); ));
} else { } else {
inner.failure_note(format!( inner.failure_note(format!(
"For more information about this error, try \ "For more information about this error, try `rustc --explain {}`.",
`rustc --explain {}`.",
&error_codes[0] &error_codes[0]
)); ));
} }
@ -1277,18 +1208,15 @@ impl DiagCtxt {
} }
#[track_caller] #[track_caller]
pub fn create_err<'a>( pub fn create_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> {
&'a self, err.into_diagnostic(self, Error { lint: false })
err: impl IntoDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
err.into_diagnostic(self, Level::Error { lint: false })
} }
pub fn create_warning<'a>( pub fn create_warning<'a>(
&'a self, &'a self,
warning: impl IntoDiagnostic<'a, ()>, warning: impl IntoDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> { ) -> DiagnosticBuilder<'a, ()> {
warning.into_diagnostic(self, Level::Warning(None)) warning.into_diagnostic(self, Warning(None))
} }
pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) {
@ -1299,7 +1227,7 @@ impl DiagCtxt {
&'a self, &'a self,
fatal: impl IntoDiagnostic<'a, FatalError>, fatal: impl IntoDiagnostic<'a, FatalError>,
) -> DiagnosticBuilder<'a, FatalError> { ) -> DiagnosticBuilder<'a, FatalError> {
fatal.into_diagnostic(self, Level::Fatal) fatal.into_diagnostic(self, Fatal)
} }
pub fn emit_almost_fatal<'a>( pub fn emit_almost_fatal<'a>(
@ -1313,7 +1241,7 @@ impl DiagCtxt {
&'a self, &'a self,
fatal: impl IntoDiagnostic<'a, FatalAbort>, fatal: impl IntoDiagnostic<'a, FatalAbort>,
) -> DiagnosticBuilder<'a, FatalAbort> { ) -> DiagnosticBuilder<'a, FatalAbort> {
fatal.into_diagnostic(self, Level::Fatal) fatal.into_diagnostic(self, Fatal)
} }
pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! { pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! {
@ -1324,7 +1252,7 @@ impl DiagCtxt {
&'a self, &'a self,
bug: impl IntoDiagnostic<'a, BugAbort>, bug: impl IntoDiagnostic<'a, BugAbort>,
) -> DiagnosticBuilder<'a, BugAbort> { ) -> DiagnosticBuilder<'a, BugAbort> {
bug.into_diagnostic(self, Level::Bug) bug.into_diagnostic(self, Bug)
} }
pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, BugAbort>) -> ! { pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, BugAbort>) -> ! {
@ -1339,7 +1267,7 @@ impl DiagCtxt {
&'a self, &'a self,
note: impl IntoDiagnostic<'a, ()>, note: impl IntoDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> { ) -> DiagnosticBuilder<'a, ()> {
note.into_diagnostic(self, Level::Note) note.into_diagnostic(self, Note)
} }
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
@ -1426,7 +1354,7 @@ impl DiagCtxtInner {
for diag in diags { for diag in diags {
// Decrement the count tracking the stash; emitting will increment it. // Decrement the count tracking the stash; emitting will increment it.
if diag.is_error() { if diag.is_error() {
if matches!(diag.level, Level::Error { lint: true }) { if matches!(diag.level, Error { lint: true }) {
self.lint_err_count -= 1; self.lint_err_count -= 1;
} else { } else {
self.err_count -= 1; self.err_count -= 1;
@ -1457,9 +1385,8 @@ impl DiagCtxtInner {
&mut self, &mut self,
diagnostic: &mut Diagnostic, diagnostic: &mut Diagnostic,
) -> Option<ErrorGuaranteed> { ) -> Option<ErrorGuaranteed> {
if matches!(diagnostic.level, Level::Error { .. } | Level::Fatal) && self.treat_err_as_bug() if matches!(diagnostic.level, Error { .. } | Fatal) && self.treat_err_as_bug() {
{ diagnostic.level = Bug;
diagnostic.level = Level::Bug;
} }
// The `LintExpectationId` can be stable or unstable depending on when it was created. // The `LintExpectationId` can be stable or unstable depending on when it was created.
@ -1471,7 +1398,7 @@ impl DiagCtxtInner {
return None; return None;
} }
if diagnostic.level == Level::DelayedBug { if diagnostic.level == DelayedBug {
// FIXME(eddyb) this should check for `has_errors` and stop pushing // FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `span_delayed_bugs` // once *any* errors were emitted (and truncate `span_delayed_bugs`
// when an error is first emitted, also), but maybe there's a case // when an error is first emitted, also), but maybe there's a case
@ -1487,7 +1414,7 @@ impl DiagCtxtInner {
} }
if diagnostic.has_future_breakage() { if diagnostic.has_future_breakage() {
// Future breakages aren't emitted if they're Level::Allowed, // Future breakages aren't emitted if they're Level::Allow,
// but they still need to be constructed and stashed below, // but they still need to be constructed and stashed below,
// so they'll trigger the good-path bug check. // so they'll trigger the good-path bug check.
self.suppressed_expected_diag = true; self.suppressed_expected_diag = true;
@ -1509,7 +1436,7 @@ impl DiagCtxtInner {
return None; return None;
} }
if matches!(diagnostic.level, Level::Expect(_) | Level::Allow) { if matches!(diagnostic.level, Expect(_) | Allow) {
(*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {}); (*TRACK_DIAGNOSTICS)(diagnostic, &mut |_| {});
return None; return None;
} }
@ -1534,7 +1461,7 @@ impl DiagCtxtInner {
debug!(?self.emitted_diagnostics); debug!(?self.emitted_diagnostics);
let already_emitted_sub = |sub: &mut SubDiagnostic| { let already_emitted_sub = |sub: &mut SubDiagnostic| {
debug!(?sub); debug!(?sub);
if sub.level != Level::OnceNote && sub.level != Level::OnceHelp { if sub.level != OnceNote && sub.level != OnceHelp {
return false; return false;
} }
let mut hasher = StableHasher::new(); let mut hasher = StableHasher::new();
@ -1559,7 +1486,7 @@ impl DiagCtxtInner {
} }
} }
if diagnostic.is_error() { if diagnostic.is_error() {
if matches!(diagnostic.level, Level::Error { lint: true }) { if matches!(diagnostic.level, Error { lint: true }) {
self.bump_lint_err_count(); self.bump_lint_err_count();
} else { } else {
self.bump_err_count(); self.bump_err_count();
@ -1583,6 +1510,13 @@ impl DiagCtxtInner {
}) })
} }
// Use this one before incrementing `err_count`.
fn treat_next_err_as_bug(&self) -> bool {
self.flags.treat_err_as_bug.is_some_and(|c| {
self.err_count + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get()
})
}
fn delayed_bug_count(&self) -> usize { fn delayed_bug_count(&self) -> usize {
self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len() self.span_delayed_bugs.len() + self.good_path_delayed_bugs.len()
} }
@ -1591,27 +1525,22 @@ impl DiagCtxtInner {
self.err_count > 0 self.err_count > 0
} }
#[track_caller]
fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
let mut diag = Diagnostic::new(Bug, msg);
diag.set_span(sp);
self.emit_diagnostic(diag);
panic::panic_any(ExplicitBug);
}
fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) { fn failure_note(&mut self, msg: impl Into<DiagnosticMessage>) {
self.emit_diagnostic(Diagnostic::new(FailureNote, msg)); self.emit_diagnostic(Diagnostic::new(FailureNote, msg));
} }
fn flush_delayed( fn flush_delayed(
&mut self, &mut self,
bugs: impl IntoIterator<Item = DelayedDiagnostic>, bugs: Vec<DelayedDiagnostic>,
explanation: impl Into<DiagnosticMessage> + Copy, explanation: impl Into<DiagnosticMessage> + Copy,
) { ) {
let mut no_bugs = true; if bugs.is_empty() {
return;
}
// If backtraces are enabled, also print the query stack // If backtraces are enabled, also print the query stack
let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0");
for bug in bugs { for (i, bug) in bugs.into_iter().enumerate() {
if let Some(file) = self.ice_file.as_ref() if let Some(file) = self.ice_file.as_ref()
&& let Ok(mut out) = std::fs::File::options().create(true).append(true).open(file) && let Ok(mut out) = std::fs::File::options().create(true).append(true).open(file)
{ {
@ -1619,25 +1548,25 @@ impl DiagCtxtInner {
&mut out, &mut out,
"delayed span bug: {}\n{}\n", "delayed span bug: {}\n{}\n",
bug.inner bug.inner
.styled_message() .messages()
.iter() .iter()
.filter_map(|(msg, _)| msg.as_str()) .filter_map(|(msg, _)| msg.as_str())
.collect::<String>(), .collect::<String>(),
&bug.note &bug.note
); );
} }
let mut bug =
if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
if no_bugs { if i == 0 {
// Put the overall explanation before the `DelayedBug`s, to // Put the overall explanation before the `DelayedBug`s, to
// frame them better (e.g. separate warnings from them). // frame them better (e.g. separate warnings from them).
self.emit_diagnostic(Diagnostic::new(Bug, explanation)); self.emit_diagnostic(Diagnostic::new(Bug, explanation));
no_bugs = false;
} }
let mut bug =
if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
// "Undelay" the `DelayedBug`s (into plain `Bug`s). // "Undelay" the `DelayedBug`s (into plain `Bug`s).
if bug.level != Level::DelayedBug { if bug.level != DelayedBug {
// NOTE(eddyb) not panicking here because we're already producing // NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier. // an ICE, and the more information the merrier.
bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel { bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
@ -1645,16 +1574,14 @@ impl DiagCtxtInner {
level: bug.level, level: bug.level,
}); });
} }
bug.level = Level::Bug; bug.level = Bug;
self.emit_diagnostic(bug); self.emit_diagnostic(bug);
} }
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
if !no_bugs {
panic::panic_any(DelayedBugPanic); panic::panic_any(DelayedBugPanic);
} }
}
fn bump_lint_err_count(&mut self) { fn bump_lint_err_count(&mut self) {
self.lint_err_count += 1; self.lint_err_count += 1;
@ -1731,25 +1658,80 @@ impl DelayedDiagnostic {
#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)] #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
pub enum Level { pub enum Level {
/// For bugs in the compiler. Manifests as an ICE (internal compiler error) panic.
///
/// Its `EmissionGuarantee` is `BugAbort`.
Bug, Bug,
/// This is a strange one: lets you register an error without emitting it. If compilation ends
/// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be
/// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
/// that should only be reached when compiling erroneous code.
///
/// Its `EmissionGuarantee` is `ErrorGuaranteed`.
DelayedBug, DelayedBug,
/// An error that causes an immediate abort. Used for things like configuration errors,
/// internal overflows, some file operation errors.
///
/// Its `EmissionGuarantee` is `FatalAbort`, except in the non-aborting "almost fatal" case
/// that is occasionaly used, where it is `FatalError`.
Fatal, Fatal,
/// An error in the code being compiled, which prevents compilation from finishing. This is the
/// most common case.
///
/// Its `EmissionGuarantee` is `ErrorGuaranteed`.
Error { Error {
/// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called. /// If this error comes from a lint, don't abort compilation even when abort_if_errors() is
/// called.
lint: bool, lint: bool,
}, },
/// A warning about the code being compiled. Does not prevent compilation from finishing.
///
/// This [`LintExpectationId`] is used for expected lint diagnostics, which should /// This [`LintExpectationId`] is used for expected lint diagnostics, which should
/// also emit a warning due to the `force-warn` flag. In all other cases this should /// also emit a warning due to the `force-warn` flag. In all other cases this should
/// be `None`. /// be `None`.
///
/// Its `EmissionGuarantee` is `()`.
Warning(Option<LintExpectationId>), Warning(Option<LintExpectationId>),
/// A message giving additional context. Rare, because notes are more commonly attached to other
/// diagnostics such as errors.
///
/// Its `EmissionGuarantee` is `()`.
Note, Note,
/// A note that is only emitted once.
/// A note that is only emitted once. Rare, mostly used in circumstances relating to lints.
///
/// Its `EmissionGuarantee` is `()`.
OnceNote, OnceNote,
/// A message suggesting how to fix something. Rare, because help messages are more commonly
/// attached to other diagnostics such as errors.
///
/// Its `EmissionGuarantee` is `()`.
Help, Help,
/// A help that is only emitted once.
/// A help that is only emitted once. Rare.
///
/// Its `EmissionGuarantee` is `()`.
OnceHelp, OnceHelp,
/// Similar to `Note`, but used in cases where compilation has failed. Rare.
///
/// Its `EmissionGuarantee` is `()`.
FailureNote, FailureNote,
/// Only used for lints.
///
/// Its `EmissionGuarantee` is `()`.
Allow, Allow,
/// Only used for lints.
///
/// Its `EmissionGuarantee` is `()`.
Expect(LintExpectationId), Expect(LintExpectationId),
} }
@ -1789,8 +1771,7 @@ impl Level {
Note | OnceNote => "note", Note | OnceNote => "note",
Help | OnceHelp => "help", Help | OnceHelp => "help",
FailureNote => "failure-note", FailureNote => "failure-note",
Allow => panic!("Shouldn't call on allowed error"), Allow | Expect(_) => unreachable!(),
Expect(_) => panic!("Shouldn't call on expected error"),
} }
} }
@ -1800,7 +1781,7 @@ impl Level {
pub fn get_expectation_id(&self) -> Option<LintExpectationId> { pub fn get_expectation_id(&self) -> Option<LintExpectationId> {
match self { match self {
Level::Expect(id) | Level::Warning(Some(id)) => Some(*id), Expect(id) | Warning(Some(id)) => Some(*id),
_ => None, _ => None,
} }
} }

View file

@ -1118,15 +1118,12 @@ impl<'a> ExtCtxt<'a> {
&self, &self,
sp: S, sp: S,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
self.sess.dcx().struct_span_err(sp, msg) self.sess.dcx().struct_span_err(sp, msg)
} }
#[track_caller] #[track_caller]
pub fn create_err( pub fn create_err(&self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> {
&self,
err: impl IntoDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
self.sess.create_err(err) self.sess.create_err(err)
} }
@ -1230,7 +1227,7 @@ pub fn expr_to_spanned_string<'a>(
cx: &'a mut ExtCtxt<'_>, cx: &'a mut ExtCtxt<'_>,
expr: P<ast::Expr>, expr: P<ast::Expr>,
err_msg: &'static str, err_msg: &'static str,
) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a, ErrorGuaranteed>, bool)>> { ) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a>, bool)>> {
// Perform eager expansion on the expression. // Perform eager expansion on the expression.
// We want to be able to handle e.g., `concat!("foo", "bar")`. // We want to be able to handle e.g., `concat!("foo", "bar")`.
let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();

View file

@ -215,7 +215,7 @@ impl<'matcher> Tracker<'matcher> for FailureForwarder {
} }
pub(super) fn emit_frag_parse_err( pub(super) fn emit_frag_parse_err(
mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>, mut e: DiagnosticBuilder<'_>,
parser: &Parser<'_>, parser: &Parser<'_>,
orig_parser: &mut Parser<'_>, orig_parser: &mut Parser<'_>,
site_span: Span, site_span: Span,
@ -224,11 +224,11 @@ pub(super) fn emit_frag_parse_err(
) { ) {
// FIXME(davidtwco): avoid depending on the error message text // FIXME(davidtwco): avoid depending on the error message text
if parser.token == token::Eof if parser.token == token::Eof
&& let DiagnosticMessage::Str(message) = &e.message[0].0 && let DiagnosticMessage::Str(message) = &e.messages[0].0
&& message.ends_with(", found `<eof>`") && message.ends_with(", found `<eof>`")
{ {
let msg = &e.message[0]; let msg = &e.messages[0];
e.message[0] = ( e.messages[0] = (
DiagnosticMessage::from(format!( DiagnosticMessage::from(format!(
"macro expansion ends with an incomplete expression: {}", "macro expansion ends with an incomplete expression: {}",
message.replace(", found `<eof>`", ""), message.replace(", found `<eof>`", ""),

View file

@ -9,8 +9,8 @@ use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::DiagnosticBuilder;
use rustc_errors::{pluralize, PResult}; use rustc_errors::{pluralize, PResult};
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_span::hygiene::{LocalExpnId, Transparency}; use rustc_span::hygiene::{LocalExpnId, Transparency};
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent}; use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
use rustc_span::Span; use rustc_span::Span;
@ -528,7 +528,7 @@ fn out_of_bounds_err<'a>(
max: usize, max: usize,
span: Span, span: Span,
ty: &str, ty: &str,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
let msg = if max == 0 { let msg = if max == 0 {
format!( format!(
"meta-variable expression `{ty}` with depth parameter \ "meta-variable expression `{ty}` with depth parameter \

View file

@ -43,7 +43,7 @@ pub enum ModError<'a> {
ModInBlock(Option<Ident>), ModInBlock(Option<Ident>),
FileNotFound(Ident, PathBuf, PathBuf), FileNotFound(Ident, PathBuf, PathBuf),
MultipleCandidates(Ident, PathBuf, PathBuf), MultipleCandidates(Ident, PathBuf, PathBuf),
ParserError(DiagnosticBuilder<'a, ErrorGuaranteed>), ParserError(DiagnosticBuilder<'a>),
} }
pub(crate) fn parse_external_mod( pub(crate) fn parse_external_mod(

View file

@ -499,12 +499,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message); rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message);
diag.set_span(MultiSpan::from_spans(diagnostic.spans)); diag.set_span(MultiSpan::from_spans(diagnostic.spans));
for child in diagnostic.children { for child in diagnostic.children {
diag.sub( diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans));
child.level.to_internal(),
child.message,
MultiSpan::from_spans(child.spans),
None,
);
} }
self.sess().dcx.emit_diagnostic(diag); self.sess().dcx.emit_diagnostic(diag);
} }

View file

@ -2686,7 +2686,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self, &self,
constrained_regions: FxHashSet<ty::BoundRegionKind>, constrained_regions: FxHashSet<ty::BoundRegionKind>,
referenced_regions: FxHashSet<ty::BoundRegionKind>, referenced_regions: FxHashSet<ty::BoundRegionKind>,
generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>, generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx>,
) { ) {
for br in referenced_regions.difference(&constrained_regions) { for br in referenced_regions.difference(&constrained_regions) {
let br_name = match *br { let br_name = match *br {

View file

@ -1912,11 +1912,7 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id))) res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)))
} }
fn error_392( fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
tcx: TyCtxt<'_>,
span: Span,
param_name: Symbol,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used"); let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used");
err.span_label(span, "unused parameter"); err.span_label(span, "unused parameter");
err err

View file

@ -181,7 +181,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
suggest: bool, suggest: bool,
hir_ty: Option<&hir::Ty<'_>>, hir_ty: Option<&hir::Ty<'_>>,
kind: &'static str, kind: &'static str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
if placeholder_types.is_empty() { if placeholder_types.is_empty() {
return bad_placeholder(tcx, additional_spans, kind); return bad_placeholder(tcx, additional_spans, kind);
} }
@ -333,7 +333,7 @@ fn bad_placeholder<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
mut spans: Vec<Span>, mut spans: Vec<Span>,
kind: &'static str, kind: &'static str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let kind = if kind.ends_with('s') { format!("{kind}es") } else { format!("{kind}s") }; let kind = if kind.ends_with('s') { format!("{kind}es") } else { format!("{kind}s") };
spans.sort(); spans.sort();

View file

@ -6,7 +6,7 @@ pub use self::{
missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*, missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
}; };
use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_session::Session; use rustc_session::Session;
pub trait StructuredDiagnostic<'tcx> { pub trait StructuredDiagnostic<'tcx> {
@ -14,7 +14,7 @@ pub trait StructuredDiagnostic<'tcx> {
fn code(&self) -> DiagnosticId; fn code(&self) -> DiagnosticId;
fn diagnostic(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
let err = self.diagnostic_common(); let err = self.diagnostic_common();
if self.session().teach(&self.code()) { if self.session().teach(&self.code()) {
@ -24,19 +24,13 @@ pub trait StructuredDiagnostic<'tcx> {
} }
} }
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx>;
fn diagnostic_regular( fn diagnostic_regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
&self,
err: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
err err
} }
fn diagnostic_extended( fn diagnostic_extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
&self,
err: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
err err
} }
} }

View file

@ -1,5 +1,5 @@
use crate::{errors, structured_errors::StructuredDiagnostic}; use crate::{errors, structured_errors::StructuredDiagnostic};
use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_middle::ty::{Ty, TypeVisitableExt};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
@ -20,7 +20,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
rustc_errors::error_code!(E0617) rustc_errors::error_code!(E0617)
} }
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
let (sugg_span, replace, help) = let (sugg_span, replace, help) =
if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) { if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
(Some(self.span), format!("{} as {}", snippet, self.cast_ty), None) (Some(self.span), format!("{} as {}", snippet, self.cast_ty), None)
@ -44,10 +44,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
err err
} }
fn diagnostic_extended( fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
&self,
mut err: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
err.note(format!( err.note(format!(
"certain types, like `{}`, must be casted before passing them to a \ "certain types, like `{}`, must be casted before passing them to a \
variadic function, because of arcane ABI rules dictated by the C \ variadic function, because of arcane ABI rules dictated by the C \

View file

@ -1,5 +1,5 @@
use crate::{errors, structured_errors::StructuredDiagnostic}; use crate::{errors, structured_errors::StructuredDiagnostic};
use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_middle::ty::{Ty, TypeVisitableExt};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
@ -20,7 +20,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> {
rustc_errors::error_code!(E0607) rustc_errors::error_code!(E0607)
} }
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
let mut err = self.sess.create_err(errors::CastThinPointerToFatPointer { let mut err = self.sess.create_err(errors::CastThinPointerToFatPointer {
span: self.span, span: self.span,
expr_ty: self.expr_ty, expr_ty: self.expr_ty,
@ -34,10 +34,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> {
err err
} }
fn diagnostic_extended( fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
&self,
mut err: DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
err.help( err.help(
"Thin pointers are \"simple\" pointers: they are purely a reference to a "Thin pointers are \"simple\" pointers: they are purely a reference to a
memory address. memory address.

View file

@ -1,7 +1,6 @@
use crate::structured_errors::StructuredDiagnostic; use crate::structured_errors::StructuredDiagnostic;
use rustc_errors::{ use rustc_errors::{
pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed, pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, MultiSpan,
MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
@ -521,7 +520,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
} }
fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> {
let span = self.path_segment.ident.span; let span = self.path_segment.ident.span;
let msg = self.create_error_message(); let msg = self.create_error_message();
@ -1113,7 +1112,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
rustc_errors::error_code!(E0107) rustc_errors::error_code!(E0107)
} }
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
let mut err = self.start_diagnostics(); let mut err = self.start_diagnostics();
self.notify(&mut err); self.notify(&mut err);

View file

@ -187,7 +187,7 @@ fn make_invalid_casting_error<'a, 'tcx>(
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
cast_ty: Ty<'tcx>, cast_ty: Ty<'tcx>,
fcx: &FnCtxt<'a, 'tcx>, fcx: &FnCtxt<'a, 'tcx>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
type_error_struct!( type_error_struct!(
sess, sess,
span, span,

View file

@ -36,9 +36,7 @@
//! ``` //! ```
use crate::FnCtxt; use crate::FnCtxt;
use rustc_errors::{ use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
@ -1772,7 +1770,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
id: hir::HirId, id: hir::HirId,
expression: Option<&'tcx hir::Expr<'tcx>>, expression: Option<&'tcx hir::Expr<'tcx>>,
blk_id: Option<hir::HirId>, blk_id: Option<hir::HirId>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
let parent_id = fcx.tcx.hir().parent_id(id); let parent_id = fcx.tcx.hir().parent_id(id);

View file

@ -1,6 +1,6 @@
use crate::FnCtxt; use crate::FnCtxt;
use rustc_errors::MultiSpan; use rustc_errors::MultiSpan;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -168,7 +168,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp: Span, sp: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
self.demand_suptype_with_origin(&self.misc(sp), expected, actual) self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
} }
@ -178,7 +178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
match self.at(cause, self.param_env).sup(DefineOpaqueTypes::Yes, expected, actual) { match self.at(cause, self.param_env).sup(DefineOpaqueTypes::Yes, expected, actual) {
Ok(InferOk { obligations, value: () }) => { Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations); self.register_predicates(obligations);
@ -199,7 +199,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp: Span, sp: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
} }
@ -208,7 +208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
match self.at(cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, actual) { match self.at(cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, actual) {
Ok(InferOk { obligations, value: () }) => { Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations); self.register_predicates(obligations);
@ -246,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
allow_two_phase: AllowTwoPhase, allow_two_phase: AllowTwoPhase,
) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>) { ) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx>>) {
let expected = self.resolve_vars_with_obligations(expected); let expected = self.resolve_vars_with_obligations(expected);
let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {

View file

@ -966,7 +966,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn check_for_missing_semi( pub fn check_for_missing_semi(
&self, &self,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
if let hir::ExprKind::Binary(binop, lhs, rhs) = expr.kind if let hir::ExprKind::Binary(binop, lhs, rhs) = expr.kind
&& let hir::BinOpKind::Mul = binop.node && let hir::BinOpKind::Mul = binop.node
@ -2738,7 +2738,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: Ident, field: Ident,
expr_t: Ty<'tcx>, expr_t: Ty<'tcx>,
id: HirId, id: HirId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let span = field.span; let span = field.span;
debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
@ -2821,11 +2821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err err
} }
fn private_field_err( fn private_field_err(&self, field: Ident, base_did: DefId) -> DiagnosticBuilder<'_> {
&self,
field: Ident,
base_did: DefId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let struct_path = self.tcx().def_path_str(base_did); let struct_path = self.tcx().def_path_str(base_did);
let kind_name = self.tcx().def_descr(base_did); let kind_name = self.tcx().def_descr(base_did);
let mut err = struct_span_err!( let mut err = struct_span_err!(

View file

@ -1258,7 +1258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>, provided_ty: Ty<'tcx>,
arg: &hir::Expr<'tcx>, arg: &hir::Expr<'tcx>,
err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>, err: &mut rustc_errors::DiagnosticBuilder<'tcx>,
) { ) {
if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind() if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind()
&& let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = && let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) =

View file

@ -13,8 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::unord::UnordSet; use rustc_data_structures::unord::UnordSet;
use rustc_errors::StashKey; use rustc_errors::StashKey;
use rustc_errors::{ use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -120,7 +119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
args: Option<&'tcx [hir::Expr<'tcx>]>, args: Option<&'tcx [hir::Expr<'tcx>]>,
expected: Expectation<'tcx>, expected: Expectation<'tcx>,
trait_missing_method: bool, trait_missing_method: bool,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'_>> {
// Avoid suggestions when we don't know what's going on. // Avoid suggestions when we don't know what's going on.
if rcvr_ty.references_error() { if rcvr_ty.references_error() {
return None; return None;
@ -261,7 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
rcvr_ty: Ty<'tcx>, rcvr_ty: Ty<'tcx>,
rcvr_expr: &hir::Expr<'tcx>, rcvr_expr: &hir::Expr<'tcx>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let mut file = None; let mut file = None;
let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file); let ty_str = self.tcx.short_ty_string(rcvr_ty, &mut file);
let mut err = struct_span_err!( let mut err = struct_span_err!(
@ -299,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
no_match_data: &mut NoMatchData<'tcx>, no_match_data: &mut NoMatchData<'tcx>,
expected: Expectation<'tcx>, expected: Expectation<'tcx>,
trait_missing_method: bool, trait_missing_method: bool,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'_>> {
let mode = no_match_data.mode; let mode = no_match_data.mode;
let tcx = self.tcx; let tcx = self.tcx;
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);

View file

@ -99,7 +99,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
ti: TopInfo<'tcx>, ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let mut diag = let mut diag =
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?;
if let Some(expr) = ti.origin_expr { if let Some(expr) = ti.origin_expr {
@ -967,7 +967,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn emit_bad_pat_path( fn emit_bad_pat_path(
&self, &self,
mut e: DiagnosticBuilder<'_, ErrorGuaranteed>, mut e: DiagnosticBuilder<'_>,
pat: &hir::Pat<'tcx>, pat: &hir::Pat<'tcx>,
res: Res, res: Res,
pat_res: Res, pat_res: Res,
@ -1508,7 +1508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant: &VariantDef, variant: &VariantDef,
pat: &'_ Pat<'_>, pat: &'_ Pat<'_>,
fields: &[hir::PatField<'_>], fields: &[hir::PatField<'_>],
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'_>> {
// if this is a tuple struct, then all field names will be numbers // if this is a tuple struct, then all field names will be numbers
// so if any fields in a struct pattern use shorthand syntax, they will // so if any fields in a struct pattern use shorthand syntax, they will
// be invalid identifiers (for example, Foo { 0, 1 }). // be invalid identifiers (for example, Foo { 0, 1 }).
@ -1584,7 +1584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>, pat: &'tcx Pat<'tcx>,
variant: &ty::VariantDef, variant: &ty::VariantDef,
args: &'tcx ty::List<ty::GenericArg<'tcx>>, args: &'tcx ty::List<ty::GenericArg<'tcx>>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let (field_names, t, plural) = if let [field] = inexistent_fields { let (field_names, t, plural) = if let [field] = inexistent_fields {
(format!("a field named `{}`", field.ident), "this", "") (format!("a field named `{}`", field.ident), "this", "")
@ -1689,7 +1689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &Pat<'_>, pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
variant: &ty::VariantDef, variant: &ty::VariantDef,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
if let (Some(CtorKind::Fn), PatKind::Struct(qpath, pattern_fields, ..)) = if let (Some(CtorKind::Fn), PatKind::Struct(qpath, pattern_fields, ..)) =
(variant.ctor_kind(), &pat.kind) (variant.ctor_kind(), &pat.kind)
{ {
@ -1775,7 +1775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
pat: &Pat<'_>, pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = self let mut err = self
.tcx .tcx
.sess .sess
@ -1867,7 +1867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unmentioned_fields: &[(&ty::FieldDef, Ident)], unmentioned_fields: &[(&ty::FieldDef, Ident)],
have_inaccessible_fields: bool, have_inaccessible_fields: bool,
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
let field_names = if let [(_, field)] = unmentioned_fields { let field_names = if let [(_, field)] = unmentioned_fields {
format!("field `{field}`{inaccessible}") format!("field `{field}`{inaccessible}")

View file

@ -306,7 +306,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
hidden_ty: Ty<'tcx>, hidden_ty: Ty<'tcx>,
hidden_region: ty::Region<'tcx>, hidden_region: ty::Region<'tcx>,
opaque_ty_key: ty::OpaqueTypeKey<'tcx>, opaque_ty_key: ty::OpaqueTypeKey<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = tcx.sess.create_err(errors::OpaqueCapturesLifetime { let mut err = tcx.sess.create_err(errors::OpaqueCapturesLifetime {
span, span,
opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args),
@ -2171,7 +2171,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
trace: TypeTrace<'tcx>, trace: TypeTrace<'tcx>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
let span = trace.cause.span(); let span = trace.cause.span();
@ -2319,7 +2319,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>, origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>, bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
if let Some(SubregionOrigin::CompareImplItemObligation { if let Some(SubregionOrigin::CompareImplItemObligation {
span, span,
impl_item_def_id, impl_item_def_id,
@ -2732,7 +2732,7 @@ impl<'tcx> InferCtxt<'tcx> {
fn report_inference_failure( fn report_inference_failure(
&self, &self,
var_origin: RegionVariableOrigin, var_origin: RegionVariableOrigin,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let br_string = |br: ty::BoundRegionKind| { let br_string = |br: ty::BoundRegionKind| {
let mut s = match br { let mut s = match br {
ty::BrNamed(_, name) => name.to_string(), ty::BrNamed(_, name) => name.to_string(),

View file

@ -5,7 +5,7 @@ use crate::errors::{
use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::error_reporting::TypeErrCtxt;
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::InferCtxt; use crate::infer::InferCtxt;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{DiagnosticBuilder, IntoDiagnosticArg};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def::{CtorOf, DefKind, Namespace};
@ -358,7 +358,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Span, span: Span,
arg_data: InferenceDiagnosticsData, arg_data: InferenceDiagnosticsData,
error_code: TypeAnnotationNeeded, error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let source_kind = "other"; let source_kind = "other";
let source_name = ""; let source_name = "";
let failure_span = None; let failure_span = None;
@ -406,7 +406,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
arg: GenericArg<'tcx>, arg: GenericArg<'tcx>,
error_code: TypeAnnotationNeeded, error_code: TypeAnnotationNeeded,
should_label_span: bool, should_label_span: bool,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let arg = self.resolve_vars_if_possible(arg); let arg = self.resolve_vars_if_possible(arg);
let arg_data = self.extract_inference_diagnostics_data(arg, None); let arg_data = self.extract_inference_diagnostics_data(arg, None);

View file

@ -50,7 +50,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
self.cx.tcx self.cx.tcx
} }
pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx>> {
// Due to the improved diagnostics returned by the MIR borrow checker, only a subset of // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of
// the nice region errors are required when running under the MIR borrow checker. // the nice region errors are required when running under the MIR borrow checker.
self.try_report_named_anon_conflict() self.try_report_named_anon_conflict()

View file

@ -5,16 +5,14 @@ use crate::{
errors::ExplicitLifetimeRequired, errors::ExplicitLifetimeRequired,
infer::error_reporting::nice_region_error::find_anon_type::find_anon_type, infer::error_reporting::nice_region_error::find_anon_type::find_anon_type,
}; };
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::DiagnosticBuilder;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// When given a `ConcreteFailure` for a function with parameters containing a named region and /// When given a `ConcreteFailure` for a function with parameters containing a named region and
/// an anonymous region, emit an descriptive diagnostic error. /// an anonymous region, emit an descriptive diagnostic error.
pub(super) fn try_report_named_anon_conflict( pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
&self,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (span, sub, sup) = self.regions()?; let (span, sub, sup) = self.regions()?;
debug!( debug!(

View file

@ -8,7 +8,7 @@ use crate::infer::ValuePairs;
use crate::infer::{SubregionOrigin, TypeTrace}; use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{DiagnosticBuilder, IntoDiagnosticArg};
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::error::ExpectedFound;
@ -57,9 +57,7 @@ where
impl<'tcx> NiceRegionError<'_, 'tcx> { impl<'tcx> NiceRegionError<'_, 'tcx> {
/// When given a `ConcreteFailure` for a function with arguments containing a named region and /// When given a `ConcreteFailure` for a function with arguments containing a named region and
/// an anonymous region, emit a descriptive diagnostic error. /// an anonymous region, emit a descriptive diagnostic error.
pub(super) fn try_report_placeholder_conflict( pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
&self,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
match &self.error { match &self.error {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// NB. The ordering of cases in this match is very // NB. The ordering of cases in this match is very
@ -195,7 +193,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
sub_placeholder: Option<Region<'tcx>>, sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<Region<'tcx>>, sup_placeholder: Option<Region<'tcx>>,
value_pairs: &ValuePairs<'tcx>, value_pairs: &ValuePairs<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let (expected_args, found_args, trait_def_id) = match value_pairs { let (expected_args, found_args, trait_def_id) = match value_pairs {
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found }) ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
if expected.def_id() == found.def_id() => if expected.def_id() == found.def_id() =>
@ -238,7 +236,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
trait_def_id: DefId, trait_def_id: DefId,
expected_args: GenericArgsRef<'tcx>, expected_args: GenericArgsRef<'tcx>,
actual_args: GenericArgsRef<'tcx>, actual_args: GenericArgsRef<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let span = cause.span(); let span = cause.span();
let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) =

View file

@ -5,14 +5,12 @@ use crate::{
}, },
}; };
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::DiagnosticBuilder;
use rustc_middle::ty::{self, RePlaceholder, Region}; use rustc_middle::ty::{self, RePlaceholder, Region};
impl<'tcx> NiceRegionError<'_, 'tcx> { impl<'tcx> NiceRegionError<'_, 'tcx> {
/// Emitted wwhen given a `ConcreteFailure` when relating two placeholders. /// Emitted wwhen given a `ConcreteFailure` when relating two placeholders.
pub(super) fn try_report_placeholder_relation( pub(super) fn try_report_placeholder_relation(&self) -> Option<DiagnosticBuilder<'tcx>> {
&self,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
match &self.error { match &self.error {
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::RelateRegionParamBound(span), SubregionOrigin::RelateRegionParamBound(span),

View file

@ -5,7 +5,7 @@ use crate::errors::{
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
use crate::infer::{self, SubregionOrigin}; use crate::infer::{self, SubregionOrigin};
use rustc_errors::{AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{AddToDiagnostic, Diagnostic, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
@ -78,7 +78,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
origin: SubregionOrigin<'tcx>, origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
sup: Region<'tcx>, sup: Region<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = match origin { let mut err = match origin {
infer::Subtype(box trace) => { infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
@ -350,7 +350,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
placeholder_origin: SubregionOrigin<'tcx>, placeholder_origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
sup: Region<'tcx>, sup: Region<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
// I can't think how to do better than this right now. -nikomatsakis // I can't think how to do better than this right now. -nikomatsakis
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
match placeholder_origin { match placeholder_origin {

View file

@ -1740,9 +1740,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sp: Span, sp: Span,
mk_diag: M, mk_diag: M,
actual_ty: Ty<'tcx>, actual_ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> ) -> DiagnosticBuilder<'tcx>
where where
M: FnOnce(String) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>, M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
{ {
let actual_ty = self.resolve_vars_if_possible(actual_ty); let actual_ty = self.resolve_vars_if_possible(actual_ty);
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
@ -1763,7 +1763,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
err: TypeError<'tcx>, err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
} }
@ -1773,7 +1773,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: ty::Const<'tcx>, expected: ty::Const<'tcx>,
actual: ty::Const<'tcx>, actual: ty::Const<'tcx>,
err: TypeError<'tcx>, err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
} }
} }

View file

@ -2,7 +2,7 @@ use super::ObjectSafetyViolation;
use crate::infer::InferCtxt; use crate::infer::InferCtxt;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_errors::{struct_span_err, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
@ -18,7 +18,7 @@ impl<'tcx> InferCtxt<'tcx> {
impl_item_def_id: LocalDefId, impl_item_def_id: LocalDefId,
trait_item_def_id: DefId, trait_item_def_id: DefId,
requirement: &dyn fmt::Display, requirement: &dyn fmt::Display,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.tcx.sess, self.tcx.sess,
error_span, error_span,
@ -44,7 +44,7 @@ pub fn report_object_safety_error<'tcx>(
span: Span, span: Span,
trait_def_id: DefId, trait_def_id: DefId,
violations: &[ObjectSafetyViolation], violations: &[ObjectSafetyViolation],
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let trait_str = tcx.def_path_str(trait_def_id); let trait_str = tcx.def_path_str(trait_def_id);
let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node { let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node {
hir::Node::Item(item) => Some(item.ident.span), hir::Node::Item(item) => Some(item.ident.span),

View file

@ -347,7 +347,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
) { ) {
Ok(bundle) => bundle, Ok(bundle) => bundle,
Err(e) => { Err(e) => {
early_dcx.early_error(format!("failed to load fluent bundle: {e}")); early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"));
} }
}; };

View file

@ -164,13 +164,13 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn { fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn {
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| { let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {path:?}: {err}"); let err = format!("couldn't load codegen backend {path:?}: {err}");
early_dcx.early_error(err); early_dcx.early_fatal(err);
}); });
let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") } let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
let err = format!("couldn't load codegen backend: {e}"); let err = format!("couldn't load codegen backend: {e}");
early_dcx.early_error(err); early_dcx.early_fatal(err);
}); });
// Intentionally leak the dynamic library. We can't ever unload it // Intentionally leak the dynamic library. We can't ever unload it
@ -271,7 +271,7 @@ fn get_codegen_sysroot(
"failed to find a `codegen-backends` folder \ "failed to find a `codegen-backends` folder \
in the sysroot candidates:\n* {candidates}" in the sysroot candidates:\n* {candidates}"
); );
early_dcx.early_error(err); early_dcx.early_fatal(err);
}); });
info!("probing {} for a codegen backend", sysroot.display()); info!("probing {} for a codegen backend", sysroot.display());
@ -282,7 +282,7 @@ fn get_codegen_sysroot(
sysroot.display(), sysroot.display(),
e e
); );
early_dcx.early_error(err); early_dcx.early_fatal(err);
}); });
let mut file: Option<PathBuf> = None; let mut file: Option<PathBuf> = None;
@ -310,7 +310,7 @@ fn get_codegen_sysroot(
prev.display(), prev.display(),
path.display() path.display()
); );
early_dcx.early_error(err); early_dcx.early_fatal(err);
} }
file = Some(path.clone()); file = Some(path.clone());
} }
@ -319,7 +319,7 @@ fn get_codegen_sysroot(
Some(ref s) => load_backend_from_dylib(early_dcx, s), Some(ref s) => load_backend_from_dylib(early_dcx, s),
None => { None => {
let err = format!("unsupported builtin codegen backend `{backend_name}`"); let err = format!("unsupported builtin codegen backend `{backend_name}`");
early_dcx.early_error(err); early_dcx.early_fatal(err);
} }
} }
} }

View file

@ -293,19 +293,16 @@ pub fn struct_lint_level(
}, },
); );
let mut err = match (level, span) { // Convert lint level to error level.
(Level::Allow, span) => { let err_level = match level {
Level::Allow => {
if has_future_breakage { if has_future_breakage {
if let Some(span) = span { rustc_errors::Level::Allow
sess.struct_span_allow(span, "")
} else {
sess.struct_allow("")
}
} else { } else {
return; return;
} }
} }
(Level::Expect(expect_id), _) => { Level::Expect(expect_id) => {
// This case is special as we actually allow the lint itself in this context, but // This case is special as we actually allow the lint itself in this context, but
// we can't return early like in the case for `Level::Allow` because we still // we can't return early like in the case for `Level::Allow` because we still
// need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`. // need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`.
@ -313,23 +310,16 @@ pub fn struct_lint_level(
// We can also not mark the lint expectation as fulfilled here right away, as it // We can also not mark the lint expectation as fulfilled here right away, as it
// can still be cancelled in the decorate function. All of this means that we simply // can still be cancelled in the decorate function. All of this means that we simply
// create a `DiagnosticBuilder` and continue as we would for warnings. // create a `DiagnosticBuilder` and continue as we would for warnings.
sess.struct_expect("", expect_id) rustc_errors::Level::Expect(expect_id)
} }
(Level::ForceWarn(Some(expect_id)), Some(span)) => { Level::ForceWarn(Some(expect_id)) => rustc_errors::Level::Warning(Some(expect_id)),
sess.struct_span_warn_with_expectation(span, "", expect_id) Level::Warn | Level::ForceWarn(None) => rustc_errors::Level::Warning(None),
} Level::Deny | Level::Forbid => rustc_errors::Level::Error { lint: true },
(Level::ForceWarn(Some(expect_id)), None) => {
sess.struct_warn_with_expectation("", expect_id)
}
(Level::Warn | Level::ForceWarn(None), Some(span)) => sess.struct_span_warn(span, ""),
(Level::Warn | Level::ForceWarn(None), None) => sess.struct_warn(""),
(Level::Deny | Level::Forbid, Some(span)) => {
let mut builder = sess.dcx().struct_err_lint("");
builder.set_span(span);
builder
}
(Level::Deny | Level::Forbid, None) => sess.dcx().struct_err_lint(""),
}; };
let mut err = DiagnosticBuilder::new(sess.dcx(), err_level, "");
if let Some(span) = span {
err.set_span(span);
}
err.set_is_lint(); err.set_is_lint();

View file

@ -90,10 +90,7 @@ pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
/// This is needed in `thir::pattern::lower_inline_const`. /// This is needed in `thir::pattern::lower_inline_const`.
pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>; pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
pub fn struct_error<'tcx>( pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> {
tcx: TyCtxtAt<'tcx>,
msg: &str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
} }

View file

@ -1481,7 +1481,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
other: &Self, other: &Self,
opaque_def_id: LocalDefId, opaque_def_id: LocalDefId,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
if let Some(diag) = tcx if let Some(diag) = tcx
.sess .sess
.dcx() .dcx()

View file

@ -2,7 +2,7 @@ use crate::fluent_generated as fluent;
use rustc_errors::DiagnosticArgValue; use rustc_errors::DiagnosticArgValue;
use rustc_errors::{ use rustc_errors::{
error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
ErrorGuaranteed, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage,
}; };
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -461,11 +461,7 @@ pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
} }
impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
fn into_diagnostic( fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'_> {
self,
dcx: &'a DiagCtxt,
level: Level,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = DiagnosticBuilder::new( let mut diag = DiagnosticBuilder::new(
dcx, dcx,
level, level,

View file

@ -54,11 +54,7 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
visitor.error visitor.error
} }
fn create_e0004( fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> {
sess: &Session,
sp: Span,
error_message: String,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
struct_span_err!(sess, sp, E0004, "{}", &error_message) struct_span_err!(sess, sp, E0004, "{}", &error_message)
} }

View file

@ -3,8 +3,8 @@ use std::borrow::Cow;
use rustc_ast::token::Token; use rustc_ast::token::Token;
use rustc_ast::{Path, Visibility}; use rustc_ast::{Path, Visibility};
use rustc_errors::{ use rustc_errors::{
AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
Level, SubdiagnosticMessage, SubdiagnosticMessage,
}; };
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
@ -1043,11 +1043,7 @@ pub(crate) struct ExpectedIdentifier {
impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier { impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier {
#[track_caller] #[track_caller]
fn into_diagnostic( fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> {
self,
dcx: &'a DiagCtxt,
level: Level,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let token_descr = TokenDescription::from_token(&self.token); let token_descr = TokenDescription::from_token(&self.token);
let mut diag = DiagnosticBuilder::new( let mut diag = DiagnosticBuilder::new(
@ -1107,11 +1103,7 @@ pub(crate) struct ExpectedSemi {
impl<'a> IntoDiagnostic<'a> for ExpectedSemi { impl<'a> IntoDiagnostic<'a> for ExpectedSemi {
#[track_caller] #[track_caller]
fn into_diagnostic( fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> {
self,
dcx: &'a DiagCtxt,
level: Level,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let token_descr = TokenDescription::from_token(&self.token); let token_descr = TokenDescription::from_token(&self.token);
let mut diag = DiagnosticBuilder::new( let mut diag = DiagnosticBuilder::new(

View file

@ -35,7 +35,7 @@ use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{ use rustc_errors::{
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
DiagnosticMessage, ErrorGuaranteed, FatalError, MultiSpan, PResult, DiagnosticMessage, FatalError, MultiSpan, PResult,
}; };
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -245,7 +245,7 @@ impl<'a> Parser<'a> {
&self, &self,
sp: S, sp: S,
m: impl Into<DiagnosticMessage>, m: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
self.dcx().struct_span_err(sp, m) self.dcx().struct_span_err(sp, m)
} }
@ -413,7 +413,7 @@ impl<'a> Parser<'a> {
} }
} }
pub(super) fn expected_ident_found_err(&mut self) -> DiagnosticBuilder<'a, ErrorGuaranteed> { pub(super) fn expected_ident_found_err(&mut self) -> DiagnosticBuilder<'a> {
self.expected_ident_found(false).unwrap_err() self.expected_ident_found(false).unwrap_err()
} }
@ -958,7 +958,7 @@ impl<'a> Parser<'a> {
pub(super) fn recover_closure_body( pub(super) fn recover_closure_body(
&mut self, &mut self,
mut err: DiagnosticBuilder<'a, ErrorGuaranteed>, mut err: DiagnosticBuilder<'a>,
before: token::Token, before: token::Token,
prev: token::Token, prev: token::Token,
token: token::Token, token: token::Token,
@ -1189,7 +1189,7 @@ impl<'a> Parser<'a> {
/// encounter a parse error when encountering the first `,`. /// encounter a parse error when encountering the first `,`.
pub(super) fn check_mistyped_turbofish_with_multiple_type_params( pub(super) fn check_mistyped_turbofish_with_multiple_type_params(
&mut self, &mut self,
mut e: DiagnosticBuilder<'a, ErrorGuaranteed>, mut e: DiagnosticBuilder<'a>,
expr: &mut P<Expr>, expr: &mut P<Expr>,
) -> PResult<'a, ()> { ) -> PResult<'a, ()> {
if let ExprKind::Binary(binop, _, _) = &expr.kind if let ExprKind::Binary(binop, _, _) = &expr.kind
@ -1234,10 +1234,7 @@ impl<'a> Parser<'a> {
/// Suggest add the missing `let` before the identifier in stmt /// Suggest add the missing `let` before the identifier in stmt
/// `a: Ty = 1` -> `let a: Ty = 1` /// `a: Ty = 1` -> `let a: Ty = 1`
pub(super) fn suggest_add_missing_let_for_stmt( pub(super) fn suggest_add_missing_let_for_stmt(&mut self, err: &mut DiagnosticBuilder<'a>) {
&mut self,
err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
) {
if self.token == token::Colon { if self.token == token::Colon {
let prev_span = self.prev_token.span.shrink_to_lo(); let prev_span = self.prev_token.span.shrink_to_lo();
let snapshot = self.create_snapshot_for_diagnostic(); let snapshot = self.create_snapshot_for_diagnostic();
@ -2320,7 +2317,7 @@ impl<'a> Parser<'a> {
} }
} }
pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> { pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a> {
let (span, msg) = match (&self.token.kind, self.subparser_name) { let (span, msg) = match (&self.token.kind, self.subparser_name) {
(&token::Eof, Some(origin)) => { (&token::Eof, Some(origin)) => {
let sp = self.prev_token.span.shrink_to_hi(); let sp = self.prev_token.span.shrink_to_hi();
@ -2572,7 +2569,7 @@ impl<'a> Parser<'a> {
pub fn recover_const_arg( pub fn recover_const_arg(
&mut self, &mut self,
start: Span, start: Span,
mut err: DiagnosticBuilder<'a, ErrorGuaranteed>, mut err: DiagnosticBuilder<'a>,
) -> PResult<'a, GenericArg> { ) -> PResult<'a, GenericArg> {
let is_op_or_dot = AssocOp::from_token(&self.token) let is_op_or_dot = AssocOp::from_token(&self.token)
.and_then(|op| { .and_then(|op| {
@ -2674,7 +2671,7 @@ impl<'a> Parser<'a> {
/// Creates a dummy const argument, and reports that the expression must be enclosed in braces /// Creates a dummy const argument, and reports that the expression must be enclosed in braces
pub fn dummy_const_arg_needs_braces( pub fn dummy_const_arg_needs_braces(
&self, &self,
mut err: DiagnosticBuilder<'a, ErrorGuaranteed>, mut err: DiagnosticBuilder<'a>,
span: Span, span: Span,
) -> GenericArg { ) -> GenericArg {
err.multipart_suggestion( err.multipart_suggestion(

View file

@ -26,8 +26,7 @@ use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
StashKey,
}; };
use rustc_macros::Subdiagnostic; use rustc_macros::Subdiagnostic;
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
@ -1691,7 +1690,7 @@ impl<'a> Parser<'a> {
&self, &self,
lifetime: Ident, lifetime: Ident,
mk_lit_char: impl FnOnce(Symbol, Span) -> L, mk_lit_char: impl FnOnce(Symbol, Span) -> L,
err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>, err: impl FnOnce(&Self) -> DiagnosticBuilder<'a>,
) -> L { ) -> L {
if let Some(mut diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar) if let Some(mut diag) = self.dcx().steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
{ {

View file

@ -32,7 +32,7 @@ use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::PResult; use rustc_errors::PResult;
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, FatalError, MultiSpan};
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -908,7 +908,7 @@ impl<'a> Parser<'a> {
fn recover_missing_braces_around_closure_body( fn recover_missing_braces_around_closure_body(
&mut self, &mut self,
closure_spans: ClosureSpans, closure_spans: ClosureSpans,
mut expect_err: DiagnosticBuilder<'_, ErrorGuaranteed>, mut expect_err: DiagnosticBuilder<'_>,
) -> PResult<'a, ()> { ) -> PResult<'a, ()> {
let initial_semicolon = self.token.span; let initial_semicolon = self.token.span;
@ -1490,7 +1490,7 @@ impl<'a> Parser<'a> {
pub(crate) fn make_unclosed_delims_error( pub(crate) fn make_unclosed_delims_error(
unmatched: UnmatchedDelim, unmatched: UnmatchedDelim,
sess: &ParseSess, sess: &ParseSess,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'_>> {
// `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to
// `unmatched_delims` only for error recovery in the `Parser`. // `unmatched_delims` only for error recovery in the `Parser`.
let found_delim = unmatched.found_delim?; let found_delim = unmatched.found_delim?;

View file

@ -18,7 +18,7 @@ use rustc_ast::{
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax, PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
}; };
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::{respan, Spanned}; use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
@ -687,7 +687,7 @@ impl<'a> Parser<'a> {
fn fatal_unexpected_non_pat( fn fatal_unexpected_non_pat(
&mut self, &mut self,
err: DiagnosticBuilder<'a, ErrorGuaranteed>, err: DiagnosticBuilder<'a>,
expected: Option<Expected>, expected: Option<Expected>,
) -> PResult<'a, P<Pat>> { ) -> PResult<'a, P<Pat>> {
err.cancel(); err.cancel();
@ -969,7 +969,7 @@ impl<'a> Parser<'a> {
let mut fields = ThinVec::new(); let mut fields = ThinVec::new();
let mut etc = false; let mut etc = false;
let mut ate_comma = true; let mut ate_comma = true;
let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None; let mut delayed_err: Option<DiagnosticBuilder<'a>> = None;
let mut first_etc_and_maybe_comma_span = None; let mut first_etc_and_maybe_comma_span = None;
let mut last_non_comma_dotdot_span = None; let mut last_non_comma_dotdot_span = None;
@ -1135,7 +1135,7 @@ impl<'a> Parser<'a> {
fn recover_misplaced_pattern_modifiers( fn recover_misplaced_pattern_modifiers(
&self, &self,
fields: &ThinVec<PatField>, fields: &ThinVec<PatField>,
err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'a>,
) { ) {
if let Some(last) = fields.iter().last() if let Some(last) = fields.iter().last()
&& last.is_shorthand && last.is_shorthand

View file

@ -19,7 +19,7 @@ use rustc_ast::util::classify;
use rustc_ast::{AttrStyle, AttrVec, LocalKind, MacCall, MacCallStmt, MacStmtStyle}; use rustc_ast::{AttrStyle, AttrVec, LocalKind, MacCall, MacCallStmt, MacStmtStyle};
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt}; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt};
use rustc_ast::{StmtKind, DUMMY_NODE_ID}; use rustc_ast::{StmtKind, DUMMY_NODE_ID};
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span};
@ -442,7 +442,7 @@ impl<'a> Parser<'a> {
fn error_block_no_opening_brace_msg( fn error_block_no_opening_brace_msg(
&mut self, &mut self,
msg: Cow<'static, str>, msg: Cow<'static, str>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
let sp = self.token.span; let sp = self.token.span;
let mut e = self.struct_span_err(sp, msg); let mut e = self.struct_span_err(sp, msg);
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon; let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;

View file

@ -4,7 +4,7 @@ use crate::query::plumbing::CycleError;
use crate::query::DepKind; use crate::query::DepKind;
use crate::query::{QueryContext, QueryStackFrame}; use crate::query::{QueryContext, QueryStackFrame};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level}; use rustc_errors::{DiagCtxt, Diagnostic, DiagnosticBuilder, Level};
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
@ -559,7 +559,7 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) {
pub(crate) fn report_cycle<'a>( pub(crate) fn report_cycle<'a>(
sess: &'a Session, sess: &'a Session,
CycleError { usage, cycle: stack }: &CycleError, CycleError { usage, cycle: stack }: &CycleError,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
assert!(!stack.is_empty()); assert!(!stack.is_empty());
let span = stack[0].query.default_span(stack[1 % stack.len()].span); let span = stack[0].query.default_span(stack[1 % stack.len()].span);

View file

@ -19,7 +19,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
#[cfg(parallel_compiler)] #[cfg(parallel_compiler)]
use rustc_data_structures::{outline, sync}; use rustc_data_structures::{outline, sync};
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError, StashKey}; use rustc_errors::{DiagnosticBuilder, FatalError, StashKey};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use std::cell::Cell; use std::cell::Cell;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
@ -112,7 +112,7 @@ fn handle_cycle_error<Q, Qcx>(
query: Q, query: Q,
qcx: Qcx, qcx: Qcx,
cycle_error: &CycleError, cycle_error: &CycleError,
mut error: DiagnosticBuilder<'_, ErrorGuaranteed>, mut error: DiagnosticBuilder<'_>,
) -> Q::Value ) -> Q::Value
where where
Q: QueryConfig<Qcx>, Q: QueryConfig<Qcx>,

View file

@ -551,7 +551,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
span: Span, span: Span,
resolution_error: ResolutionError<'a>, resolution_error: ResolutionError<'a>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
match resolution_error { match resolution_error {
ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => { ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
use errs::GenericParamsFromOuterItemLabel as Label; use errs::GenericParamsFromOuterItemLabel as Label;

View file

@ -3693,7 +3693,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node); let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
// overwrite all properties with the parent's error message // overwrite all properties with the parent's error message
err.message = take(&mut parent_err.message); err.messages = take(&mut parent_err.messages);
err.code = take(&mut parent_err.code); err.code = take(&mut parent_err.code);
swap(&mut err.span, &mut parent_err.span); swap(&mut err.span, &mut parent_err.span);
err.children = take(&mut parent_err.children); err.children = take(&mut parent_err.children);

View file

@ -424,7 +424,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
span: Span, span: Span,
source: PathSource<'_>, source: PathSource<'_>,
res: Option<Res>, res: Option<Res>,
) -> (DiagnosticBuilder<'tcx, ErrorGuaranteed>, Vec<ImportSuggestion>) { ) -> (DiagnosticBuilder<'tcx>, Vec<ImportSuggestion>) {
debug!(?res, ?source); debug!(?res, ?source);
let base_error = self.make_base_error(path, span, source, res); let base_error = self.make_base_error(path, span, source, res);

View file

@ -37,7 +37,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_data_structures::steal::Steal; use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{FreezeReadGuard, Lrc}; use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::Namespace::{self, *};
@ -704,7 +704,7 @@ struct PrivacyError<'a> {
#[derive(Debug)] #[derive(Debug)]
struct UseError<'a> { struct UseError<'a> {
err: DiagnosticBuilder<'a, ErrorGuaranteed>, err: DiagnosticBuilder<'a>,
/// Candidates which user could `use` to access the missing type. /// Candidates which user could `use` to access the missing type.
candidates: Vec<ImportSuggestion>, candidates: Vec<ImportSuggestion>,
/// The `DefId` of the module to place the use-statements in. /// The `DefId` of the module to place the use-statements in.

View file

@ -1594,7 +1594,7 @@ pub(super) fn build_target_config(
|t| Ok((t, TargetWarnings::empty())), |t| Ok((t, TargetWarnings::empty())),
); );
let (target, target_warnings) = target_result.unwrap_or_else(|e| { let (target, target_warnings) = target_result.unwrap_or_else(|e| {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"Error loading target specification: {e}. \ "Error loading target specification: {e}. \
Run `rustc --print target-list` for a list of built-in targets" Run `rustc --print target-list` for a list of built-in targets"
)) ))
@ -1604,7 +1604,7 @@ pub(super) fn build_target_config(
} }
if !matches!(target.pointer_width, 16 | 32 | 64) { if !matches!(target.pointer_width, 16 | 32 | 64) {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"target specification was invalid: unrecognized target-pointer-width {}", "target specification was invalid: unrecognized target-pointer-width {}",
target.pointer_width target.pointer_width
)) ))
@ -1869,7 +1869,7 @@ pub fn get_cmd_lint_options(
let lint_cap = matches.opt_str("cap-lints").map(|cap| { let lint_cap = matches.opt_str("cap-lints").map(|cap| {
lint::Level::from_str(&cap) lint::Level::from_str(&cap)
.unwrap_or_else(|| early_dcx.early_error(format!("unknown lint level: `{cap}`"))) .unwrap_or_else(|| early_dcx.early_fatal(format!("unknown lint level: `{cap}`")))
}); });
(lint_opts, describe_lints, lint_cap) (lint_opts, describe_lints, lint_cap)
@ -1884,7 +1884,7 @@ pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Col
None => ColorConfig::Auto, None => ColorConfig::Auto,
Some(arg) => early_dcx.early_error(format!( Some(arg) => early_dcx.early_fatal(format!(
"argument for `--color` must be auto, \ "argument for `--color` must be auto, \
always or never (instead was `{arg}`)" always or never (instead was `{arg}`)"
)), )),
@ -1942,7 +1942,7 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json
// won't actually be emitting any colors and anything colorized is // won't actually be emitting any colors and anything colorized is
// embedded in a diagnostic message anyway. // embedded in a diagnostic message anyway.
if matches.opt_str("color").is_some() { if matches.opt_str("color").is_some() {
early_dcx.early_error("cannot specify the `--color` option with `--json`"); early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
} }
for sub_option in option.split(',') { for sub_option in option.split(',') {
@ -1953,7 +1953,7 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json
"unused-externs" => json_unused_externs = JsonUnusedExterns::Loud, "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
"unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent, "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
"future-incompat" => json_future_incompat = true, "future-incompat" => json_future_incompat = true,
s => early_dcx.early_error(format!("unknown `--json` option `{s}`")), s => early_dcx.early_fatal(format!("unknown `--json` option `{s}`")),
} }
} }
} }
@ -1993,7 +1993,7 @@ pub fn parse_error_format(
early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable( early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
HumanReadableErrorType::Default(color), HumanReadableErrorType::Default(color),
)); ));
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"argument for `--error-format` must be `human`, `json` or \ "argument for `--error-format` must be `human`, `json` or \
`short` (instead was `{arg}`)" `short` (instead was `{arg}`)"
)) ))
@ -2010,7 +2010,7 @@ pub fn parse_error_format(
// `--error-format=json`. This means that `--json` is specified we // `--error-format=json`. This means that `--json` is specified we
// should actually be emitting JSON blobs. // should actually be emitting JSON blobs.
_ if !matches.opt_strs("json").is_empty() => { _ if !matches.opt_strs("json").is_empty() => {
early_dcx.early_error("using `--json` requires also using `--error-format=json`"); early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
} }
_ => {} _ => {}
@ -2022,7 +2022,7 @@ pub fn parse_error_format(
pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition { pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
let edition = match matches.opt_str("edition") { let edition = match matches.opt_str("edition") {
Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| { Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"argument for `--edition` must be one of: \ "argument for `--edition` must be one of: \
{EDITION_NAME_LIST}. (instead was `{arg}`)" {EDITION_NAME_LIST}. (instead was `{arg}`)"
)) ))
@ -2039,7 +2039,7 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches
} else { } else {
format!("edition {edition} is unstable and only available with -Z unstable-options") format!("edition {edition} is unstable and only available with -Z unstable-options")
}; };
early_dcx.early_error(msg) early_dcx.early_fatal(msg)
} }
edition edition
@ -2057,7 +2057,7 @@ fn check_error_format_stability(
pretty: false, pretty: false,
json_rendered, json_rendered,
}); });
early_dcx.early_error("`--error-format=pretty-json` is unstable"); early_dcx.early_fatal("`--error-format=pretty-json` is unstable");
} }
if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) = if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
error_format error_format
@ -2066,7 +2066,7 @@ fn check_error_format_stability(
pretty: false, pretty: false,
json_rendered, json_rendered,
}); });
early_dcx.early_error("`--error-format=human-annotate-rs` is unstable"); early_dcx.early_fatal("`--error-format=human-annotate-rs` is unstable");
} }
} }
} }
@ -2082,7 +2082,7 @@ fn parse_output_types(
for output_type in list.split(',') { for output_type in list.split(',') {
let (shorthand, path) = split_out_file_name(output_type); let (shorthand, path) = split_out_file_name(output_type);
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| { let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"unknown emission type: `{shorthand}` - expected one of: {display}", "unknown emission type: `{shorthand}` - expected one of: {display}",
display = OutputType::shorthands_display(), display = OutputType::shorthands_display(),
)) ))
@ -2144,7 +2144,7 @@ fn should_override_cgus_and_disable_thinlto(
} }
if codegen_units == Some(0) { if codegen_units == Some(0) {
early_dcx.early_error("value for codegen units must be a positive non-zero integer"); early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
} }
(disable_local_thinlto, codegen_units) (disable_local_thinlto, codegen_units)
@ -2204,7 +2204,7 @@ fn collect_print_requests(
if unstable_opts.unstable_options { if unstable_opts.unstable_options {
PrintKind::TargetSpec PrintKind::TargetSpec
} else { } else {
early_dcx.early_error( early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \ "the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option", enable the target-spec-json print option",
); );
@ -2214,7 +2214,7 @@ fn collect_print_requests(
if unstable_opts.unstable_options { if unstable_opts.unstable_options {
PrintKind::AllTargetSpecs PrintKind::AllTargetSpecs
} else { } else {
early_dcx.early_error( early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \ "the `-Z unstable-options` flag must also be passed to \
enable the all-target-specs-json print option", enable the all-target-specs-json print option",
); );
@ -2225,7 +2225,7 @@ fn collect_print_requests(
let prints = let prints =
PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>(); PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", "); let prints = prints.join(", ");
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"unknown print request `{req}`. Valid print requests are: {prints}" "unknown print request `{req}`. Valid print requests are: {prints}"
)); ));
} }
@ -2234,7 +2234,7 @@ fn collect_print_requests(
let out = out.unwrap_or(OutFileName::Stdout); let out = out.unwrap_or(OutFileName::Stdout);
if let OutFileName::Real(path) = &out { if let OutFileName::Real(path) = &out {
if !printed_paths.insert(path.clone()) { if !printed_paths.insert(path.clone()) {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"cannot print multiple outputs to the same path: {}", "cannot print multiple outputs to the same path: {}",
path.display(), path.display(),
)); ));
@ -2252,7 +2252,7 @@ pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches
Some(target) if target.ends_with(".json") => { Some(target) if target.ends_with(".json") => {
let path = Path::new(&target); let path = Path::new(&target);
TargetTriple::from_path(path).unwrap_or_else(|_| { TargetTriple::from_path(path).unwrap_or_else(|_| {
early_dcx.early_error(format!("target file {path:?} does not exist")) early_dcx.early_fatal(format!("target file {path:?} does not exist"))
}) })
} }
Some(target) => TargetTriple::TargetTriple(target), Some(target) => TargetTriple::TargetTriple(target),
@ -2291,7 +2291,7 @@ fn parse_opt_level(
"s" => OptLevel::Size, "s" => OptLevel::Size,
"z" => OptLevel::SizeMin, "z" => OptLevel::SizeMin,
arg => { arg => {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"optimization level needs to be \ "optimization level needs to be \
between 0-3, s or z (instead was `{arg}`)" between 0-3, s or z (instead was `{arg}`)"
)); ));
@ -2321,7 +2321,7 @@ fn parse_assert_incr_state(
Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded), Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded), Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
Some(s) => { Some(s) => {
early_dcx.early_error(format!("unexpected incremental state assertion value: {s}")) early_dcx.early_fatal(format!("unexpected incremental state assertion value: {s}"))
} }
None => None, None => None,
} }
@ -2348,11 +2348,11 @@ fn parse_native_lib_kind(
} else { } else {
", the `-Z unstable-options` flag must also be passed to use it" ", the `-Z unstable-options` flag must also be passed to use it"
}; };
early_dcx.early_error(format!("library kind `link-arg` is unstable{why}")) early_dcx.early_fatal(format!("library kind `link-arg` is unstable{why}"))
} }
NativeLibKind::LinkArg NativeLibKind::LinkArg
} }
_ => early_dcx.early_error(format!( _ => early_dcx.early_fatal(format!(
"unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg" "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
)), )),
}; };
@ -2372,7 +2372,7 @@ fn parse_native_lib_modifiers(
for modifier in modifiers.split(',') { for modifier in modifiers.split(',') {
let (modifier, value) = match modifier.strip_prefix(['+', '-']) { let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
Some(m) => (m, modifier.starts_with('+')), Some(m) => (m, modifier.starts_with('+')),
None => early_dcx.early_error( None => early_dcx.early_fatal(
"invalid linking modifier syntax, expected '+' or '-' prefix \ "invalid linking modifier syntax, expected '+' or '-' prefix \
before one of: bundle, verbatim, whole-archive, as-needed", before one of: bundle, verbatim, whole-archive, as-needed",
), ),
@ -2385,20 +2385,20 @@ fn parse_native_lib_modifiers(
} else { } else {
", the `-Z unstable-options` flag must also be passed to use it" ", the `-Z unstable-options` flag must also be passed to use it"
}; };
early_dcx.early_error(format!("linking modifier `{modifier}` is unstable{why}")) early_dcx.early_fatal(format!("linking modifier `{modifier}` is unstable{why}"))
} }
}; };
let assign_modifier = |dst: &mut Option<bool>| { let assign_modifier = |dst: &mut Option<bool>| {
if dst.is_some() { if dst.is_some() {
let msg = format!("multiple `{modifier}` modifiers in a single `-l` option"); let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
early_dcx.early_error(msg) early_dcx.early_fatal(msg)
} else { } else {
*dst = Some(value); *dst = Some(value);
} }
}; };
match (modifier, &mut kind) { match (modifier, &mut kind) {
("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle), ("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
("bundle", _) => early_dcx.early_error( ("bundle", _) => early_dcx.early_fatal(
"linking modifier `bundle` is only compatible with `static` linking kind", "linking modifier `bundle` is only compatible with `static` linking kind",
), ),
@ -2407,7 +2407,7 @@ fn parse_native_lib_modifiers(
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
assign_modifier(whole_archive) assign_modifier(whole_archive)
} }
("whole-archive", _) => early_dcx.early_error( ("whole-archive", _) => early_dcx.early_fatal(
"linking modifier `whole-archive` is only compatible with `static` linking kind", "linking modifier `whole-archive` is only compatible with `static` linking kind",
), ),
@ -2416,14 +2416,14 @@ fn parse_native_lib_modifiers(
report_unstable_modifier(); report_unstable_modifier();
assign_modifier(as_needed) assign_modifier(as_needed)
} }
("as-needed", _) => early_dcx.early_error( ("as-needed", _) => early_dcx.early_fatal(
"linking modifier `as-needed` is only compatible with \ "linking modifier `as-needed` is only compatible with \
`dylib` and `framework` linking kinds", `dylib` and `framework` linking kinds",
), ),
// Note: this error also excludes the case with empty modifier // Note: this error also excludes the case with empty modifier
// string, like `modifiers = ""`. // string, like `modifiers = ""`.
_ => early_dcx.early_error(format!( _ => early_dcx.early_fatal(format!(
"unknown linking modifier `{modifier}`, expected one \ "unknown linking modifier `{modifier}`, expected one \
of: bundle, verbatim, whole-archive, as-needed" of: bundle, verbatim, whole-archive, as-needed"
)), )),
@ -2457,7 +2457,7 @@ fn parse_libs(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Vec<Nati
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())), Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
}; };
if name.is_empty() { if name.is_empty() {
early_dcx.early_error("library name must not be empty"); early_dcx.early_fatal("library name must not be empty");
} }
NativeLib { name, new_name, kind, verbatim } NativeLib { name, new_name, kind, verbatim }
}) })
@ -2493,7 +2493,7 @@ pub fn parse_externs(
}; };
if !is_ascii_ident(&name) { if !is_ascii_ident(&name) {
let mut error = early_dcx.early_struct_error(format!( let mut error = early_dcx.early_struct_fatal(format!(
"crate name `{name}` passed to `--extern` is not a valid ASCII identifier" "crate name `{name}` passed to `--extern` is not a valid ASCII identifier"
)); ));
let adjusted_name = name.replace('-', "_"); let adjusted_name = name.replace('-', "_");
@ -2555,7 +2555,7 @@ pub fn parse_externs(
let mut force = false; let mut force = false;
if let Some(opts) = options { if let Some(opts) = options {
if !is_unstable_enabled { if !is_unstable_enabled {
early_dcx.early_error( early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \ "the `-Z unstable-options` flag must also be passed to \
enable `--extern` options", enable `--extern` options",
); );
@ -2567,14 +2567,14 @@ pub fn parse_externs(
if let ExternLocation::ExactPaths(_) = &entry.location { if let ExternLocation::ExactPaths(_) = &entry.location {
add_prelude = false; add_prelude = false;
} else { } else {
early_dcx.early_error( early_dcx.early_fatal(
"the `noprelude` --extern option requires a file path", "the `noprelude` --extern option requires a file path",
); );
} }
} }
"nounused" => nounused_dep = true, "nounused" => nounused_dep = true,
"force" => force = true, "force" => force = true,
_ => early_dcx.early_error(format!("unknown --extern option `{opt}`")), _ => early_dcx.early_fatal(format!("unknown --extern option `{opt}`")),
} }
} }
} }
@ -2602,7 +2602,7 @@ fn parse_remap_path_prefix(
.into_iter() .into_iter()
.map(|remap| match remap.rsplit_once('=') { .map(|remap| match remap.rsplit_once('=') {
None => { None => {
early_dcx.early_error("--remap-path-prefix must contain '=' between FROM and TO") early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
} }
Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)), Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
}) })
@ -2627,7 +2627,7 @@ fn parse_logical_env(
if let Some((name, val)) = arg.split_once('=') { if let Some((name, val)) = arg.split_once('=') {
vars.insert(name.to_string(), val.to_string()); vars.insert(name.to_string(), val.to_string());
} else { } else {
early_dcx.early_error(format!("`--env`: specify value for variable `{arg}`")); early_dcx.early_fatal(format!("`--env`: specify value for variable `{arg}`"));
} }
} }
@ -2653,12 +2653,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
early_dcx.abort_if_error_and_set_error_format(error_format); early_dcx.abort_if_error_and_set_error_format(error_format);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| { let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
early_dcx.early_error("`--diagnostic-width` must be an positive integer"); early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
}); });
let unparsed_crate_types = matches.opt_strs("crate-type"); let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types) let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_dcx.early_error(e)); .unwrap_or_else(|e| early_dcx.early_fatal(e));
let mut unstable_opts = UnstableOptions::build(early_dcx, matches); let mut unstable_opts = UnstableOptions::build(early_dcx, matches);
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
@ -2666,7 +2666,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
check_error_format_stability(early_dcx, &unstable_opts, error_format, json_rendered); check_error_format_stability(early_dcx, &unstable_opts, error_format, json_rendered);
if !unstable_opts.unstable_options && json_unused_externs.is_enabled() { if !unstable_opts.unstable_options && json_unused_externs.is_enabled() {
early_dcx.early_error( early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to enable \ "the `-Z unstable-options` flag must also be passed to enable \
the flag `--json=unused-externs`", the flag `--json=unused-externs`",
); );
@ -2683,15 +2683,15 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
); );
if unstable_opts.threads == 0 { if unstable_opts.threads == 0 {
early_dcx.early_error("value for threads must be a positive non-zero integer"); early_dcx.early_fatal("value for threads must be a positive non-zero integer");
} }
let fuel = unstable_opts.fuel.is_some() || unstable_opts.print_fuel.is_some(); let fuel = unstable_opts.fuel.is_some() || unstable_opts.print_fuel.is_some();
if fuel && unstable_opts.threads > 1 { if fuel && unstable_opts.threads > 1 {
early_dcx.early_error("optimization fuel is incompatible with multiple threads"); early_dcx.early_fatal("optimization fuel is incompatible with multiple threads");
} }
if fuel && cg.incremental.is_some() { if fuel && cg.incremental.is_some() {
early_dcx.early_error("optimization fuel is incompatible with incremental compilation"); early_dcx.early_fatal("optimization fuel is incompatible with incremental compilation");
} }
let incremental = cg.incremental.as_ref().map(PathBuf::from); let incremental = cg.incremental.as_ref().map(PathBuf::from);
@ -2699,25 +2699,25 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
if unstable_opts.profile && incremental.is_some() { if unstable_opts.profile && incremental.is_some() {
early_dcx.early_error("can't instrument with gcov profiling when compiling incrementally"); early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally");
} }
if unstable_opts.profile { if unstable_opts.profile {
match codegen_units { match codegen_units {
Some(1) => {} Some(1) => {}
None => codegen_units = Some(1), None => codegen_units = Some(1),
Some(_) => early_dcx Some(_) => early_dcx
.early_error("can't instrument with gcov profiling with multiple codegen units"), .early_fatal("can't instrument with gcov profiling with multiple codegen units"),
} }
} }
if cg.profile_generate.enabled() && cg.profile_use.is_some() { if cg.profile_generate.enabled() && cg.profile_use.is_some() {
early_dcx.early_error("options `-C profile-generate` and `-C profile-use` are exclusive"); early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
} }
if unstable_opts.profile_sample_use.is_some() if unstable_opts.profile_sample_use.is_some()
&& (cg.profile_generate.enabled() || cg.profile_use.is_some()) && (cg.profile_generate.enabled() || cg.profile_use.is_some())
{ {
early_dcx.early_error( early_dcx.early_fatal(
"option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`", "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
); );
} }
@ -2730,7 +2730,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
// Unstable values: // Unstable values:
Some(SymbolManglingVersion::Legacy) => { Some(SymbolManglingVersion::Legacy) => {
if !unstable_opts.unstable_options { if !unstable_opts.unstable_options {
early_dcx.early_error( early_dcx.early_fatal(
"`-C symbol-mangling-version=legacy` requires `-Z unstable-options`", "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
); );
} }
@ -2747,7 +2747,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
| InstrumentCoverage::ExceptUnusedFunctions | InstrumentCoverage::ExceptUnusedFunctions
| InstrumentCoverage::ExceptUnusedGenerics => { | InstrumentCoverage::ExceptUnusedGenerics => {
if !unstable_opts.unstable_options { if !unstable_opts.unstable_options {
early_dcx.early_error( early_dcx.early_fatal(
"`-C instrument-coverage=branch` and `-C instrument-coverage=except-*` \ "`-C instrument-coverage=branch` and `-C instrument-coverage=except-*` \
require `-Z unstable-options`", require `-Z unstable-options`",
); );
@ -2757,7 +2757,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
if cg.instrument_coverage != InstrumentCoverage::Off { if cg.instrument_coverage != InstrumentCoverage::Off {
if cg.profile_generate.enabled() || cg.profile_use.is_some() { if cg.profile_generate.enabled() || cg.profile_use.is_some() {
early_dcx.early_error( early_dcx.early_fatal(
"option `-C instrument-coverage` is not compatible with either `-C profile-use` \ "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
or `-C profile-generate`", or `-C profile-generate`",
); );
@ -2787,7 +2787,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
match cg.lto { match cg.lto {
LtoCli::No | LtoCli::Unspecified => {} LtoCli::No | LtoCli::Unspecified => {}
LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => { LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
early_dcx.early_error("options `-C embed-bitcode=no` and `-C lto` are incompatible") early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
} }
} }
} }
@ -2799,7 +2799,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let uses_unstable_self_contained_option = let uses_unstable_self_contained_option =
cg.link_self_contained.are_unstable_variants_set(); cg.link_self_contained.are_unstable_variants_set();
if uses_unstable_self_contained_option { if uses_unstable_self_contained_option {
early_dcx.early_error( early_dcx.early_fatal(
"only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \ "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \
the `-Z unstable-options` flag must also be passed to use the unstable values", the `-Z unstable-options` flag must also be passed to use the unstable values",
); );
@ -2807,7 +2807,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
if let Some(flavor) = cg.linker_flavor { if let Some(flavor) = cg.linker_flavor {
if flavor.is_unstable() { if flavor.is_unstable() {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"the linker flavor `{}` is unstable, the `-Z unstable-options` \ "the linker flavor `{}` is unstable, the `-Z unstable-options` \
flag must also be passed to use the unstable values", flag must also be passed to use the unstable values",
flavor.desc() flavor.desc()
@ -2824,7 +2824,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
.map(|c| c.as_str().unwrap()) .map(|c| c.as_str().unwrap())
.intersperse(", ") .intersperse(", ")
.collect(); .collect();
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"some `-C link-self-contained` components were both enabled and disabled: {names}" "some `-C link-self-contained` components were both enabled and disabled: {names}"
)); ));
} }
@ -2871,7 +2871,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
// query-dep-graph is required if dump-dep-graph is given #106736 // query-dep-graph is required if dump-dep-graph is given #106736
if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph { if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
early_dcx.early_error("can't dump dependency graph without `-Z query-dep-graph`"); early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
} }
let logical_env = parse_logical_env(early_dcx, matches); let logical_env = parse_logical_env(early_dcx, matches);
@ -2905,7 +2905,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
}; };
let working_dir = std::env::current_dir().unwrap_or_else(|e| { let working_dir = std::env::current_dir().unwrap_or_else(|e| {
early_dcx.early_error(format!("Current directory is invalid: {e}")); early_dcx.early_fatal(format!("Current directory is invalid: {e}"));
}); });
let remap = file_path_mapping(remap_path_prefix.clone(), &unstable_opts); let remap = file_path_mapping(remap_path_prefix.clone(), &unstable_opts);
@ -2980,7 +2980,7 @@ fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> O
"mir" => Mir, "mir" => Mir,
"stable-mir" => StableMir, "stable-mir" => StableMir,
"mir-cfg" => MirCFG, "mir-cfg" => MirCFG,
name => early_dcx.early_error(format!( name => early_dcx.early_fatal(format!(
"argument to `unpretty` must be one of `normal`, `identified`, \ "argument to `unpretty` must be one of `normal`, `identified`, \
`expanded`, `expanded,identified`, `expanded,hygiene`, \ `expanded`, `expanded,identified`, `expanded,hygiene`, \
`ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \ `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
@ -3060,7 +3060,7 @@ pub mod nightly_options {
continue; continue;
} }
if opt.name != "Z" && !has_z_unstable_option { if opt.name != "Z" && !has_z_unstable_option {
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"the `-Z unstable-options` flag must also be passed to enable \ "the `-Z unstable-options` flag must also be passed to enable \
the flag `{}`", the flag `{}`",
opt.name opt.name
@ -3076,7 +3076,7 @@ pub mod nightly_options {
"the option `{}` is only accepted on the nightly compiler", "the option `{}` is only accepted on the nightly compiler",
opt.name opt.name
); );
let _ = early_dcx.early_error_no_abort(msg); let _ = early_dcx.early_err(msg);
} }
OptionStability::Stable => {} OptionStability::Stable => {}
} }
@ -3086,7 +3086,7 @@ pub mod nightly_options {
.early_help("consider switching to a nightly toolchain: `rustup default nightly`"); .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>"); early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>"); early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
early_dcx.early_error(format!( early_dcx.early_fatal(format!(
"{} nightly option{} were parsed", "{} nightly option{} were parsed",
nightly_options_on_stable, nightly_options_on_stable,
if nightly_options_on_stable > 1 { "s" } else { "" } if nightly_options_on_stable > 1 { "s" } else { "" }

View file

@ -4,8 +4,7 @@ use crate::parse::ParseSess;
use rustc_ast::token; use rustc_ast::token;
use rustc_ast::util::literal::LitError; use rustc_ast::util::literal::LitError;
use rustc_errors::{ use rustc_errors::{
error_code, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, error_code, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
Level, MultiSpan,
}; };
use rustc_macros::Diagnostic; use rustc_macros::Diagnostic;
use rustc_span::{BytePos, Span, Symbol}; use rustc_span::{BytePos, Span, Symbol};
@ -18,11 +17,7 @@ pub struct FeatureGateError {
impl<'a> IntoDiagnostic<'a> for FeatureGateError { impl<'a> IntoDiagnostic<'a> for FeatureGateError {
#[track_caller] #[track_caller]
fn into_diagnostic( fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> {
self,
dcx: &'a DiagCtxt,
level: Level,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut diag = DiagnosticBuilder::new(dcx, level, self.explain); let mut diag = DiagnosticBuilder::new(dcx, level, self.explain);
diag.set_span(self.span); diag.set_span(self.span);
diag.code(error_code!(E0658)); diag.code(error_code!(E0658));

View file

@ -337,12 +337,12 @@ fn build_options<O: Default>(
Some((_, setter, type_desc, _)) => { Some((_, setter, type_desc, _)) => {
if !setter(&mut op, value) { if !setter(&mut op, value) {
match value { match value {
None => early_dcx.early_error( None => early_dcx.early_fatal(
format!( format!(
"{outputname} option `{key}` requires {type_desc} ({prefix} {key}=<value>)" "{outputname} option `{key}` requires {type_desc} ({prefix} {key}=<value>)"
), ),
), ),
Some(value) => early_dcx.early_error( Some(value) => early_dcx.early_fatal(
format!( format!(
"incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected" "incorrect value `{value}` for {outputname} option `{key}` - {type_desc} was expected"
), ),
@ -350,7 +350,7 @@ fn build_options<O: Default>(
} }
} }
} }
None => early_dcx.early_error(format!("unknown {outputname} option: `{key}`")), None => early_dcx.early_fatal(format!("unknown {outputname} option: `{key}`")),
} }
} }
return op; return op;

View file

@ -83,7 +83,7 @@ pub fn feature_err(
feature: Symbol, feature: Symbol,
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
explain: impl Into<DiagnosticMessage>, explain: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
feature_err_issue(sess, feature, span, GateIssue::Language, explain) feature_err_issue(sess, feature, span, GateIssue::Language, explain)
} }
@ -98,7 +98,7 @@ pub fn feature_err_issue(
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
issue: GateIssue, issue: GateIssue,
explain: impl Into<DiagnosticMessage>, explain: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
let span = span.into(); let span = span.into();
// Cancel an earlier warning for this same error, if it exists. // Cancel an earlier warning for this same error, if it exists.
@ -318,10 +318,7 @@ impl ParseSess {
} }
#[track_caller] #[track_caller]
pub fn create_err<'a>( pub fn create_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> {
&'a self,
err: impl IntoDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
err.into_diagnostic(&self.dcx, Level::Error { lint: false }) err.into_diagnostic(&self.dcx, Level::Error { lint: false })
} }
@ -371,10 +368,7 @@ impl ParseSess {
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_err( pub fn struct_err(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_> {
&self,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.dcx.struct_err(msg) self.dcx.struct_err(msg)
} }

View file

@ -61,7 +61,7 @@ impl SearchPath {
(PathKind::All, path) (PathKind::All, path)
}; };
if path.is_empty() { if path.is_empty() {
early_dcx.early_error("empty search path given via `-L`"); early_dcx.early_fatal("empty search path given via `-L`");
} }
let dir = PathBuf::from(path); let dir = PathBuf::from(path);

View file

@ -321,16 +321,6 @@ impl Session {
} }
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_span_warn_with_expectation<S: Into<MultiSpan>>(
&self,
sp: S,
msg: impl Into<DiagnosticMessage>,
id: lint::LintExpectationId,
) -> DiagnosticBuilder<'_, ()> {
self.dcx().struct_span_warn_with_expectation(sp, msg, id)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_warn_with_code<S: Into<MultiSpan>>( pub fn struct_span_warn_with_code<S: Into<MultiSpan>>(
&self, &self,
sp: S, sp: S,
@ -346,24 +336,6 @@ impl Session {
} }
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_warn_with_expectation(
&self,
msg: impl Into<DiagnosticMessage>,
id: lint::LintExpectationId,
) -> DiagnosticBuilder<'_, ()> {
self.dcx().struct_warn_with_expectation(msg, id)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_span_allow<S: Into<MultiSpan>>(
&self,
sp: S,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ()> {
self.dcx().struct_span_allow(sp, msg)
}
#[rustc_lint_diagnostics]
#[track_caller]
pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> { pub fn struct_allow(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, ()> {
self.dcx().struct_allow(msg) self.dcx().struct_allow(msg)
} }
@ -382,7 +354,7 @@ impl Session {
&self, &self,
sp: S, sp: S,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
self.dcx().struct_span_err(sp, msg) self.dcx().struct_span_err(sp, msg)
} }
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
@ -392,16 +364,13 @@ impl Session {
sp: S, sp: S,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
code: DiagnosticId, code: DiagnosticId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
self.dcx().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). // FIXME: This method should be removed (every error should have an associated error code).
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
#[track_caller] #[track_caller]
pub fn struct_err( pub fn struct_err(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_> {
&self,
msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
self.parse_sess.struct_err(msg) self.parse_sess.struct_err(msg)
} }
#[track_caller] #[track_caller]
@ -410,7 +379,7 @@ impl Session {
&self, &self,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
code: DiagnosticId, code: DiagnosticId,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> { ) -> DiagnosticBuilder<'_> {
self.dcx().struct_err_with_code(msg, code) self.dcx().struct_err_with_code(msg, code)
} }
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
@ -491,10 +460,7 @@ impl Session {
self.dcx().err(msg) self.dcx().err(msg)
} }
#[track_caller] #[track_caller]
pub fn create_err<'a>( pub fn create_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> {
&'a self,
err: impl IntoDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
self.parse_sess.create_err(err) self.parse_sess.create_err(err)
} }
#[track_caller] #[track_caller]
@ -502,10 +468,10 @@ impl Session {
&'a self, &'a self,
err: impl IntoDiagnostic<'a>, err: impl IntoDiagnostic<'a>,
feature: Symbol, feature: Symbol,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> { ) -> DiagnosticBuilder<'a> {
let mut err = self.parse_sess.create_err(err); let mut err = self.parse_sess.create_err(err);
if err.code.is_none() { if err.code.is_none() {
err.code = std::option::Option::Some(error_code!(E0658)); err.code(error_code!(E0658));
} }
add_feature_diagnostics(&mut err, &self.parse_sess, feature); add_feature_diagnostics(&mut err, &self.parse_sess, feature);
err err
@ -1393,7 +1359,7 @@ pub fn build_session(
let target_cfg = config::build_target_config(&early_dcx, &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_triple = TargetTriple::from_triple(config::host_triple());
let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| { let (host, target_warnings) = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
early_dcx.early_error(format!("Error loading host specification: {e}")) early_dcx.early_fatal(format!("Error loading host specification: {e}"))
}); });
for warning in target_warnings.warning_messages() { for warning in target_warnings.warning_messages() {
early_dcx.early_warn(warning) early_dcx.early_warn(warning)
@ -1768,19 +1734,19 @@ impl EarlyDiagCtxt {
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[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"] #[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 { pub fn early_err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
self.dcx.struct_err(msg).emit() self.dcx.struct_err(msg).emit()
} }
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_error(&self, msg: impl Into<DiagnosticMessage>) -> ! { pub fn early_fatal(&self, msg: impl Into<DiagnosticMessage>) -> ! {
self.dcx.struct_fatal(msg).emit() self.dcx.struct_fatal(msg).emit()
} }
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
pub fn early_struct_error( pub fn early_struct_fatal(
&self, &self,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) -> DiagnosticBuilder<'_, FatalAbort> { ) -> DiagnosticBuilder<'_, FatalAbort> {

View file

@ -1,7 +1,7 @@
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::InferCtxt; use crate::infer::InferCtxt;
use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; use crate::traits::{Obligation, ObligationCause, ObligationCtxt};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::Node; use rustc_hir::Node;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -29,7 +29,7 @@ pub trait InferCtxtExt<'tcx> {
found_args: Vec<ArgKind>, found_args: Vec<ArgKind>,
is_closure: bool, is_closure: bool,
closure_pipe_span: Option<Span>, closure_pipe_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
/// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce` /// Checks if the type implements one of `Fn`, `FnMut`, or `FnOnce`
/// in that order, and returns the generic type corresponding to the /// in that order, and returns the generic type corresponding to the
@ -118,7 +118,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
found_args: Vec<ArgKind>, found_args: Vec<ArgKind>,
is_closure: bool, is_closure: bool,
closure_arg_span: Option<Span>, closure_arg_span: Option<Span>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let kind = if is_closure { "closure" } else { "function" }; let kind = if is_closure { "closure" } else { "function" };
let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {

View file

@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder,
ErrorGuaranteed, MultiSpan, Style, SuggestionStyle, MultiSpan, Style, SuggestionStyle,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -207,7 +207,7 @@ pub trait TypeErrCtxtExt<'tcx> {
fn point_at_returns_when_relevant( fn point_at_returns_when_relevant(
&self, &self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'tcx>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
); );
@ -220,7 +220,7 @@ pub trait TypeErrCtxtExt<'tcx> {
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>, found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
fn note_conflicting_fn_args( fn note_conflicting_fn_args(
&self, &self,
@ -234,7 +234,7 @@ pub trait TypeErrCtxtExt<'tcx> {
fn note_conflicting_closure_bounds( fn note_conflicting_closure_bounds(
&self, &self,
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'tcx>,
); );
fn suggest_fully_qualified_path( fn suggest_fully_qualified_path(
@ -1384,7 +1384,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if has_custom_message { if has_custom_message {
err.note(msg); err.note(msg);
} else { } else {
err.message = err.messages =
vec![(rustc_errors::DiagnosticMessage::from(msg), Style::NoStyle)]; vec![(rustc_errors::DiagnosticMessage::from(msg), Style::NoStyle)];
} }
let mut file = None; let mut file = None;
@ -1920,7 +1920,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn point_at_returns_when_relevant( fn point_at_returns_when_relevant(
&self, &self,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'tcx>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) { ) {
match obligation.cause.code().peel_derives() { match obligation.cause.code().peel_derives() {
@ -1961,7 +1961,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>, found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
pub(crate) fn build_fn_sig_ty<'tcx>( pub(crate) fn build_fn_sig_ty<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
@ -2187,7 +2187,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn note_conflicting_closure_bounds( fn note_conflicting_closure_bounds(
&self, &self,
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, err: &mut DiagnosticBuilder<'tcx>,
) { ) {
// First, look for an `ExprBindingObligation`, which means we can get // First, look for an `ExprBindingObligation`, which means we can get
// the unsubstituted predicate list of the called function. And check // the unsubstituted predicate list of the called function. And check

View file

@ -59,7 +59,7 @@ pub trait TypeErrCtxtExt<'tcx> {
predicate: &T, predicate: &T,
span: Span, span: Span,
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> ) -> DiagnosticBuilder<'tcx>
where where
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>; T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
@ -118,7 +118,7 @@ pub trait TypeErrCtxtExt<'tcx> {
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
} }
impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
@ -263,7 +263,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
predicate: &T, predicate: &T,
span: Span, span: Span,
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> ) -> DiagnosticBuilder<'tcx>
where where
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
{ {
@ -1226,7 +1226,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let span = obligation.cause.span; let span = obligation.cause.span;
let mut diag = match ty.kind() { let mut diag = match ty.kind() {
@ -1491,7 +1491,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
closure_def_id: DefId, closure_def_id: DefId,
found_kind: ty::ClosureKind, found_kind: ty::ClosureKind,
kind: ty::ClosureKind, kind: ty::ClosureKind,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
fn report_type_parameter_mismatch_cyclic_type_error( fn report_type_parameter_mismatch_cyclic_type_error(
&self, &self,
@ -1499,13 +1499,13 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
fn report_opaque_type_auto_trait_leakage( fn report_opaque_type_auto_trait_leakage(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
def_id: DefId, def_id: DefId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; ) -> DiagnosticBuilder<'tcx>;
fn report_type_parameter_mismatch_error( fn report_type_parameter_mismatch_error(
&self, &self,
@ -1513,13 +1513,13 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
span: Span, span: Span,
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; ) -> Option<DiagnosticBuilder<'tcx>>;
fn report_not_const_evaluatable_error( fn report_not_const_evaluatable_error(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
span: Span, span: Span,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; ) -> Option<DiagnosticBuilder<'tcx>>;
} }
impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
@ -3305,7 +3305,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
closure_def_id: DefId, closure_def_id: DefId,
found_kind: ty::ClosureKind, found_kind: ty::ClosureKind,
kind: ty::ClosureKind, kind: ty::ClosureKind,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let closure_span = self.tcx.def_span(closure_def_id); let closure_span = self.tcx.def_span(closure_def_id);
let mut err = ClosureKindMismatch { let mut err = ClosureKindMismatch {
@ -3347,7 +3347,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let self_ty = found_trait_ref.self_ty().skip_binder(); let self_ty = found_trait_ref.self_ty().skip_binder();
let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() {
( (
@ -3367,7 +3367,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
def_id: DefId, def_id: DefId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { ) -> DiagnosticBuilder<'tcx> {
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) { let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
"opaque type".to_string() "opaque type".to_string()
@ -3409,7 +3409,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
span: Span, span: Span,
found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref);
let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref);
@ -3515,7 +3515,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
span: Span, span: Span,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx>> {
if !self.tcx.features().generic_const_exprs { if !self.tcx.features().generic_const_exprs {
let mut err = self let mut err = self
.tcx .tcx

View file

@ -403,7 +403,7 @@ impl Options {
&& !matches.opt_present("show-coverage") && !matches.opt_present("show-coverage")
&& !nightly_options::is_unstable_enabled(matches) && !nightly_options::is_unstable_enabled(matches)
{ {
early_dcx.early_error( early_dcx.early_fatal(
"the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)", "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
); );
} }

View file

@ -194,10 +194,10 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) {
Ok("always") => true, Ok("always") => true,
Ok("never") => false, Ok("never") => false,
Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(), Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
Ok(value) => early_dcx.early_error(format!( Ok(value) => early_dcx.early_fatal(format!(
"invalid log color value '{value}': expected one of always, never, or auto", "invalid log color value '{value}': expected one of always, never, or auto",
)), )),
Err(VarError::NotUnicode(value)) => early_dcx.early_error(format!( Err(VarError::NotUnicode(value)) => early_dcx.early_fatal(format!(
"invalid log color value '{}': expected one of always, never, or auto", "invalid log color value '{}': expected one of always, never, or auto",
value.to_string_lossy() value.to_string_lossy()
)), )),
@ -727,7 +727,7 @@ fn main_args(
let matches = match options.parse(&args) { let matches = match options.parse(&args) {
Ok(m) => m, Ok(m) => m,
Err(err) => { Err(err) => {
early_dcx.early_error(err.to_string()); early_dcx.early_fatal(err.to_string());
} }
}; };

View file

@ -161,7 +161,7 @@ impl Emitter for BufferEmitter {
let fluent_args = to_fluent_args(diag.args()); let fluent_args = to_fluent_args(diag.args());
let translated_main_message = self let translated_main_message = self
.translate_message(&diag.message[0].0, &fluent_args) .translate_message(&diag.messages[0].0, &fluent_args)
.unwrap_or_else(|e| panic!("{e}")); .unwrap_or_else(|e| panic!("{e}"));
buffer.messages.push(format!("error from rustc: {translated_main_message}")); buffer.messages.push(format!("error from rustc: {translated_main_message}"));

View file

@ -3,7 +3,7 @@ use std::num::NonZeroU64;
use log::trace; use log::trace;
use rustc_errors::DiagnosticMessage; use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Level};
use rustc_span::{SpanData, Symbol, DUMMY_SP}; use rustc_span::{SpanData, Symbol, DUMMY_SP};
use rustc_target::abi::{Align, Size}; use rustc_target::abi::{Align, Size};
@ -453,11 +453,13 @@ pub fn report_msg<'tcx>(
) { ) {
let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span); let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span);
let sess = machine.tcx.sess; let sess = machine.tcx.sess;
let mut err = match diag_level { let level = match diag_level {
DiagLevel::Error => sess.struct_span_err(span, title).forget_guarantee(), DiagLevel::Error => Level::Error { lint: false },
DiagLevel::Warning => sess.struct_span_warn(span, title), DiagLevel::Warning => Level::Warning(None),
DiagLevel::Note => sess.dcx().struct_span_note(span, title), DiagLevel::Note => Level::Note,
}; };
let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), level, title);
err.set_span(span);
// Show main message. // Show main message.
if span != DUMMY_SP { if span != DUMMY_SP {

View file

@ -370,7 +370,7 @@ mod tests {
fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic { fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> Diagnostic {
let mut diag = Diagnostic::new(level, ""); let mut diag = Diagnostic::new(level, "");
diag.message.clear(); diag.messages.clear();
if let Some(span) = span { if let Some(span) = span {
diag.span = span; diag.span = span;
} }