about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-08 17:08:52 +0000
committerbors <bors@rust-lang.org>2023-12-08 17:08:52 +0000
commit77bb46dedbebdb4dd97c3f61cca4becedfc49066 (patch)
treeeb3ec527779d374cfce34e7ed1e06b9db0028b97 /src
parentf114bb42ec9220a488e9cab120dadf2587196fec (diff)
parenta445ba8a9d1016895e06dfff532ee1b722c13c37 (diff)
downloadrust-77bb46dedbebdb4dd97c3f61cca4becedfc49066.tar.gz
rust-77bb46dedbebdb4dd97c3f61cca4becedfc49066.zip
Auto merge of #118527 - Nadrieril:never_patterns_parse, r=compiler-errors
never_patterns: Parse match arms with no body

Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
    None => { foo(); }
    Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).

~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit

r? `@compiler-errors`
Diffstat (limited to 'src')
-rw-r--r--src/matches.rs8
-rw-r--r--src/spanned.rs7
2 files changed, 10 insertions, 5 deletions
diff --git a/src/matches.rs b/src/matches.rs
index 95b0ed16db8..ef509b56837 100644
--- a/src/matches.rs
+++ b/src/matches.rs
@@ -223,7 +223,7 @@ fn rewrite_match_arm(
 ) -> Option<String> {
     let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
         if contains_skip(&arm.attrs) {
-            let (_, body) = flatten_arm_body(context, &arm.body, None);
+            let (_, body) = flatten_arm_body(context, arm.body.as_deref()?, None);
             // `arm.span()` does not include trailing comma, add it manually.
             return Some(format!(
                 "{}{}",
@@ -246,7 +246,7 @@ fn rewrite_match_arm(
     };
 
     // Patterns
-    let pat_shape = match &arm.body.kind {
+    let pat_shape = match &arm.body.as_ref()?.kind {
         ast::ExprKind::Block(_, Some(label)) => {
             // Some block with a label ` => 'label: {`
             // 7 = ` => : {`
@@ -280,10 +280,10 @@ fn rewrite_match_arm(
         false,
     )?;
 
-    let arrow_span = mk_sp(arm.pat.span.hi(), arm.body.span().lo());
+    let arrow_span = mk_sp(arm.pat.span.hi(), arm.body.as_ref()?.span().lo());
     rewrite_match_body(
         context,
-        &arm.body,
+        arm.body.as_ref()?,
         &lhs_str,
         shape,
         guard_str.contains('\n'),
diff --git a/src/spanned.rs b/src/spanned.rs
index 2136cfeae1a..5960b144499 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -97,7 +97,12 @@ impl Spanned for ast::Arm {
         } else {
             self.attrs[0].span.lo()
         };
-        span_with_attrs_lo_hi!(self, lo, self.body.span.hi())
+        let hi = if let Some(body) = &self.body {
+            body.span.hi()
+        } else {
+            self.pat.span.hi()
+        };
+        span_with_attrs_lo_hi!(self, lo, hi)
     }
 }