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`
This commit is contained in:
bors 2023-12-08 17:08:52 +00:00
commit 77bb46dedb
2 changed files with 10 additions and 5 deletions

View File

@ -223,7 +223,7 @@ fn rewrite_match_arm(
) -> Option<String> { ) -> Option<String> {
let (missing_span, attrs_str) = if !arm.attrs.is_empty() { let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
if contains_skip(&arm.attrs) { 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. // `arm.span()` does not include trailing comma, add it manually.
return Some(format!( return Some(format!(
"{}{}", "{}{}",
@ -246,7 +246,7 @@ fn rewrite_match_arm(
}; };
// Patterns // Patterns
let pat_shape = match &arm.body.kind { let pat_shape = match &arm.body.as_ref()?.kind {
ast::ExprKind::Block(_, Some(label)) => { ast::ExprKind::Block(_, Some(label)) => {
// Some block with a label ` => 'label: {` // Some block with a label ` => 'label: {`
// 7 = ` => : {` // 7 = ` => : {`
@ -280,10 +280,10 @@ fn rewrite_match_arm(
false, 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( rewrite_match_body(
context, context,
&arm.body, arm.body.as_ref()?,
&lhs_str, &lhs_str,
shape, shape,
guard_str.contains('\n'), guard_str.contains('\n'),

View File

@ -97,7 +97,12 @@ fn span(&self) -> Span {
} else { } else {
self.attrs[0].span.lo() 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)
} }
} }