Skip to content

Commit

Permalink
Overhaul how stashed diagnostics work, again.
Browse files Browse the repository at this point in the history
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. rust-lang#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 rust-lang#121451.
Fixes rust-lang#121477.
Fixes rust-lang#121504.
Fixes rust-lang#121508.
  • Loading branch information
nnethercote committed Feb 29, 2024
1 parent e3b8b52 commit 81783fb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tests/ui/crashes/unreachable-array-or-slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct Foo(isize, isize, isize, isize);

pub fn main() {
let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);
match [5, 5, 5, 5] {
[..] => { }
}
}
9 changes: 9 additions & 0 deletions tests/ui/crashes/unreachable-array-or-slice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
--> tests/ui/crashes/unreachable-array-or-slice.rs:4:9
|
LL | let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);
| ^^^^ `Self` is only available in impls, traits, and type definitions

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0433`.

0 comments on commit 81783fb

Please sign in to comment.