Overhaul how stashed diagnostics work, again.
Stashed errors used to be counted as errors, but could then be cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed that, closing the soundness hole. But it introduced other difficulties because you sometimes have to account for pending stashed errors when making decisions about whether errors have occured/will occur and it's easy to overlook these. This commit aims for a middle ground. - Stashed errors (not warnings) are counted immediately as emitted errors, avoiding the possibility of forgetting to consider them. - The ability to cancel (or downgrade) stashed errors is eliminated, by disallowing the use of `steal_diagnostic` with errors, and introducing the more restrictive methods `try_steal_{modify,replace}_and_emit_err` that can be used instead. Other things: - `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both return `Option<ErrorGuaranteed>`, which enables the removal of two `delayed_bug` calls and one `Ty::new_error_with_message` call. This is possible because we store error guarantees in `DiagCtxt::stashed_diagnostics`. - Storing the guarantees also saves us having to maintain a counter. - Calls to the `stashed_err_count` method are no longer necessary alongside calls to `has_errors`, which is a nice simplification, and eliminates two more `span_delayed_bug` calls and one FIXME comment. - Tests are added for three of the four fixed PRs mentioned below. - `issue-121108.rs`'s output improved slightly, omitting a non-useful error message. Fixes #121451. Fixes #121477. Fixes #121504. Fixes #121508.
This commit is contained in:
parent
ec25d6db53
commit
260ae70140
29 changed files with 406 additions and 295 deletions
|
@ -889,7 +889,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id) => self.report_opaque_type_auto_trait_leakage(
|
||||
SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id) => return self.report_opaque_type_auto_trait_leakage(
|
||||
&obligation,
|
||||
def_id,
|
||||
),
|
||||
|
@ -2252,8 +2252,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
ErrorCode::E0282,
|
||||
false,
|
||||
);
|
||||
err.stash(span, StashKey::MaybeForgetReturn);
|
||||
return self.dcx().delayed_bug("stashed error never reported");
|
||||
return err.stash(span, StashKey::MaybeForgetReturn).unwrap();
|
||||
}
|
||||
Some(e) => return e,
|
||||
}
|
||||
|
@ -2766,7 +2765,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
self.suggest_unsized_bound_if_applicable(err, obligation);
|
||||
if let Some(span) = err.span.primary_span()
|
||||
&& let Some(mut diag) =
|
||||
self.tcx.dcx().steal_diagnostic(span, StashKey::AssociatedTypeSuggestion)
|
||||
self.tcx.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
|
||||
&& let Ok(ref mut s1) = err.suggestions
|
||||
&& let Ok(ref mut s2) = diag.suggestions
|
||||
{
|
||||
|
@ -3291,7 +3290,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> Diag<'tcx> {
|
||||
) -> ErrorGuaranteed {
|
||||
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
|
||||
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
|
||||
"opaque type".to_string()
|
||||
|
@ -3318,12 +3317,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(diag) = self.dcx().steal_diagnostic(self.tcx.def_span(def_id), StashKey::Cycle)
|
||||
{
|
||||
diag.cancel();
|
||||
}
|
||||
|
||||
err
|
||||
self.note_obligation_cause(&mut err, &obligation);
|
||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
||||
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
|
||||
}
|
||||
|
||||
fn report_signature_mismatch_error(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue