Skip to content

Commit 34315bc

Browse files
committed
Avoid a span_delayed_bug in TypeErrCtxt::report_region_errors.
By returning error guarantees from a few functions it relies on.
1 parent 5996f79 commit 34315bc

File tree

2 files changed

+96
-90
lines changed
  • compiler/rustc_infer/src/infer/error_reporting

2 files changed

+96
-90
lines changed

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

+91-88
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
425425
generic_param_scope: LocalDefId,
426426
errors: &[RegionResolutionError<'tcx>],
427427
) -> ErrorGuaranteed {
428+
assert!(!errors.is_empty());
429+
428430
if let Some(guaranteed) = self.infcx.tainted_by_errors() {
429431
return guaranteed;
430432
}
@@ -437,90 +439,96 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
437439

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

440-
for error in errors {
441-
debug!("report_region_errors: error = {:?}", error);
442-
443-
if !self.try_report_nice_region_error(&error) {
444-
match error.clone() {
445-
// These errors could indicate all manner of different
446-
// problems with many different solutions. Rather
447-
// than generate a "one size fits all" error, what we
448-
// attempt to do is go through a number of specific
449-
// scenarios and try to find the best way to present
450-
// the error. If all of these fails, we fall back to a rather
451-
// general bit of code that displays the error information
452-
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
453-
if sub.is_placeholder() || sup.is_placeholder() {
454-
self.report_placeholder_failure(origin, sub, sup).emit();
455-
} else {
456-
self.report_concrete_failure(origin, sub, sup).emit();
442+
let guars: Vec<_> = errors
443+
.iter()
444+
.map(|error| {
445+
debug!("report_region_errors: error = {:?}", error);
446+
447+
if let Some(guar) = self.try_report_nice_region_error(&error) {
448+
guar
449+
} else {
450+
match error.clone() {
451+
// These errors could indicate all manner of different
452+
// problems with many different solutions. Rather
453+
// than generate a "one size fits all" error, what we
454+
// attempt to do is go through a number of specific
455+
// scenarios and try to find the best way to present
456+
// the error. If all of these fails, we fall back to a rather
457+
// general bit of code that displays the error information
458+
RegionResolutionError::ConcreteFailure(origin, sub, sup) => {
459+
if sub.is_placeholder() || sup.is_placeholder() {
460+
self.report_placeholder_failure(origin, sub, sup).emit()
461+
} else {
462+
self.report_concrete_failure(origin, sub, sup).emit()
463+
}
457464
}
458-
}
459465

460-
RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => {
461-
self.report_generic_bound_failure(
462-
generic_param_scope,
463-
origin.span(),
464-
Some(origin),
465-
param_ty,
466-
sub,
467-
);
468-
}
466+
RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self
467+
.report_generic_bound_failure(
468+
generic_param_scope,
469+
origin.span(),
470+
Some(origin),
471+
param_ty,
472+
sub,
473+
),
469474

470-
RegionResolutionError::SubSupConflict(
471-
_,
472-
var_origin,
473-
sub_origin,
474-
sub_r,
475-
sup_origin,
476-
sup_r,
477-
_,
478-
) => {
479-
if sub_r.is_placeholder() {
480-
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit();
481-
} else if sup_r.is_placeholder() {
482-
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
483-
} else {
484-
self.report_sub_sup_conflict(
485-
var_origin, sub_origin, sub_r, sup_origin, sup_r,
486-
);
475+
RegionResolutionError::SubSupConflict(
476+
_,
477+
var_origin,
478+
sub_origin,
479+
sub_r,
480+
sup_origin,
481+
sup_r,
482+
_,
483+
) => {
484+
if sub_r.is_placeholder() {
485+
self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit()
486+
} else if sup_r.is_placeholder() {
487+
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
488+
} else {
489+
self.report_sub_sup_conflict(
490+
var_origin, sub_origin, sub_r, sup_origin, sup_r,
491+
)
492+
}
487493
}
488-
}
489494

490-
RegionResolutionError::UpperBoundUniverseConflict(
491-
_,
492-
_,
493-
_,
494-
sup_origin,
495-
sup_r,
496-
) => {
497-
assert!(sup_r.is_placeholder());
498-
499-
// Make a dummy value for the "sub region" --
500-
// this is the initial value of the
501-
// placeholder. In practice, we expect more
502-
// tailored errors that don't really use this
503-
// value.
504-
let sub_r = self.tcx.lifetimes.re_erased;
505-
506-
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
507-
}
495+
RegionResolutionError::UpperBoundUniverseConflict(
496+
_,
497+
_,
498+
_,
499+
sup_origin,
500+
sup_r,
501+
) => {
502+
assert!(sup_r.is_placeholder());
503+
504+
// Make a dummy value for the "sub region" --
505+
// this is the initial value of the
506+
// placeholder. In practice, we expect more
507+
// tailored errors that don't really use this
508+
// value.
509+
let sub_r = self.tcx.lifetimes.re_erased;
510+
511+
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit()
512+
}
508513

509-
RegionResolutionError::CannotNormalize(clause, origin) => {
510-
let clause: ty::Clause<'tcx> =
511-
clause.map_bound(ty::ClauseKind::TypeOutlives).to_predicate(self.tcx);
512-
self.tcx
513-
.dcx()
514-
.struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
515-
.emit();
514+
RegionResolutionError::CannotNormalize(clause, origin) => {
515+
let clause: ty::Clause<'tcx> = clause
516+
.map_bound(ty::ClauseKind::TypeOutlives)
517+
.to_predicate(self.tcx);
518+
self.tcx
519+
.dcx()
520+
.struct_span_err(
521+
origin.span(),
522+
format!("cannot normalize `{clause}`"),
523+
)
524+
.emit()
525+
}
516526
}
517527
}
518-
}
519-
}
528+
})
529+
.collect();
520530

521-
self.tcx
522-
.dcx()
523-
.span_delayed_bug(self.tcx.def_span(generic_param_scope), "expected region errors")
531+
guars[0] // any guarantee will do, and the vec is definitely not empty
524532
}
525533

526534
// This method goes through all the errors and try to group certain types
@@ -2306,9 +2314,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23062314
origin: Option<SubregionOrigin<'tcx>>,
23072315
bound_kind: GenericKind<'tcx>,
23082316
sub: Region<'tcx>,
2309-
) {
2317+
) -> ErrorGuaranteed {
23102318
self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub)
2311-
.emit();
2319+
.emit()
23122320
}
23132321

23142322
pub fn construct_generic_bound_failure(
@@ -2559,7 +2567,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25592567
sub_region: Region<'tcx>,
25602568
sup_origin: SubregionOrigin<'tcx>,
25612569
sup_region: Region<'tcx>,
2562-
) {
2570+
) -> ErrorGuaranteed {
25632571
let mut err = self.report_inference_failure(var_origin);
25642572

25652573
note_and_explain_region(
@@ -2598,12 +2606,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
25982606
);
25992607

26002608
err.note_expected_found(&"", sup_expected, &"", sup_found);
2601-
if sub_region.is_error() | sup_region.is_error() {
2602-
err.delay_as_bug();
2609+
return if sub_region.is_error() | sup_region.is_error() {
2610+
err.delay_as_bug()
26032611
} else {
2604-
err.emit();
2605-
}
2606-
return;
2612+
err.emit()
2613+
};
26072614
}
26082615

26092616
self.note_region_origin(&mut err, &sup_origin);
@@ -2618,11 +2625,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26182625
);
26192626

26202627
self.note_region_origin(&mut err, &sub_origin);
2621-
if sub_region.is_error() | sup_region.is_error() {
2622-
err.delay_as_bug();
2623-
} else {
2624-
err.emit();
2625-
}
2628+
if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() }
26262629
}
26272630

26282631
/// 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

0 commit comments

Comments
 (0)