about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2023-11-27 01:53:05 +0100
committerNadrieril <nadrieril+git@gmail.com>2023-12-03 12:25:46 +0100
commita2dcb3a6d9aead3964b3b1cdf814dc7eb9c5d8ed (patch)
tree6dface89197039eb8fddb71508a4522ac0892eca /compiler/rustc_ast_lowering/src
parent0bfebc6105ea882d7048057718b2e34d09a5d17e (diff)
downloadrust-a2dcb3a6d9aead3964b3b1cdf814dc7eb9c5d8ed.tar.gz
rust-a2dcb3a6d9aead3964b3b1cdf814dc7eb9c5d8ed.zip
Disallow an arm without a body (except for never patterns)
Parsing now accepts a match arm without a body, so we must make sure to
only accept that if the pattern is a never pattern.
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs13
2 files changed, 19 insertions, 3 deletions
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 6e1a9eff500..1bcf4a07eb0 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -340,6 +340,15 @@ pub struct NotSupportedForLifetimeBinderAsyncClosure {
     pub span: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(ast_lowering_match_arm_with_no_body)]
+pub struct MatchArmWithNoBody {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
+    pub suggestion: Span,
+}
+
 #[derive(Diagnostic, Clone, Copy)]
 #[diag(ast_lowering_arbitrary_expression_in_pattern)]
 pub struct ArbitraryExpressionInPattern {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index b688950f5a3..4a32fa7f929 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1,7 +1,7 @@
 use super::errors::{
     AsyncCoroutinesNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
     BaseExpressionDoubleDot, ClosureCannotBeStatic, CoroutineTooManyParameters,
-    FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd,
+    FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd, MatchArmWithNoBody,
     NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign,
 };
 use super::ResolverAstLoweringExt;
@@ -565,14 +565,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         });
         let hir_id = self.next_id();
+        let span = self.lower_span(arm.span);
         self.lower_attrs(hir_id, &arm.attrs);
         let body = if let Some(body) = &arm.body {
+            // FIXME(never_patterns): Disallow never pattern with a body or guard
             self.lower_expr(body)
         } else {
+            if !pat.is_never_pattern() {
+                self.tcx
+                    .sess
+                    .emit_err(MatchArmWithNoBody { span, suggestion: span.shrink_to_hi() });
+            }
+
             // An arm without a body, meant for never patterns.
             // We add a fake `loop {}` arm body so that it typecks to `!`.
             // FIXME(never_patterns): Desugar into a call to `unreachable_unchecked`.
-            let span = pat.span;
             let block = self.arena.alloc(hir::Block {
                 stmts: &[],
                 expr: None,
@@ -587,7 +594,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 span,
             })
         };
-        hir::Arm { hir_id, pat, guard, body, span: self.lower_span(arm.span) }
+        hir::Arm { hir_id, pat, guard, body, span }
     }
 
     /// Lower an `async` construct to a coroutine that implements `Future`.