Skip to content

Commit 02e377e

Browse files
committed
Add MatchKind member to the Match expr for pretty printing & fmt
1 parent 62f97c3 commit 02e377e

File tree

20 files changed

+99
-40
lines changed

20 files changed

+99
-40
lines changed

compiler/rustc_ast/src/ast.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ pub enum ExprKind {
14371437
/// `'label: loop { block }`
14381438
Loop(P<Block>, Option<Label>, Span),
14391439
/// A `match` block.
1440-
Match(P<Expr>, ThinVec<Arm>),
1440+
Match(P<Expr>, ThinVec<Arm>, MatchKind),
14411441
/// A closure (e.g., `move |a, b, c| a + b + c`).
14421442
Closure(Box<Closure>),
14431443
/// A block (`'label: { ... }`).
@@ -1759,6 +1759,15 @@ pub enum StrStyle {
17591759
Raw(u8),
17601760
}
17611761

1762+
/// The kind of match expression
1763+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1764+
pub enum MatchKind {
1765+
/// match expr { ... }
1766+
Prefix,
1767+
/// expr.match { ... }
1768+
Postfix,
1769+
}
1770+
17621771
/// A literal in a meta item.
17631772
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
17641773
pub struct MetaItemLit {

compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
14221422
visit_opt(label, |label| vis.visit_label(label));
14231423
vis.visit_span(span);
14241424
}
1425-
ExprKind::Match(expr, arms) => {
1425+
ExprKind::Match(expr, arms, _) => {
14261426
vis.visit_expr(expr);
14271427
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
14281428
}

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
981981
visit_opt!(visitor, visit_label, opt_label);
982982
try_visit!(visitor.visit_block(block));
983983
}
984-
ExprKind::Match(subexpression, arms) => {
984+
ExprKind::Match(subexpression, arms, _) => {
985985
try_visit!(visitor.visit_expr(subexpression));
986986
walk_list!(visitor, visit_arm, arms);
987987
}

compiler/rustc_ast_lowering/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
184184
)
185185
}),
186186
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
187-
ExprKind::Match(expr, arms) => hir::ExprKind::Match(
187+
ExprKind::Match(expr, arms, _) => hir::ExprKind::Match(
188188
self.lower_expr(expr),
189189
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
190190
hir::MatchSource::Normal,

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::pp::Breaks::Inconsistent;
22
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
3-
use ast::ForLoopKind;
3+
use ast::{ForLoopKind, MatchKind};
44
use itertools::{Itertools, Position};
55
use rustc_ast::ptr::P;
66
use rustc_ast::token;
@@ -589,12 +589,22 @@ impl<'a> State<'a> {
589589
self.word_nbsp("loop");
590590
self.print_block_with_attrs(blk, attrs);
591591
}
592-
ast::ExprKind::Match(expr, arms) => {
592+
ast::ExprKind::Match(expr, arms, match_kind) => {
593593
self.cbox(0);
594594
self.ibox(0);
595-
self.word_nbsp("match");
596-
self.print_expr_as_cond(expr);
597-
self.space();
595+
596+
match match_kind {
597+
MatchKind::Prefix => {
598+
self.word_nbsp("match");
599+
self.print_expr_as_cond(expr);
600+
self.space();
601+
}
602+
MatchKind::Postfix => {
603+
self.print_expr_as_cond(expr);
604+
self.word_nbsp(".match");
605+
}
606+
}
607+
598608
self.bopen();
599609
self.print_inner_attributes_no_trailing_hardbreak(attrs);
600610
for arm in arms {

compiler/rustc_builtin_macros/src/assert/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
245245
ExprKind::Let(_, local_expr, _, _) => {
246246
self.manage_cond_expr(local_expr);
247247
}
248-
ExprKind::Match(local_expr, _) => {
248+
ExprKind::Match(local_expr, _, _) => {
249249
self.manage_cond_expr(local_expr);
250250
}
251251
ExprKind::MethodCall(call) => {

compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::deriving::generic::ty::*;
22
use crate::deriving::generic::*;
33
use crate::deriving::path_std;
4-
use rustc_ast::MetaItem;
4+
use rustc_ast::{ast::MatchKind, MetaItem};
55
use rustc_expand::base::{Annotatable, ExtCtxt};
66
use rustc_span::symbol::{sym, Ident};
77
use rustc_span::Span;
@@ -70,7 +70,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl
7070
let eq_arm = cx.arm(span, cx.pat_path(span, equal_path.clone()), expr1);
7171
let neq_arm =
7272
cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
73-
cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm])
73+
cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm], MatchKind::Prefix)
7474
}
7575
CsFold::Fieldless => cx.expr_path(equal_path.clone()),
7676
},

compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::deriving::generic::ty::*;
22
use crate::deriving::generic::*;
33
use crate::deriving::{path_std, pathvec_std};
4-
use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind};
4+
use rustc_ast::{ExprKind, ItemKind, MatchKind, MetaItem, PatKind};
55
use rustc_expand::base::{Annotatable, ExtCtxt};
66
use rustc_span::symbol::{sym, Ident};
77
use rustc_span::Span;
@@ -132,7 +132,7 @@ fn cs_partial_cmp(
132132
// Reference: https://github.com/rust-lang/rust/pull/103659#issuecomment-1328126354
133133

134134
if !tag_then_data
135-
&& let ExprKind::Match(_, arms) = &mut expr1.kind
135+
&& let ExprKind::Match(_, arms, _) = &mut expr1.kind
136136
&& let Some(last) = arms.last_mut()
137137
&& let PatKind::Wild = last.pat.kind
138138
{
@@ -146,7 +146,7 @@ fn cs_partial_cmp(
146146
);
147147
let neq_arm =
148148
cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
149-
cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm])
149+
cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm], MatchKind::Prefix)
150150
}
151151
}
152152
CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),

compiler/rustc_builtin_macros/src/deriving/debug.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::deriving::generic::*;
33
use crate::deriving::path_std;
44

55
use ast::EnumDef;
6+
use ast::MatchKind;
67
use rustc_ast::{self as ast, MetaItem};
78
use rustc_expand::base::{Annotatable, ExtCtxt};
89
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -235,7 +236,7 @@ fn show_fieldless_enum(
235236
cx.arm(span, pat, cx.expr_str(span, v.ident.name))
236237
})
237238
.collect::<ThinVec<_>>();
238-
let name = cx.expr_match(span, cx.expr_self(span), arms);
239+
let name = cx.expr_match(span, cx.expr_self(span), arms, MatchKind::Prefix);
239240
let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
240241
BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]))
241242
}

compiler/rustc_builtin_macros/src/deriving/decodable.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::deriving::generic::ty::*;
44
use crate::deriving::generic::*;
55
use crate::deriving::pathvec_std;
6+
use ast::MatchKind;
67
use rustc_ast::ptr::P;
78
use rustc_ast::{self as ast, Expr, MetaItem, Mutability};
89
use rustc_expand::base::{Annotatable, ExtCtxt};
@@ -153,7 +154,12 @@ fn decodable_substructure(
153154

154155
let result = cx.expr_ok(
155156
trait_span,
156-
cx.expr_match(trait_span, cx.expr_ident(trait_span, variant), arms),
157+
cx.expr_match(
158+
trait_span,
159+
cx.expr_ident(trait_span, variant),
160+
arms,
161+
MatchKind::Prefix,
162+
),
157163
);
158164
let lambda = cx.lambda(trait_span, vec![blkarg, variant], result);
159165
let variant_array_ref = cx.expr_array_ref(trait_span, variants);

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
//! )
175175
//! ```
176176
177+
use ast::MatchKind;
177178
pub use StaticFields::*;
178179
pub use SubstructureFields::*;
179180

@@ -1184,7 +1185,7 @@ impl<'a> MethodDef<'a> {
11841185
selflike_args.truncate(1);
11851186
let match_arg = cx.expr_deref(span, selflike_args.pop().unwrap());
11861187
let match_arms = ThinVec::new();
1187-
let expr = cx.expr_match(span, match_arg, match_arms);
1188+
let expr = cx.expr_match(span, match_arg, match_arms, MatchKind::Prefix);
11881189
return BlockOrExpr(ThinVec::new(), Some(expr));
11891190
}
11901191

@@ -1381,7 +1382,7 @@ impl<'a> MethodDef<'a> {
13811382
} else {
13821383
cx.expr(span, ast::ExprKind::Tup(selflike_args))
13831384
};
1384-
cx.expr_match(span, match_arg, match_arms)
1385+
cx.expr_match(span, match_arg, match_arms, MatchKind::Prefix)
13851386
};
13861387

13871388
// If the trait uses the tag and there are multiple variants, we need

compiler/rustc_expand/src/build.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::base::ExtCtxt;
2+
use ast::MatchKind;
23
use rustc_ast::ptr::P;
34
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
45
use rustc_ast::{attr, token, util::literal};
@@ -450,7 +451,7 @@ impl<'a> ExtCtxt<'a> {
450451
let err_arm = self.arm(sp, err_pat, err_expr);
451452

452453
// `match head { Ok() => ..., Err() => ... }`
453-
self.expr_match(sp, head, thin_vec![ok_arm, err_arm])
454+
self.expr_match(sp, head, thin_vec![ok_arm, err_arm], MatchKind::Prefix)
454455
}
455456

456457
pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
@@ -520,8 +521,14 @@ impl<'a> ExtCtxt<'a> {
520521
self.arm(span, self.pat_wild(span), self.expr_unreachable(span))
521522
}
522523

523-
pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> {
524-
self.expr(span, ast::ExprKind::Match(arg, arms))
524+
pub fn expr_match(
525+
&self,
526+
span: Span,
527+
arg: P<ast::Expr>,
528+
arms: ThinVec<ast::Arm>,
529+
kind: MatchKind,
530+
) -> P<Expr> {
531+
self.expr(span, ast::ExprKind::Match(arg, arms, kind))
525532
}
526533

527534
pub fn expr_if(

compiler/rustc_lint/src/unused.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ trait UnusedDelimLint {
865865
(iter, UnusedDelimsCtx::ForIterExpr, true, None, Some(body.span.lo()), true)
866866
}
867867

868-
Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
868+
Match(ref head, _, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
869869
let left = e.span.lo() + rustc_span::BytePos(5);
870870
(head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None, true)
871871
}
@@ -1133,7 +1133,7 @@ impl EarlyLintPass for UnusedParens {
11331133
}
11341134
return;
11351135
}
1136-
ExprKind::Match(ref _expr, ref arm) => {
1136+
ExprKind::Match(ref _expr, ref arm, _) => {
11371137
for a in arm {
11381138
if let Some(body) = &a.body {
11391139
self.check_unused_delims_expr(

compiler/rustc_parse/src/parser/expr.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::errors;
1111
use crate::maybe_recover_from_interpolated_ty_qpath;
1212
use ast::mut_visit::{noop_visit_expr, MutVisitor};
1313
use ast::token::IdentIsRaw;
14-
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, Pat, Path, PathSegment};
14+
use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment};
1515
use core::mem;
1616
use rustc_ast::ptr::P;
1717
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
@@ -1375,10 +1375,11 @@ impl<'a> Parser<'a> {
13751375
return Ok(self.mk_await_expr(self_arg, lo));
13761376
}
13771377

1378+
// Post-fix match
13781379
if self.eat_keyword(kw::Match) {
13791380
let match_span = self.prev_token.span;
13801381
self.sess.gated_spans.gate(sym::postfix_match, match_span);
1381-
return self.parse_match_block(lo, match_span, self_arg);
1382+
return self.parse_match_block(lo, match_span, self_arg, MatchKind::Postfix);
13821383
}
13831384

13841385
let fn_span_lo = self.token.span;
@@ -2895,16 +2896,17 @@ impl<'a> Parser<'a> {
28952896
let match_span = self.prev_token.span;
28962897
let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
28972898

2898-
self.parse_match_block(match_span, match_span, scrutinee)
2899+
self.parse_match_block(match_span, match_span, scrutinee, MatchKind::Prefix)
28992900
}
29002901

2901-
/// Parses a `match expr { ... }` or a `expr.match { ... }` expression.
2902-
/// This is after the match token and scrutinee are eaten
2902+
/// Parses the block of a `match expr { ... }` or a `expr.match { ... }`
2903+
/// expression. This is after the match token and scrutinee are eaten
29032904
fn parse_match_block(
29042905
&mut self,
29052906
lo: Span,
29062907
match_span: Span,
29072908
scrutinee: P<Expr>,
2909+
match_kind: MatchKind,
29082910
) -> PResult<'a, P<Expr>> {
29092911
if let Err(mut e) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
29102912
if self.token == token::Semi {
@@ -2948,15 +2950,15 @@ impl<'a> Parser<'a> {
29482950
});
29492951
return Ok(self.mk_expr_with_attrs(
29502952
span,
2951-
ExprKind::Match(scrutinee, arms),
2953+
ExprKind::Match(scrutinee, arms, match_kind),
29522954
attrs,
29532955
));
29542956
}
29552957
}
29562958
}
29572959
let hi = self.token.span;
29582960
self.bump();
2959-
Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
2961+
Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms, match_kind), attrs))
29602962
}
29612963

29622964
/// Attempt to recover from match arm body with statements and no surrounding braces.
@@ -3946,7 +3948,7 @@ impl MutVisitor for CondChecker<'_> {
39463948
| ExprKind::While(_, _, _)
39473949
| ExprKind::ForLoop { .. }
39483950
| ExprKind::Loop(_, _, _)
3949-
| ExprKind::Match(_, _)
3951+
| ExprKind::Match(_, _, _)
39503952
| ExprKind::Closure(_)
39513953
| ExprKind::Block(_, _)
39523954
| ExprKind::Gen(_, _, _)

src/tools/clippy/clippy_lints/src/redundant_else.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl<'ast> Visitor<'ast> for BreakVisitor {
105105
fn visit_expr(&mut self, expr: &'ast Expr) {
106106
self.is_break = match expr.kind {
107107
ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) => true,
108-
ExprKind::Match(_, ref arms) => arms.iter().all(|arm|
108+
ExprKind::Match(_, ref arms, _) => arms.iter().all(|arm|
109109
arm.body.is_none() || arm.body.as_deref().is_some_and(|body| self.check_expr(body))
110110
),
111111
ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),

src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ fn ident_difference_expr_with_base_location(
552552
| (Gen(_, _, _), Gen(_, _, _))
553553
| (Block(_, _), Block(_, _))
554554
| (Closure(_), Closure(_))
555-
| (Match(_, _), Match(_, _))
555+
| (Match(_, _, _), Match(_, _, _))
556556
| (Loop(_, _, _), Loop(_, _, _))
557557
| (ForLoop { .. }, ForLoop { .. })
558558
| (While(_, _, _), While(_, _, _))

src/tools/clippy/clippy_utils/src/ast_utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
197197
},
198198
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
199199
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
200-
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
200+
(Match(ls, la, lkind), Match(rs, ra, rkind)) => (lkind == rkind) && eq_expr(ls, rs) && over(la, ra, eq_arm),
201201
(
202202
Closure(box ast::Closure {
203203
binder: lb,

src/tools/rustfmt/src/expr.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::cmp::min;
33

44
use itertools::Itertools;
55
use rustc_ast::token::{Delimiter, Lit, LitKind};
6-
use rustc_ast::{ast, ptr, token, ForLoopKind};
6+
use rustc_ast::{ast, ast::MatchKind, ptr, token, ForLoopKind};
77
use rustc_span::{BytePos, Span};
88

99
use crate::chains::rewrite_chain;
@@ -170,8 +170,8 @@ pub(crate) fn format_expr(
170170
}
171171
}
172172
}
173-
ast::ExprKind::Match(ref cond, ref arms) => {
174-
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs)
173+
ast::ExprKind::Match(ref cond, ref arms, kind) => {
174+
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs, kind)
175175
}
176176
ast::ExprKind::Path(ref qself, ref path) => {
177177
rewrite_path(context, PathContext::Expr, qself, path, shape)
@@ -625,7 +625,7 @@ pub(crate) fn rewrite_cond(
625625
shape: Shape,
626626
) -> Option<String> {
627627
match expr.kind {
628-
ast::ExprKind::Match(ref cond, _) => {
628+
ast::ExprKind::Match(ref cond, _, MatchKind::Prefix) => {
629629
// `match `cond` {`
630630
let cond_shape = match context.config.indent_style() {
631631
IndentStyle::Visual => shape.shrink_left(6).and_then(|s| s.sub_width(2))?,

src/tools/rustfmt/src/matches.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::iter::repeat;
44

5-
use rustc_ast::{ast, ptr};
5+
use rustc_ast::{ast, ast::MatchKind, ptr};
66
use rustc_span::{BytePos, Span};
77

88
use crate::comment::{combine_strs_with_missing_comments, rewrite_comment};
@@ -72,6 +72,8 @@ pub(crate) fn rewrite_match(
7272
shape: Shape,
7373
span: Span,
7474
attrs: &[ast::Attribute],
75+
// TODO: Use this
76+
_: MatchKind,
7577
) -> Option<String> {
7678
// Do not take the rhs overhead from the upper expressions into account
7779
// when rewriting match condition.

0 commit comments

Comments
 (0)