Skip to content

Commit efde155

Browse files
authored
Rollup merge of rust-lang#121619 - RossSmyth:pfix_match, r=petrochenkov
Experimental feature postfix match This has a basic experimental implementation for the RFC postfix match (rust-lang/rfcs#3295, rust-lang#121618). [Liaison is](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Postfix.20Match.20Liaison/near/423301844) ``@scottmcm`` with the lang team's [experimental feature gate process](https://github.com/rust-lang/lang-team/blob/master/src/how_to/experiment.md). This feature has had an RFC for a while, and there has been discussion on it for a while. It would probably be valuable to see it out in the field rather than continue discussing it. This feature also allows to see how popular postfix expressions like this are for the postfix macros RFC, as those will take more time to implement. It is entirely implemented in the parser, so it should be relatively easy to remove if needed. This PR is split in to 5 commits to ease review. 1. The implementation of the feature & gating. 2. Add a MatchKind field, fix uses, fix pretty. 3. Basic rustfmt impl, as rustfmt crashes upon seeing this syntax without a fix. 4. Add new MatchSource to HIR for Clippy & other HIR consumers
2 parents 7762adc + 567c98b commit efde155

File tree

34 files changed

+367
-41
lines changed

34 files changed

+367
-41
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ pub enum ExprKind {
14411441
/// `'label: loop { block }`
14421442
Loop(P<Block>, Option<Label>, Span),
14431443
/// A `match` block.
1444-
Match(P<Expr>, ThinVec<Arm>),
1444+
Match(P<Expr>, ThinVec<Arm>, MatchKind),
14451445
/// A closure (e.g., `move |a, b, c| a + b + c`).
14461446
Closure(Box<Closure>),
14471447
/// A block (`'label: { ... }`).
@@ -1766,6 +1766,15 @@ pub enum StrStyle {
17661766
Raw(u8),
17671767
}
17681768

1769+
/// The kind of match expression
1770+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1771+
pub enum MatchKind {
1772+
/// match expr { ... }
1773+
Prefix,
1774+
/// expr.match { ... }
1775+
Postfix,
1776+
}
1777+
17691778
/// A literal in a meta item.
17701779
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
17711780
pub struct MetaItemLit {

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
14251425
visit_opt(label, |label| vis.visit_label(label));
14261426
vis.visit_span(span);
14271427
}
1428-
ExprKind::Match(expr, arms) => {
1428+
ExprKind::Match(expr, arms, _kind) => {
14291429
vis.visit_expr(expr);
14301430
arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
14311431
}

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
923923
visit_opt!(visitor, visit_label, opt_label);
924924
try_visit!(visitor.visit_block(block));
925925
}
926-
ExprKind::Match(subexpression, arms) => {
926+
ExprKind::Match(subexpression, arms, _kind) => {
927927
try_visit!(visitor.visit_expr(subexpression));
928928
walk_list!(visitor, visit_arm, arms);
929929
}

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
181181
)
182182
}),
183183
ExprKind::TryBlock(body) => self.lower_expr_try_block(body),
184-
ExprKind::Match(expr, arms) => hir::ExprKind::Match(
184+
ExprKind::Match(expr, arms, kind) => hir::ExprKind::Match(
185185
self.lower_expr(expr),
186186
self.arena.alloc_from_iter(arms.iter().map(|x| self.lower_arm(x))),
187-
hir::MatchSource::Normal,
187+
match kind {
188+
MatchKind::Prefix => hir::MatchSource::Normal,
189+
MatchKind::Postfix => hir::MatchSource::Postfix,
190+
},
188191
),
189192
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
190193
ExprKind::Closure(box Closure {

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
564564
gate_all!(generic_const_items, "generic const items are experimental");
565565
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
566566
gate_all!(fn_delegation, "functions delegation is not yet fully implemented");
567+
gate_all!(postfix_match, "postfix match is experimental");
567568

568569
if !visitor.features.never_patterns {
569570
if let Some(spans) = spans.get(&sym::never_patterns) {

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

Lines changed: 15 additions & 5 deletions
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

Lines changed: 1 addition & 1 deletion
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/partial_ord.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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
{

compiler/rustc_builtin_macros/src/deriving/debug.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::deriving::generic::ty::*;
22
use crate::deriving::generic::*;
33
use crate::deriving::path_std;
44

5-
use ast::EnumDef;
6-
use rustc_ast::{self as ast, MetaItem};
5+
use rustc_ast::{self as ast, EnumDef, MetaItem};
76
use rustc_expand::base::{Annotatable, ExtCtxt};
87
use rustc_span::symbol::{sym, Ident, Symbol};
98
use rustc_span::Span;

compiler/rustc_expand/src/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::base::ExtCtxt;
22
use rustc_ast::ptr::P;
3-
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp};
3+
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp};
44
use rustc_ast::{attr, token, util::literal};
55
use rustc_span::source_map::Spanned;
66
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -524,7 +524,7 @@ impl<'a> ExtCtxt<'a> {
524524
}
525525

526526
pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> {
527-
self.expr(span, ast::ExprKind::Match(arg, arms))
527+
self.expr(span, ast::ExprKind::Match(arg, arms, MatchKind::Prefix))
528528
}
529529

530530
pub fn expr_if(

0 commit comments

Comments
 (0)