Skip to content

Commit 9afdb8d

Browse files
committed
Auto merge of #121285 - nnethercote:delayed_bug-audit, r=lcnr
Delayed bug audit I went through all the calls to `delayed_bug` and `span_delayed_bug` and found a few places where they could be avoided. r? `@compiler-errors`
2 parents 53ed660 + a8a486c commit 9afdb8d

File tree

12 files changed

+97
-93
lines changed

12 files changed

+97
-93
lines changed

compiler/rustc_ast_lowering/src/delegation.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
103103
span: Span,
104104
) -> Result<DefId, ErrorGuaranteed> {
105105
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
106-
let sig_id = self
107-
.resolver
108-
.get_partial_res(sig_id)
109-
.map(|r| r.expect_full_res().opt_def_id())
110-
.unwrap_or(None);
111-
106+
let sig_id =
107+
self.resolver.get_partial_res(sig_id).and_then(|r| r.expect_full_res().opt_def_id());
112108
sig_id.ok_or_else(|| {
113109
self.tcx
114110
.dcx()

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Error reporting machinery for lifetime errors.
22
33
use rustc_data_structures::fx::FxIndexSet;
4-
use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
4+
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
55
use rustc_hir as hir;
66
use rustc_hir::def::Res::Def;
77
use rustc_hir::def_id::DefId;
@@ -73,7 +73,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
7373
///
7474
/// Usually we expect this to either be empty or contain a small number of items, so we can avoid
7575
/// allocation most of the time.
76-
pub(crate) struct RegionErrors<'tcx>(Vec<RegionErrorKind<'tcx>>, TyCtxt<'tcx>);
76+
pub(crate) struct RegionErrors<'tcx>(Vec<(RegionErrorKind<'tcx>, ErrorGuaranteed)>, TyCtxt<'tcx>);
7777

7878
impl<'tcx> RegionErrors<'tcx> {
7979
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
@@ -82,15 +82,18 @@ impl<'tcx> RegionErrors<'tcx> {
8282
#[track_caller]
8383
pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
8484
let val = val.into();
85-
self.1.sess.dcx().delayed_bug(format!("{val:?}"));
86-
self.0.push(val);
85+
let guar = self.1.sess.dcx().delayed_bug(format!("{val:?}"));
86+
self.0.push((val, guar));
8787
}
8888
pub fn is_empty(&self) -> bool {
8989
self.0.is_empty()
9090
}
91-
pub fn into_iter(self) -> impl Iterator<Item = RegionErrorKind<'tcx>> {
91+
pub fn into_iter(self) -> impl Iterator<Item = (RegionErrorKind<'tcx>, ErrorGuaranteed)> {
9292
self.0.into_iter()
9393
}
94+
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
95+
self.0.get(0).map(|x| x.1)
96+
}
9497
}
9598

9699
impl std::fmt::Debug for RegionErrors<'_> {
@@ -304,10 +307,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
304307
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
305308
None;
306309

307-
for nll_error in nll_errors.into_iter() {
310+
for (nll_error, _) in nll_errors.into_iter() {
308311
match nll_error {
309312
RegionErrorKind::TypeTestError { type_test } => {
310-
// Try to convert the lower-bound region into something named we can print for the user.
313+
// Try to convert the lower-bound region into something named we can print for
314+
// the user.
311315
let lower_bound_region = self.to_error_region(type_test.lower_bound);
312316

313317
let type_test_span = type_test.span;

compiler/rustc_borrowck/src/nll.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,9 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
184184
let (closure_region_requirements, nll_errors) =
185185
regioncx.solve(infcx, body, polonius_output.clone());
186186

187-
if !nll_errors.is_empty() {
187+
if let Some(guar) = nll_errors.has_errors() {
188188
// Suppress unhelpful extra errors in `infer_opaque_types`.
189-
infcx.set_tainted_by_errors(infcx.dcx().span_delayed_bug(
190-
body.span,
191-
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
192-
));
189+
infcx.set_tainted_by_errors(guar);
193190
}
194191

195192
let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -311,17 +311,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
311311
// Add implied bounds from impl header.
312312
if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) {
313313
for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) {
314-
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = self
314+
let result: Result<_, ErrorGuaranteed> = self
315315
.param_env
316316
.and(type_op::normalize::Normalize::new(ty))
317-
.fully_perform(self.infcx, span)
318-
else {
319-
// Note: this path is currently not reached in any test, so
320-
// any example that triggers this would be worth minimizing
321-
// and converting into a test.
322-
tcx.dcx().span_delayed_bug(span, format!("failed to normalize {ty:?}"));
317+
.fully_perform(self.infcx, span);
318+
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else {
323319
continue;
324320
};
321+
325322
constraints.extend(c);
326323

327324
// We currently add implied bounds from the normalized ty only.

compiler/rustc_hir_analysis/src/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
760760
let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
761761
prev_discr = Some(
762762
if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr {
763-
def.eval_explicit_discr(tcx, const_def_id)
763+
def.eval_explicit_discr(tcx, const_def_id).ok()
764764
} else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
765765
Some(discr)
766766
} else {

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+26-29
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
428428
generic_param_scope: LocalDefId,
429429
errors: &[RegionResolutionError<'tcx>],
430430
) -> ErrorGuaranteed {
431+
assert!(!errors.is_empty());
432+
431433
if let Some(guaranteed) = self.infcx.tainted_by_errors() {
432434
return guaranteed;
433435
}
@@ -440,10 +442,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
440442

441443
debug!("report_region_errors: {} errors after preprocessing", errors.len());
442444

445+
let mut guar = None;
443446
for error in errors {
444447
debug!("report_region_errors: error = {:?}", error);
445448

446-
if !self.try_report_nice_region_error(&error) {
449+
guar = Some(if let Some(guar) = self.try_report_nice_region_error(&error) {
450+
guar
451+
} else {
447452
match error.clone() {
448453
// These errors could indicate all manner of different
449454
// problems with many different solutions. Rather
@@ -454,21 +459,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
454459
// general bit of code that displays the error information
455460
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
456461
if sub.is_placeholder() || sup.is_placeholder() {
457-
self.report_placeholder_failure(origin, sub, sup).emit();
462+
self.report_placeholder_failure(origin, sub, sup).emit()
458463
} else {
459-
self.report_concrete_failure(origin, sub, sup).emit();
464+
self.report_concrete_failure(origin, sub, sup).emit()
460465
}
461466
}
462467

463-
RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
464-
self.report_generic_bound_failure(
468+
RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self
469+
.report_generic_bound_failure(
465470
generic_param_scope,
466471
origin.span(),
467472
Some(origin),
468473
param_ty,
469474
sub,
470-
);
471-
}
475+
),
472476

473477
RegionResolutionError::SubSupConflict(
474478
_,
@@ -480,13 +484,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
480484
_,
481485
) => {
482486
if sub_r.is_placeholder() {
483-
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit();
487+
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit()
484488
} else if sup_r.is_placeholder() {
485-
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
489+
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
486490
} else {
487491
self.report_sub_sup_conflict(
488492
var_origin, sub_origin, sub_r, sup_origin, sup_r,
489-
);
493+
)
490494
}
491495
}
492496

@@ -506,7 +510,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
506510
// value.
507511
let sub_r = self.tcx.lifetimes.re_erased;
508512

509-
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
513+
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
510514
}
511515

512516
RegionResolutionError::CannotNormalize(clause, origin) => {
@@ -515,15 +519,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
515519
self.tcx
516520
.dcx()
517521
.struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
518-
.emit();
522+
.emit()
519523
}
520524
}
521-
}
525+
})
522526
}
523527

524-
self.tcx
525-
.dcx()
526-
.span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors")
528+
guar.unwrap()
527529
}
528530

529531
// This method goes through all the errors and try to group certain types
@@ -2314,9 +2316,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23142316
origin: Option<SubregionOrigin<'tcx>>,
23152317
bound_kind: GenericKind<'tcx>,
23162318
sub: Region<'tcx>,
2317-
) {
2319+
) -> ErrorGuaranteed {
23182320
self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub)
2319-
.emit();
2321+
.emit()
23202322
}
23212323

23222324
pub fn construct_generic_bound_failure(
@@ -2575,7 +2577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25752577
sub_region: Region<'tcx>,
25762578
sup_origin: SubregionOrigin<'tcx>,
25772579
sup_region: Region<'tcx>,
2578-
) {
2580+
) -> ErrorGuaranteed {
25792581
let mut err = self.report_inference_failure(var_origin);
25802582

25812583
note_and_explain_region(
@@ -2614,12 +2616,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26142616
);
26152617

26162618
err.note_expected_found(&"", sup_expected, &"", sup_found);
2617-
if sub_region.is_error() | sup_region.is_error() {
2618-
err.delay_as_bug();
2619+
return if sub_region.is_error() | sup_region.is_error() {
2620+
err.delay_as_bug()
26192621
} else {
2620-
err.emit();
2621-
}
2622-
return;
2622+
err.emit()
2623+
};
26232624
}
26242625

26252626
self.note_region_origin(&mut err, &sup_origin);
@@ -2634,11 +2635,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26342635
);
26352636

26362637
self.note_region_origin(&mut err, &sub_origin);
2637-
if sub_region.is_error() | sup_region.is_error() {
2638-
err.delay_as_bug();
2639-
} else {
2640-
err.emit();
2641-
}
2638+
if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() }
26422639
}
26432640

26442641
/// Determine whether an error associated with the given span and definition

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ pub use static_impl_trait::{suggest_new_region_bound, HirTraitObjectVisitor, Tra
2121
pub use util::find_param_with_region;
2222

2323
impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> {
24-
pub fn try_report_nice_region_error(&'cx self, error: &RegionResolutionError<'tcx>) -> bool {
25-
NiceRegionError::new(self, error.clone()).try_report().is_some()
24+
pub fn try_report_nice_region_error(
25+
&'cx self,
26+
error: &RegionResolutionError<'tcx>,
27+
) -> Option<ErrorGuaranteed> {
28+
NiceRegionError::new(self, error.clone()).try_report()
2629
}
2730
}
2831

compiler/rustc_middle/src/ty/adt.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
77
use rustc_data_structures::intern::Interned;
88
use rustc_data_structures::stable_hasher::HashingControls;
99
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
10+
use rustc_errors::ErrorGuaranteed;
1011
use rustc_hir as hir;
1112
use rustc_hir::def::{CtorKind, DefKind, Res};
1213
use rustc_hir::def_id::DefId;
@@ -475,7 +476,11 @@ impl<'tcx> AdtDef<'tcx> {
475476
}
476477

477478
#[inline]
478-
pub fn eval_explicit_discr(self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
479+
pub fn eval_explicit_discr(
480+
self,
481+
tcx: TyCtxt<'tcx>,
482+
expr_did: DefId,
483+
) -> Result<Discr<'tcx>, ErrorGuaranteed> {
479484
assert!(self.is_enum());
480485
let param_env = tcx.param_env(expr_did);
481486
let repr_type = self.repr().discr_type();
@@ -484,22 +489,24 @@ impl<'tcx> AdtDef<'tcx> {
484489
let ty = repr_type.to_ty(tcx);
485490
if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
486491
trace!("discriminants: {} ({:?})", b, repr_type);
487-
Some(Discr { val: b, ty })
492+
Ok(Discr { val: b, ty })
488493
} else {
489494
info!("invalid enum discriminant: {:#?}", val);
490-
tcx.dcx().emit_err(crate::error::ConstEvalNonIntError {
495+
let guar = tcx.dcx().emit_err(crate::error::ConstEvalNonIntError {
491496
span: tcx.def_span(expr_did),
492497
});
493-
None
498+
Err(guar)
494499
}
495500
}
496501
Err(err) => {
497-
let msg = match err {
498-
ErrorHandled::Reported(..) => "enum discriminant evaluation failed",
499-
ErrorHandled::TooGeneric(..) => "enum discriminant depends on generics",
502+
let guar = match err {
503+
ErrorHandled::Reported(info, _) => info.into(),
504+
ErrorHandled::TooGeneric(..) => tcx.dcx().span_delayed_bug(
505+
tcx.def_span(expr_did),
506+
"enum discriminant depends on generics",
507+
),
500508
};
501-
tcx.dcx().span_delayed_bug(tcx.def_span(expr_did), msg);
502-
None
509+
Err(guar)
503510
}
504511
}
505512
}
@@ -516,7 +523,7 @@ impl<'tcx> AdtDef<'tcx> {
516523
self.variants().iter_enumerated().map(move |(i, v)| {
517524
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
518525
if let VariantDiscr::Explicit(expr_did) = v.discr {
519-
if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
526+
if let Ok(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
520527
discr = new_discr;
521528
}
522529
}
@@ -544,9 +551,13 @@ impl<'tcx> AdtDef<'tcx> {
544551
) -> Discr<'tcx> {
545552
assert!(self.is_enum());
546553
let (val, offset) = self.discriminant_def_for_variant(variant_index);
547-
let explicit_value = val
548-
.and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
549-
.unwrap_or_else(|| self.repr().discr_type().initial_discriminant(tcx));
554+
let explicit_value = if let Some(expr_did) = val
555+
&& let Ok(val) = self.eval_explicit_discr(tcx, expr_did)
556+
{
557+
val
558+
} else {
559+
self.repr().discr_type().initial_discriminant(tcx)
560+
};
550561
explicit_value.checked_add(tcx, offset as u128).0
551562
}
552563

compiler/rustc_parse/src/parser/expr.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -2688,23 +2688,20 @@ impl<'a> Parser<'a> {
26882688
branch_span: Span,
26892689
attrs: AttrWrapper,
26902690
) {
2691-
if attrs.is_empty() {
2692-
return;
2691+
if !attrs.is_empty()
2692+
&& let [x0 @ xn] | [x0, .., xn] = &*attrs.take_for_recovery(self.sess)
2693+
{
2694+
let attributes = x0.span.to(xn.span);
2695+
let last = xn.span;
2696+
let ctx = if is_ctx_else { "else" } else { "if" };
2697+
self.dcx().emit_err(errors::OuterAttributeNotAllowedOnIfElse {
2698+
last,
2699+
branch_span,
2700+
ctx_span,
2701+
ctx: ctx.to_string(),
2702+
attributes,
2703+
});
26932704
}
2694-
2695-
let attrs: &[ast::Attribute] = &attrs.take_for_recovery(self.sess);
2696-
let (attributes, last) = match attrs {
2697-
[] => return,
2698-
[x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span),
2699-
};
2700-
let ctx = if is_ctx_else { "else" } else { "if" };
2701-
self.dcx().emit_err(errors::OuterAttributeNotAllowedOnIfElse {
2702-
last,
2703-
branch_span,
2704-
ctx_span,
2705-
ctx: ctx.to_string(),
2706-
attributes,
2707-
});
27082705
}
27092706

27102707
fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {

0 commit comments

Comments
 (0)