about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-03-01 05:49:56 +0100
committerGitHub <noreply@github.com>2025-03-01 05:49:56 +0100
commit472bc0ee257ab6f387e5d9b9dd2a718372fa0c3a (patch)
tree19efe26c3408dc914deb1069d5d130b001ab5abe
parentecfb7d281159fe407e93ee33ca67825a8c3306a7 (diff)
parentd504f70ec9e56a49337173d384061d0b1cdd15e8 (diff)
downloadrust-472bc0ee257ab6f387e5d9b9dd2a718372fa0c3a.tar.gz
rust-472bc0ee257ab6f387e5d9b9dd2a718372fa0c3a.zip
Rollup merge of #137742 - mu001999-contrib:fix-137708, r=compiler-errors
unconditionally lower match arm even if it's unneeded for never pattern in match

fixes #137708

Lowering arm body is skipped when lowering match arm with never pattern, but we may need the HirId for DefId in the body in later passes. And then we got the ICE `No HirId for DefId`.

Fixes this by lowering the arm body even if it's unneeded for never pattern in match, so that we can generate HirId and use it then.

r? `@compiler-errors`
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs7
-rw-r--r--tests/ui/never_type/unused_trait_in_never_pattern_body.rs12
-rw-r--r--tests/ui/never_type/unused_trait_in_never_pattern_body.stderr36
3 files changed, 53 insertions, 2 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index efbd1711daa..9c3db7abc1c 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -671,10 +671,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let span = self.lower_span(arm.span);
         self.lower_attrs(hir_id, &arm.attrs, arm.span);
         let is_never_pattern = pat.is_never_pattern();
-        let body = if let Some(body) = &arm.body
+        // We need to lower the body even if it's unneeded for never pattern in match,
+        // ensure that we can get HirId for DefId if need (issue #137708).
+        let body = arm.body.as_ref().map(|x| self.lower_expr(x));
+        let body = if let Some(body) = body
             && !is_never_pattern
         {
-            self.lower_expr(body)
+            body
         } else {
             // Either `body.is_none()` or `is_never_pattern` here.
             if !is_never_pattern {
diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.rs b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs
new file mode 100644
index 00000000000..8179c94b72b
--- /dev/null
+++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.rs
@@ -0,0 +1,12 @@
+fn a() {
+    match 0 {
+        ! => || { //~ ERROR `!` patterns are experimental
+        //~^ ERROR a never pattern is always unreachable
+        //~^^ ERROR mismatched types
+            use std::ops::Add;
+            0.add(1)
+        },
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr
new file mode 100644
index 00000000000..18ca9f12b7e
--- /dev/null
+++ b/tests/ui/never_type/unused_trait_in_never_pattern_body.stderr
@@ -0,0 +1,36 @@
+error[E0658]: `!` patterns are experimental
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:9
+   |
+LL |         ! => || {
+   |         ^
+   |
+   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
+   = help: add `#![feature(never_patterns)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: a never pattern is always unreachable
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:14
+   |
+LL |           ! => || {
+   |  ______________^
+LL | |
+LL | |
+LL | |             use std::ops::Add;
+LL | |             0.add(1)
+LL | |         },
+   | |         ^
+   | |         |
+   | |_________this will never be executed
+   |           help: remove this expression
+
+error: mismatched types
+  --> $DIR/unused_trait_in_never_pattern_body.rs:3:9
+   |
+LL |         ! => || {
+   |         ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `i32`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.