Skip to content

Commit

Permalink
Auto merge of rust-lang#118527 - Nadrieril:never_patterns_parse, r=co…
Browse files Browse the repository at this point in the history
…mpiler-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`
  • Loading branch information
bors committed Dec 8, 2023
2 parents 5f191ce + 7ffe1ff commit f39d18b
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 3 deletions.
4 changes: 3 additions & 1 deletion clippy_lints/src/non_expressive_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,9 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {

self.apply(|this| {
SimilarNamesNameVisitor(this).visit_pat(&arm.pat);
this.apply(|this| walk_expr(this, &arm.body));
if let Some(body) = &arm.body {
this.apply(|this| walk_expr(this, body));
}
});

self.check_single_char_names();
Expand Down
4 changes: 3 additions & 1 deletion clippy_lints/src/redundant_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ impl<'ast> Visitor<'ast> for BreakVisitor {
fn visit_expr(&mut self, expr: &'ast Expr) {
self.is_break = match expr.kind {
ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) => true,
ExprKind::Match(_, ref arms) => arms.iter().all(|arm| self.check_expr(&arm.body)),
ExprKind::Match(_, ref arms) => arms.iter().all(|arm|
arm.body.is_none() || arm.body.as_deref().is_some_and(|body| self.check_expr(body))
),
ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),
ExprKind::If(_, _, None)
// ignore loops for simplicity
Expand Down
2 changes: 1 addition & 1 deletion clippy_utils/src/ast_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
pub fn eq_arm(l: &Arm, r: &Arm) -> bool {
l.is_placeholder == r.is_placeholder
&& eq_pat(&l.pat, &r.pat)
&& eq_expr(&l.body, &r.body)
&& eq_expr_opt(&l.body, &r.body)
&& eq_expr_opt(&l.guard, &r.guard)
&& over(&l.attrs, &r.attrs, eq_attr)
}
Expand Down

0 comments on commit f39d18b

Please sign in to comment.