From 81783fbf89869b33c1f18aa16fc00c062b6d97c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 26 Feb 2024 15:21:01 +1100 Subject: [PATCH] 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`, 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. --- tests/ui/crashes/unreachable-array-or-slice.rs | 8 ++++++++ tests/ui/crashes/unreachable-array-or-slice.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/crashes/unreachable-array-or-slice.rs create mode 100644 tests/ui/crashes/unreachable-array-or-slice.stderr diff --git a/tests/ui/crashes/unreachable-array-or-slice.rs b/tests/ui/crashes/unreachable-array-or-slice.rs new file mode 100644 index 0000000000000..b56abccbd4112 --- /dev/null +++ b/tests/ui/crashes/unreachable-array-or-slice.rs @@ -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] { + [..] => { } + } +} diff --git a/tests/ui/crashes/unreachable-array-or-slice.stderr b/tests/ui/crashes/unreachable-array-or-slice.stderr new file mode 100644 index 0000000000000..9e0d3b934b80f --- /dev/null +++ b/tests/ui/crashes/unreachable-array-or-slice.stderr @@ -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`.