diff options
| author | Ross Smyth <crs2017@gmail.com> | 2024-02-17 12:43:54 -0500 |
|---|---|---|
| committer | Ross Smyth <crs2017@gmail.com> | 2024-03-06 00:35:19 -0500 |
| commit | 78b3bf98c3425d139b42a6326701573ff98b1a1f (patch) | |
| tree | 225c8c9365517efde4a2913b550f989593481c86 | |
| parent | 68a58f255ac7b7487769667fdd5fe2536f952c15 (diff) | |
| download | rust-78b3bf98c3425d139b42a6326701573ff98b1a1f.tar.gz rust-78b3bf98c3425d139b42a6326701573ff98b1a1f.zip | |
Add MatchKind member to the Match expr for pretty printing & fmt
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/assert/context.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/debug.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/build.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/unused.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 18 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/redundant_else.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs | 2 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_utils/src/ast_utils.rs | 2 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/expr.rs | 8 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/matches.rs | 4 | ||||
| -rw-r--r-- | tests/pretty/postfix-match.rs | 21 |
17 files changed, 76 insertions, 33 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 13b1a589d9b..6ffb3d65abc 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1436,7 +1436,7 @@ pub enum ExprKind { /// `'label: loop { block }` Loop(P<Block>, Option<Label>, Span), /// A `match` block. - Match(P<Expr>, ThinVec<Arm>), + Match(P<Expr>, ThinVec<Arm>, MatchKind), /// A closure (e.g., `move |a, b, c| a + b + c`). Closure(Box<Closure>), /// A block (`'label: { ... }`). @@ -1761,6 +1761,15 @@ pub enum StrStyle { Raw(u8), } +/// The kind of match expression +#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)] +pub enum MatchKind { + /// match expr { ... } + Prefix, + /// expr.match { ... } + Postfix, +} + /// A literal in a meta item. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItemLit { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index bbbb34f7f2f..f9b519b3079 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1423,7 +1423,7 @@ pub fn noop_visit_expr<T: MutVisitor>( visit_opt(label, |label| vis.visit_label(label)); vis.visit_span(span); } - ExprKind::Match(expr, arms) => { + ExprKind::Match(expr, arms, _kind) => { vis.visit_expr(expr); arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9efb87e53cd..64c2cbd297d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -919,7 +919,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V visit_opt!(visitor, visit_label, opt_label); try_visit!(visitor.visit_block(block)); } - ExprKind::Match(subexpression, arms) => { + ExprKind::Match(subexpression, arms, _kind) => { try_visit!(visitor.visit_expr(subexpression)); walk_list!(visitor, visit_arm, arms); } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 85b599902b9..b4515ea3a9b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -181,7 +181,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }), ExprKind::TryBlock(body) => self.lower_expr_try_block(body), - ExprKind::Match(expr, arms) => hir::ExprKind::Match( + ExprKind::Match(expr, arms, _) => hir::ExprKind::Match( self.lower_expr(expr), self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))), hir::MatchSource::Normal, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 433ef03b6e5..8bd8b6ac144 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -1,6 +1,6 @@ use crate::pp::Breaks::Inconsistent; use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; -use ast::ForLoopKind; +use ast::{ForLoopKind, MatchKind}; use itertools::{Itertools, Position}; use rustc_ast::ptr::P; use rustc_ast::token; @@ -589,12 +589,22 @@ impl<'a> State<'a> { self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Match(expr, arms) => { + ast::ExprKind::Match(expr, arms, match_kind) => { self.cbox(0); self.ibox(0); - self.word_nbsp("match"); - self.print_expr_as_cond(expr); - self.space(); + + match match_kind { + MatchKind::Prefix => { + self.word_nbsp("match"); + self.print_expr_as_cond(expr); + self.space(); + } + MatchKind::Postfix => { + self.print_expr_as_cond(expr); + self.word_nbsp(".match"); + } + } + self.bopen(); self.print_inner_attributes_no_trailing_hardbreak(attrs); for arm in arms { diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 56c56b2704b..92efeab08eb 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -245,7 +245,7 @@ impl<'cx, 'a> Context<'cx, 'a> { ExprKind::Let(_, local_expr, _, _) => { self.manage_cond_expr(local_expr); } - ExprKind::Match(local_expr, _) => { + ExprKind::Match(local_expr, ..) => { self.manage_cond_expr(local_expr); } ExprKind::MethodCall(call) => { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 6eccd67f8af..60dbdf8b544 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -132,7 +132,7 @@ fn cs_partial_cmp( // Reference: https://github.com/rust-lang/rust/pull/103659#issuecomment-1328126354 if !tag_then_data - && let ExprKind::Match(_, arms) = &mut expr1.kind + && let ExprKind::Match(_, arms, _) = &mut expr1.kind && let Some(last) = arms.last_mut() && let PatKind::Wild = last.pat.kind { diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index b11a1b6cda1..108c1078eaa 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -2,8 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; -use ast::EnumDef; -use rustc_ast::{self as ast, MetaItem}; +use rustc_ast::{self as ast, EnumDef, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 989b7b485c9..15964016357 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -1,6 +1,6 @@ use crate::base::ExtCtxt; use rustc_ast::ptr::P; -use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp}; +use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp}; use rustc_ast::{attr, token, util::literal}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -524,7 +524,7 @@ impl<'a> ExtCtxt<'a> { } pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> { - self.expr(span, ast::ExprKind::Match(arg, arms)) + self.expr(span, ast::ExprKind::Match(arg, arms, MatchKind::Prefix)) } pub fn expr_if( diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3481c66da70..32b45f865e9 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -865,7 +865,7 @@ trait UnusedDelimLint { (iter, UnusedDelimsCtx::ForIterExpr, true, None, Some(body.span.lo()), true) } - Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => { + Match(ref head, ..) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => { let left = e.span.lo() + rustc_span::BytePos(5); (head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None, true) } @@ -1133,7 +1133,7 @@ impl EarlyLintPass for UnusedParens { } return; } - ExprKind::Match(ref _expr, ref arm) => { + ExprKind::Match(ref _expr, ref arm, _) => { for a in arm { if let Some(body) = &a.body { self.check_unused_delims_expr( diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 02ff452473d..e9c1bc7ad56 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -11,7 +11,7 @@ use crate::errors; use crate::maybe_recover_from_interpolated_ty_qpath; use ast::mut_visit::{noop_visit_expr, MutVisitor}; use ast::token::IdentIsRaw; -use ast::{CoroutineKind, ForLoopKind, GenBlockKind, Pat, Path, PathSegment}; +use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment}; use core::mem; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; @@ -1375,10 +1375,11 @@ impl<'a> Parser<'a> { return Ok(self.mk_await_expr(self_arg, lo)); } + // Post-fix match if self.eat_keyword(kw::Match) { let match_span = self.prev_token.span; self.psess.gated_spans.gate(sym::postfix_match, match_span); - return self.parse_match_block(lo, match_span, self_arg); + return self.parse_match_block(lo, match_span, self_arg, MatchKind::Postfix); } let fn_span_lo = self.token.span; @@ -2897,16 +2898,17 @@ impl<'a> Parser<'a> { let match_span = self.prev_token.span; let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; - self.parse_match_block(match_span, match_span, scrutinee) + self.parse_match_block(match_span, match_span, scrutinee, MatchKind::Prefix) } - /// Parses a `match expr { ... }` or a `expr.match { ... }` expression. - /// This is after the match token and scrutinee are eaten + /// Parses the block of a `match expr { ... }` or a `expr.match { ... }` + /// expression. This is after the match token and scrutinee are eaten fn parse_match_block( &mut self, lo: Span, match_span: Span, scrutinee: P<Expr>, + match_kind: MatchKind, ) -> PResult<'a, P<Expr>> { if let Err(mut e) = self.expect(&token::OpenDelim(Delimiter::Brace)) { if self.token == token::Semi { @@ -2950,7 +2952,7 @@ impl<'a> Parser<'a> { }); return Ok(self.mk_expr_with_attrs( span, - ExprKind::Match(scrutinee, arms), + ExprKind::Match(scrutinee, arms, match_kind), attrs, )); } @@ -2958,7 +2960,7 @@ impl<'a> Parser<'a> { } let hi = self.token.span; self.bump(); - Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs)) + Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms, match_kind), attrs)) } /// Attempt to recover from match arm body with statements and no surrounding braces. @@ -3967,7 +3969,7 @@ impl MutVisitor for CondChecker<'_> { | ExprKind::While(_, _, _) | ExprKind::ForLoop { .. } | ExprKind::Loop(_, _, _) - | ExprKind::Match(_, _) + | ExprKind::Match(_, _, _) | ExprKind::Closure(_) | ExprKind::Block(_, _) | ExprKind::Gen(_, _, _) diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs index fb434fb7450..3bdf13dbbea 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_else.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs @@ -105,7 +105,7 @@ 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| + 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), diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index 60e9d262e7e..ab1b3043f0c 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -552,7 +552,7 @@ fn ident_difference_expr_with_base_location( | (Gen(_, _, _), Gen(_, _, _)) | (Block(_, _), Block(_, _)) | (Closure(_), Closure(_)) - | (Match(_, _), Match(_, _)) + | (Match(_, _, _), Match(_, _, _)) | (Loop(_, _, _), Loop(_, _, _)) | (ForLoop { .. }, ForLoop { .. }) | (While(_, _, _), While(_, _, _)) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 3b3939da7b6..eb916a37f6e 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -198,7 +198,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { }, (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv), (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp), - (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm), + (Match(ls, la, lkind), Match(rs, ra, rkind)) => (lkind == rkind) && eq_expr(ls, rs) && over(la, ra, eq_arm), ( Closure(box ast::Closure { binder: lb, diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index c500b30b998..e04290ce87c 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -3,7 +3,7 @@ use std::cmp::min; use itertools::Itertools; use rustc_ast::token::{Delimiter, Lit, LitKind}; -use rustc_ast::{ast, ptr, token, ForLoopKind}; +use rustc_ast::{ast, MatchKind, ptr, token, ForLoopKind}; use rustc_span::{BytePos, Span}; use crate::chains::rewrite_chain; @@ -170,8 +170,8 @@ pub(crate) fn format_expr( } } } - ast::ExprKind::Match(ref cond, ref arms) => { - rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs) + ast::ExprKind::Match(ref cond, ref arms, kind) => { + rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs, kind) } ast::ExprKind::Path(ref qself, ref path) => { rewrite_path(context, PathContext::Expr, qself, path, shape) @@ -625,7 +625,7 @@ pub(crate) fn rewrite_cond( shape: Shape, ) -> Option<String> { match expr.kind { - ast::ExprKind::Match(ref cond, _) => { + ast::ExprKind::Match(ref cond, _, MatchKind::Prefix) => { // `match `cond` {` let cond_shape = match context.config.indent_style() { IndentStyle::Visual => shape.shrink_left(6).and_then(|s| s.sub_width(2))?, diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs index 5a00984d4c0..63e3162be2c 100644 --- a/src/tools/rustfmt/src/matches.rs +++ b/src/tools/rustfmt/src/matches.rs @@ -2,7 +2,7 @@ use std::iter::repeat; -use rustc_ast::{ast, ptr}; +use rustc_ast::{ast, MatchKind, ptr}; use rustc_span::{BytePos, Span}; use crate::comment::{combine_strs_with_missing_comments, rewrite_comment}; @@ -72,6 +72,8 @@ pub(crate) fn rewrite_match( shape: Shape, span: Span, attrs: &[ast::Attribute], + // TODO: Use this + _: MatchKind, ) -> Option<String> { // Do not take the rhs overhead from the upper expressions into account // when rewriting match condition. diff --git a/tests/pretty/postfix-match.rs b/tests/pretty/postfix-match.rs new file mode 100644 index 00000000000..5bb54e15275 --- /dev/null +++ b/tests/pretty/postfix-match.rs @@ -0,0 +1,21 @@ +#![feature(postfix_match)] + +fn main() { + let val = Some(42); + + val.match { + Some(_) => 2, + _ => 1 + }; + + + Some(2).match { + Some(_) => true, + None => false + }.match { + false => "ferris is cute", + true => "I turn cats in to petted cats", + }.match { + _ => (), + } +} |
