about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-02-26 15:21:01 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2024-02-29 11:08:27 +1100
commit81783fbf89869b33c1f18aa16fc00c062b6d97c5 (patch)
treea266573720b02261be60c590133b56e36a391690
parente3b8b5282c5b8f5ab9cb49d0a7e74717fe97bdd1 (diff)
downloadrust-81783fbf89869b33c1f18aa16fc00c062b6d97c5.tar.gz
rust-81783fbf89869b33c1f18aa16fc00c062b6d97c5.zip
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.
-rw-r--r--tests/ui/crashes/unreachable-array-or-slice.rs8
-rw-r--r--tests/ui/crashes/unreachable-array-or-slice.stderr9
2 files changed, 17 insertions, 0 deletions
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 00000000000..b56abccbd41
--- /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 00000000000..9e0d3b934b8
--- /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`.