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
|
@ -87,7 +87,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
reported_signature_mismatch: self.reported_signature_mismatch.clone(),
|
||||
tainted_by_errors: self.tainted_by_errors.clone(),
|
||||
err_count_on_creation: self.err_count_on_creation,
|
||||
stashed_err_count_on_creation: self.stashed_err_count_on_creation,
|
||||
universe: self.universe.clone(),
|
||||
intercrate,
|
||||
next_trait_solver: self.next_trait_solver,
|
||||
|
|
|
@ -306,12 +306,6 @@ pub struct InferCtxt<'tcx> {
|
|||
// FIXME(matthewjasper) Merge into `tainted_by_errors`
|
||||
err_count_on_creation: usize,
|
||||
|
||||
/// Track how many errors were stashed when this infcx is created.
|
||||
/// Used for the same purpose as `err_count_on_creation`, even
|
||||
/// though it's weaker because the count can go up and down.
|
||||
// FIXME(matthewjasper) Merge into `tainted_by_errors`
|
||||
stashed_err_count_on_creation: usize,
|
||||
|
||||
/// What is the innermost universe we have created? Starts out as
|
||||
/// `UniverseIndex::root()` but grows from there as we enter
|
||||
/// universal quantifiers.
|
||||
|
@ -717,7 +711,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
reported_signature_mismatch: Default::default(),
|
||||
tainted_by_errors: Cell::new(None),
|
||||
err_count_on_creation: tcx.dcx().err_count_excluding_lint_errs(),
|
||||
stashed_err_count_on_creation: tcx.dcx().stashed_err_count(),
|
||||
universe: Cell::new(ty::UniverseIndex::ROOT),
|
||||
intercrate,
|
||||
next_trait_solver,
|
||||
|
@ -1274,14 +1267,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
let guar = self.dcx().has_errors().unwrap();
|
||||
self.set_tainted_by_errors(guar);
|
||||
Some(guar)
|
||||
} else if self.dcx().stashed_err_count() > self.stashed_err_count_on_creation {
|
||||
// Errors stashed since this infcx was made. Not entirely reliable
|
||||
// because the count of stashed errors can go down. But without
|
||||
// this case we get a moderate number of uninteresting and
|
||||
// extraneous "type annotations needed" errors.
|
||||
let guar = self.dcx().delayed_bug("tainted_by_errors: stashed bug awaiting emission");
|
||||
self.set_tainted_by_errors(guar);
|
||||
Some(guar)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue