about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-07 14:22:02 +0200
committerGitHub <noreply@github.com>2024-07-07 14:22:02 +0200
commit1ee6345b7b76416ca9cf4eacdb74d9590563c53f (patch)
tree7b526cf6659a4695749800c7fd2c7d86101b7b02
parentc40530d0de9ab1eca158a3113d3873e983bc1bf7 (diff)
parent9da3638c6a90748cc913a3e2e02a74eb851ec48a (diff)
Rollup merge of #127409 - gurry:127332-ice-with-expr-not-struct, r=oli-obk
Emit a wrap expr span_bug only if context is not tainted

Fixes #127332

The ICE occurs because of this `span_bug`: https://github.com/rust-lang/rust/blob/51917e2e69702e5752bce6a4f3bfd285d0f4ae39/compiler/rustc_hir_typeck/src/expr_use_visitor.rs#L732-L738
which is triggered by the fact that we're trying to use an `enum` in a `with` expression instead of a `struct`.

The issue originates in commit https://github.com/rust-lang/rust/pull/127202/commits/814bfe9335fd7c941169e0ef15ae2cffeacc78eb   from PR #127202. As per the title of that commit the ICEing code should not be reachable any more, but looks like it still is.

This PR changes the code so that the `span_bug` will be emitted only if the context is not tainted by a previous error.
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs4
-rw-r--r--tests/crashes/127332.rs9
-rw-r--r--tests/ui/typeck/ice-with-expr-not-struct-127332.rs15
-rw-r--r--tests/ui/typeck/ice-with-expr-not-struct-127332.stderr9
4 files changed, 27 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index c8ab0429ffc..193dbbbcdf4 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -734,7 +734,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 // struct; however, when EUV is run during typeck, it
                 // may not. This will generate an error earlier in typeck,
                 // so we can just ignore it.
-                span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
+                if self.cx.tainted_by_errors().is_ok() {
+                    span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
+                }
             }
         }
 
diff --git a/tests/crashes/127332.rs b/tests/crashes/127332.rs
deleted file mode 100644
index 5c14af01cec..00000000000
--- a/tests/crashes/127332.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: rust-lang/rust #127332
-
-async fn fun() {
-    enum Foo {
-        A { x: u32 },
-    }
-    let orig = Foo::A { x: 5 };
-    Foo::A { x: 6, ..orig };
-}
diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.rs b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs
new file mode 100644
index 00000000000..f3ea360e7e9
--- /dev/null
+++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs
@@ -0,0 +1,15 @@
+// Regression test for ICE #127332
+
+// Tests that we do not ICE when a with expr is
+// not a struct but something else like an enum
+
+fn main() {
+    let x = || {
+        enum Foo {
+            A { x: u32 },
+        }
+        let orig = Foo::A { x: 5 };
+        Foo::A { x: 6, ..orig };
+        //~^ ERROR functional record update syntax requires a struct
+    };
+}
diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr
new file mode 100644
index 00000000000..446f49e8639
--- /dev/null
+++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr
@@ -0,0 +1,9 @@
+error[E0436]: functional record update syntax requires a struct
+  --> $DIR/ice-with-expr-not-struct-127332.rs:12:26
+   |
+LL |         Foo::A { x: 6, ..orig };
+   |                          ^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0436`.