Add or- and parenthesized-patterns

This commit is contained in:
Matthew Jasper 2020-02-09 18:57:01 +00:00
parent 1b9b13b4b4
commit 8c8d0bb34f
15 changed files with 184 additions and 46 deletions

View file

@ -75,10 +75,10 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx) -> Option<Assist> {
} }
fn is_trivial(arm: &ast::MatchArm) -> bool { fn is_trivial(arm: &ast::MatchArm) -> bool {
arm.pats().any(|pat| match pat { match arm.pat() {
ast::Pat::PlaceholderPat(..) => true, Some(ast::Pat::PlaceholderPat(..)) => true,
_ => false, _ => false,
}) }
} }
fn resolve_enum_def( fn resolve_enum_def(

View file

@ -75,7 +75,7 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> {
} else { } else {
arms_to_merge arms_to_merge
.iter() .iter()
.flat_map(ast::MatchArm::pats) .filter_map(ast::MatchArm::pat)
.map(|x| x.syntax().to_string()) .map(|x| x.syntax().to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(" | ") .join(" | ")
@ -96,10 +96,10 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> {
} }
fn contains_placeholder(a: &ast::MatchArm) -> bool { fn contains_placeholder(a: &ast::MatchArm) -> bool {
a.pats().any(|x| match x { match a.pat() {
ra_syntax::ast::Pat::PlaceholderPat(..) => true, Some(ra_syntax::ast::Pat::PlaceholderPat(..)) => true,
_ => false, _ => false,
}) }
} }
fn next_arm(arm: &ast::MatchArm) -> Option<ast::MatchArm> { fn next_arm(arm: &ast::MatchArm) -> Option<ast::MatchArm> {

View file

@ -90,7 +90,7 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> {
// ``` // ```
pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> { pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?; let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?;
let last_match_pat = match_arm.pats().last()?; let match_pat = match_arm.pat()?;
let arm_body = match_arm.expr()?; let arm_body = match_arm.expr()?;
let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone())?; let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone())?;
@ -122,8 +122,8 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
_ => edit.replace(if_expr.syntax().text_range(), then_block.syntax().text()), _ => edit.replace(if_expr.syntax().text_range(), then_block.syntax().text()),
} }
edit.insert(last_match_pat.syntax().text_range().end(), buf); edit.insert(match_pat.syntax().text_range().end(), buf);
edit.set_cursor(last_match_pat.syntax().text_range().end() + TextUnit::from(1)); edit.set_cursor(match_pat.syntax().text_range().end() + TextUnit::from(1));
}, },
) )
} }

View file

@ -164,9 +164,9 @@ where
let match_expr = self.collect_expr_opt(condition.expr()); let match_expr = self.collect_expr_opt(condition.expr());
let placeholder_pat = self.missing_pat(); let placeholder_pat = self.missing_pat();
let arms = vec![ let arms = vec![
MatchArm { pats: vec![pat], expr: then_branch, guard: None }, MatchArm { pat, expr: then_branch, guard: None },
MatchArm { MatchArm {
pats: vec![placeholder_pat], pat: placeholder_pat,
expr: else_branch.unwrap_or_else(|| self.empty_block()), expr: else_branch.unwrap_or_else(|| self.empty_block()),
guard: None, guard: None,
}, },
@ -203,8 +203,8 @@ where
let placeholder_pat = self.missing_pat(); let placeholder_pat = self.missing_pat();
let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); let break_ = self.alloc_expr_desugared(Expr::Break { expr: None });
let arms = vec![ let arms = vec![
MatchArm { pats: vec![pat], expr: body, guard: None }, MatchArm { pat, expr: body, guard: None },
MatchArm { pats: vec![placeholder_pat], expr: break_, guard: None }, MatchArm { pat: placeholder_pat, expr: break_, guard: None },
]; ];
let match_expr = let match_expr =
self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
@ -250,7 +250,7 @@ where
match_arm_list match_arm_list
.arms() .arms()
.map(|arm| MatchArm { .map(|arm| MatchArm {
pats: arm.pats().map(|p| self.collect_pat(p)).collect(), pat: self.collect_pat_opt(arm.pat()),
expr: self.collect_expr_opt(arm.expr()), expr: self.collect_expr_opt(arm.expr()),
guard: arm guard: arm
.guard() .guard()
@ -587,6 +587,11 @@ where
let path = p.path().and_then(|path| self.expander.parse_path(path)); let path = p.path().and_then(|path| self.expander.parse_path(path));
path.map(Pat::Path).unwrap_or(Pat::Missing) path.map(Pat::Path).unwrap_or(Pat::Missing)
} }
ast::Pat::OrPat(p) => {
let pats = p.pats().map(|p| self.collect_pat(p)).collect();
Pat::Or(pats)
}
ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()),
ast::Pat::TuplePat(p) => { ast::Pat::TuplePat(p) => {
let args = p.args().map(|p| self.collect_pat(p)).collect(); let args = p.args().map(|p| self.collect_pat(p)).collect();
Pat::Tuple(args) Pat::Tuple(args)

View file

@ -158,9 +158,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
compute_expr_scopes(*expr, body, scopes, scope); compute_expr_scopes(*expr, body, scopes, scope);
for arm in arms { for arm in arms {
let scope = scopes.new_scope(scope); let scope = scopes.new_scope(scope);
for pat in &arm.pats { scopes.add_bindings(body, scope, arm.pat);
scopes.add_bindings(body, scope, *pat);
}
scopes.set_scope(arm.expr, scope); scopes.set_scope(arm.expr, scope);
compute_expr_scopes(arm.expr, body, scopes, scope); compute_expr_scopes(arm.expr, body, scopes, scope);
} }

View file

@ -202,7 +202,7 @@ pub enum Array {
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct MatchArm { pub struct MatchArm {
pub pats: Vec<PatId>, pub pat: PatId,
pub guard: Option<ExprId>, pub guard: Option<ExprId>,
pub expr: ExprId, pub expr: ExprId,
} }
@ -382,6 +382,7 @@ pub enum Pat {
Missing, Missing,
Wild, Wild,
Tuple(Vec<PatId>), Tuple(Vec<PatId>),
Or(Vec<PatId>),
Record { Record {
path: Option<Path>, path: Option<Path>,
args: Vec<RecordFieldPat>, args: Vec<RecordFieldPat>,
@ -420,7 +421,7 @@ impl Pat {
Pat::Bind { subpat, .. } => { Pat::Bind { subpat, .. } => {
subpat.iter().copied().for_each(f); subpat.iter().copied().for_each(f);
} }
Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { Pat::Or(args) | Pat::Tuple(args) | Pat::TupleStruct { args, .. } => {
args.iter().copied().for_each(f); args.iter().copied().for_each(f);
} }
Pat::Ref { pat, .. } => f(*pat), Pat::Ref { pat, .. } => f(*pat),

View file

@ -168,9 +168,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let mut result_ty = self.table.new_maybe_never_type_var(); let mut result_ty = self.table.new_maybe_never_type_var();
for arm in arms { for arm in arms {
for &pat in &arm.pats { let _pat_ty = self.infer_pat(arm.pat, &input_ty, BindingMode::default());
let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default());
}
if let Some(guard_expr) = arm.guard { if let Some(guard_expr) = arm.guard {
self.infer_expr( self.infer_expr(
guard_expr, guard_expr,

View file

@ -82,6 +82,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
let is_non_ref_pat = match &body[pat] { let is_non_ref_pat = match &body[pat] {
Pat::Tuple(..) Pat::Tuple(..)
| Pat::Or(..)
| Pat::TupleStruct { .. } | Pat::TupleStruct { .. }
| Pat::Record { .. } | Pat::Record { .. }
| Pat::Range { .. } | Pat::Range { .. }
@ -126,6 +127,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys)) Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys))
} }
Pat::Or(ref pats) => {
if let Some((first_pat, rest)) = pats.split_first() {
let ty = self.infer_pat(*first_pat, expected, default_bm);
for pat in rest {
self.infer_pat(*pat, expected, default_bm);
}
ty
} else {
Ty::Unknown
}
}
Pat::Ref { pat, mutability } => { Pat::Ref { pat, mutability } => {
let expectation = match expected.as_reference() { let expectation = match expected.as_reference() {
Some((inner_ty, exp_mut)) => { Some((inner_ty, exp_mut)) => {

View file

@ -80,8 +80,7 @@ fn get_inlay_hints(
}, },
ast::MatchArmList(it) => { ast::MatchArmList(it) => {
it.arms() it.arms()
.map(|match_arm| match_arm.pats()) .filter_map(|match_arm| match_arm.pat())
.flatten()
.for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length)); .for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length));
}, },
ast::CallExpr(it) => { ast::CallExpr(it) => {
@ -202,6 +201,7 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> {
Some(pat) => pats_to_process.push_back(pat), Some(pat) => pats_to_process.push_back(pat),
_ => leaf_pats.push(maybe_leaf_pat), _ => leaf_pats.push(maybe_leaf_pat),
}, },
ast::Pat::OrPat(ref_pat) => pats_to_process.extend(ref_pat.pats()),
ast::Pat::TuplePat(tuple_pat) => pats_to_process.extend(tuple_pat.args()), ast::Pat::TuplePat(tuple_pat) => pats_to_process.extend(tuple_pat.args()),
ast::Pat::RecordPat(record_pat) => { ast::Pat::RecordPat(record_pat) => {
if let Some(pat_list) = record_pat.record_field_pat_list() { if let Some(pat_list) = record_pat.record_field_pat_list() {
@ -222,6 +222,7 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> {
ast::Pat::TupleStructPat(tuple_struct_pat) => { ast::Pat::TupleStructPat(tuple_struct_pat) => {
pats_to_process.extend(tuple_struct_pat.args()) pats_to_process.extend(tuple_struct_pat.args())
} }
ast::Pat::ParenPat(inner_pat) => pats_to_process.extend(inner_pat.pat()),
ast::Pat::RefPat(ref_pat) => pats_to_process.extend(ref_pat.pat()), ast::Pat::RefPat(ref_pat) => pats_to_process.extend(ref_pat.pat()),
_ => (), _ => (),
} }

View file

@ -336,7 +336,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
fn cond(p: &mut Parser) { fn cond(p: &mut Parser) {
let m = p.start(); let m = p.start();
if p.eat(T![let]) { if p.eat(T![let]) {
patterns::pattern_list(p); patterns::pattern_top(p);
p.expect(T![=]); p.expect(T![=]);
} }
expr_no_struct(p); expr_no_struct(p);
@ -430,7 +430,7 @@ fn match_arm(p: &mut Parser) -> BlockLike {
// } // }
attributes::outer_attributes(p); attributes::outer_attributes(p);
patterns::pattern_list_r(p, TokenSet::EMPTY); patterns::pattern_top_r(p, TokenSet::EMPTY);
if p.at(T![if]) { if p.at(T![if]) {
match_guard(p); match_guard(p);
} }

View file

@ -116,7 +116,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
// type Qux = fn(baz: Bar::Baz); // type Qux = fn(baz: Bar::Baz);
Flavor::FnPointer => { Flavor::FnPointer => {
if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
patterns::pattern(p); patterns::pattern_single(p);
types::ascription(p); types::ascription(p);
} else { } else {
types::type_(p); types::type_(p);
@ -127,7 +127,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
// let foo = |bar, baz: Baz, qux: Qux::Quux| (); // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
// } // }
Flavor::Closure => { Flavor::Closure => {
patterns::pattern(p); patterns::pattern_single(p);
if p.at(T![:]) && !p.at(T![::]) { if p.at(T![:]) && !p.at(T![::]) {
types::ascription(p); types::ascription(p);
} }

View file

@ -11,22 +11,49 @@ pub(crate) fn pattern(p: &mut Parser) {
} }
/// Parses a pattern list separated by pipes `|` /// Parses a pattern list separated by pipes `|`
pub(super) fn pattern_list(p: &mut Parser) { pub(super) fn pattern_top(p: &mut Parser) {
pattern_list_r(p, PAT_RECOVERY_SET) pattern_top_r(p, PAT_RECOVERY_SET)
}
pub(crate) fn pattern_single(p: &mut Parser) {
pattern_single_r(p, PAT_RECOVERY_SET);
} }
/// Parses a pattern list separated by pipes `|` /// Parses a pattern list separated by pipes `|`
/// using the given `recovery_set` /// using the given `recovery_set`
pub(super) fn pattern_list_r(p: &mut Parser, recovery_set: TokenSet) { pub(super) fn pattern_top_r(p: &mut Parser, recovery_set: TokenSet) {
p.eat(T![|]); p.eat(T![|]);
pattern_r(p, recovery_set); pattern_r(p, recovery_set);
}
/// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
/// given `recovery_set`
// test or_pattern
// fn main() {
// match () {
// (_ | _) => (),
// &(_ | _) => (),
// (_ | _,) => (),
// [_ | _,] => (),
// }
// }
fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
let m = p.start();
pattern_single_r(p, recovery_set);
let mut is_or_pat = false;
while p.eat(T![|]) { while p.eat(T![|]) {
pattern_r(p, recovery_set); is_or_pat = true;
pattern_single_r(p, recovery_set);
}
if is_or_pat {
m.complete(p, OR_PAT);
} else {
m.abandon(p);
} }
} }
pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
if let Some(lhs) = atom_pat(p, recovery_set) { if let Some(lhs) = atom_pat(p, recovery_set) {
// test range_pat // test range_pat
// fn main() { // fn main() {
@ -258,7 +285,7 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker {
let m = p.start(); let m = p.start();
p.bump(T![&]); p.bump(T![&]);
p.eat(T![mut]); p.eat(T![mut]);
pattern(p); pattern_single(p);
m.complete(p, REF_PAT) m.complete(p, REF_PAT)
} }
@ -269,8 +296,27 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker {
fn tuple_pat(p: &mut Parser) -> CompletedMarker { fn tuple_pat(p: &mut Parser) -> CompletedMarker {
assert!(p.at(T!['('])); assert!(p.at(T!['(']));
let m = p.start(); let m = p.start();
tuple_pat_fields(p); p.bump(T!['(']);
m.complete(p, TUPLE_PAT) let mut has_comma = false;
let mut has_pat = false;
let mut has_rest = false;
while !p.at(EOF) && !p.at(T![')']) {
has_pat = true;
if !p.at_ts(PATTERN_FIRST) {
p.error("expected a pattern");
break;
}
has_rest |= p.at(T![..]);
pattern(p);
if !p.at(T![')']) {
has_comma = true;
p.expect(T![,]);
}
}
p.expect(T![')']);
m.complete(p, if !has_comma && !has_rest && has_pat { PAREN_PAT } else { TUPLE_PAT })
} }
// test slice_pat // test slice_pat
@ -315,7 +361,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
p.eat(T![mut]); p.eat(T![mut]);
name(p); name(p);
if with_at && p.eat(T![@]) { if with_at && p.eat(T![@]) {
pattern(p); pattern_single(p);
} }
m.complete(p, BIND_PAT) m.complete(p, BIND_PAT)
} }
@ -330,6 +376,6 @@ fn box_pat(p: &mut Parser) -> CompletedMarker {
assert!(p.at(T![box])); assert!(p.at(T![box]));
let m = p.start(); let m = p.start();
p.bump(T![box]); p.bump(T![box]);
pattern(p); pattern_single(p);
m.complete(p, BOX_PAT) m.complete(p, BOX_PAT)
} }

View file

@ -151,6 +151,8 @@ pub enum SyntaxKind {
FOR_TYPE, FOR_TYPE,
IMPL_TRAIT_TYPE, IMPL_TRAIT_TYPE,
DYN_TRAIT_TYPE, DYN_TRAIT_TYPE,
OR_PAT,
PAREN_PAT,
REF_PAT, REF_PAT,
BOX_PAT, BOX_PAT,
BIND_PAT, BIND_PAT,

View file

@ -1759,8 +1759,8 @@ impl AstNode for MatchArm {
} }
impl ast::AttrsOwner for MatchArm {} impl ast::AttrsOwner for MatchArm {}
impl MatchArm { impl MatchArm {
pub fn pats(&self) -> AstChildren<Pat> { pub fn pat(&self) -> Option<Pat> {
AstChildren::new(&self.syntax) AstChildren::new(&self.syntax).next()
} }
pub fn guard(&self) -> Option<MatchGuard> { pub fn guard(&self) -> Option<MatchGuard> {
AstChildren::new(&self.syntax).next() AstChildren::new(&self.syntax).next()
@ -1887,6 +1887,60 @@ impl RecordField {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct OrPat {
pub(crate) syntax: SyntaxNode,
}
impl AstNode for OrPat {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
OR_PAT => true,
_ => false,
}
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.syntax
}
}
impl OrPat {
pub fn pats(&self) -> AstChildren<Pat> {
AstChildren::new(&self.syntax)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ParenPat {
pub(crate) syntax: SyntaxNode,
}
impl AstNode for ParenPat {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
PAREN_PAT => true,
_ => false,
}
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.syntax
}
}
impl ParenPat {
pub fn pat(&self) -> Option<Pat> {
AstChildren::new(&self.syntax).next()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RefPat { pub struct RefPat {
pub(crate) syntax: SyntaxNode, pub(crate) syntax: SyntaxNode,
} }
@ -3900,6 +3954,8 @@ impl AstNode for Expr {
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Pat { pub enum Pat {
OrPat(OrPat),
ParenPat(ParenPat),
RefPat(RefPat), RefPat(RefPat),
BoxPat(BoxPat), BoxPat(BoxPat),
BindPat(BindPat), BindPat(BindPat),
@ -3913,6 +3969,16 @@ pub enum Pat {
RangePat(RangePat), RangePat(RangePat),
LiteralPat(LiteralPat), LiteralPat(LiteralPat),
} }
impl From<OrPat> for Pat {
fn from(node: OrPat) -> Pat {
Pat::OrPat(node)
}
}
impl From<ParenPat> for Pat {
fn from(node: ParenPat) -> Pat {
Pat::ParenPat(node)
}
}
impl From<RefPat> for Pat { impl From<RefPat> for Pat {
fn from(node: RefPat) -> Pat { fn from(node: RefPat) -> Pat {
Pat::RefPat(node) Pat::RefPat(node)
@ -3976,15 +4042,16 @@ impl From<LiteralPat> for Pat {
impl AstNode for Pat { impl AstNode for Pat {
fn can_cast(kind: SyntaxKind) -> bool { fn can_cast(kind: SyntaxKind) -> bool {
match kind { match kind {
REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT
| RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => { | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT
true | LITERAL_PAT => true,
}
_ => false, _ => false,
} }
} }
fn cast(syntax: SyntaxNode) -> Option<Self> { fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() { let res = match syntax.kind() {
OR_PAT => Pat::OrPat(OrPat { syntax }),
PAREN_PAT => Pat::ParenPat(ParenPat { syntax }),
REF_PAT => Pat::RefPat(RefPat { syntax }), REF_PAT => Pat::RefPat(RefPat { syntax }),
BOX_PAT => Pat::BoxPat(BoxPat { syntax }), BOX_PAT => Pat::BoxPat(BoxPat { syntax }),
BIND_PAT => Pat::BindPat(BindPat { syntax }), BIND_PAT => Pat::BindPat(BindPat { syntax }),
@ -4003,6 +4070,8 @@ impl AstNode for Pat {
} }
fn syntax(&self) -> &SyntaxNode { fn syntax(&self) -> &SyntaxNode {
match self { match self {
Pat::OrPat(it) => &it.syntax,
Pat::ParenPat(it) => &it.syntax,
Pat::RefPat(it) => &it.syntax, Pat::RefPat(it) => &it.syntax,
Pat::BoxPat(it) => &it.syntax, Pat::BoxPat(it) => &it.syntax,
Pat::BindPat(it) => &it.syntax, Pat::BindPat(it) => &it.syntax,

View file

@ -120,6 +120,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
"FOR_TYPE", "FOR_TYPE",
"IMPL_TRAIT_TYPE", "IMPL_TRAIT_TYPE",
"DYN_TRAIT_TYPE", "DYN_TRAIT_TYPE",
"OR_PAT",
"PAREN_PAT",
"REF_PAT", "REF_PAT",
"BOX_PAT", "BOX_PAT",
"BIND_PAT", "BIND_PAT",
@ -412,7 +414,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
struct MatchExpr { Expr, MatchArmList } struct MatchExpr { Expr, MatchArmList }
struct MatchArmList: AttrsOwner { arms: [MatchArm] } struct MatchArmList: AttrsOwner { arms: [MatchArm] }
struct MatchArm: AttrsOwner { struct MatchArm: AttrsOwner {
pats: [Pat], pat: Pat,
guard: MatchGuard, guard: MatchGuard,
Expr, Expr,
} }
@ -425,6 +427,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
} }
struct RecordField { NameRef, Expr } struct RecordField { NameRef, Expr }
struct OrPat { pats: [Pat] }
struct ParenPat { Pat }
struct RefPat { Pat } struct RefPat { Pat }
struct BoxPat { Pat } struct BoxPat { Pat }
struct BindPat: NameOwner { Pat } struct BindPat: NameOwner { Pat }
@ -601,6 +605,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
} }
enum Pat { enum Pat {
OrPat,
ParenPat,
RefPat, RefPat,
BoxPat, BoxPat,
BindPat, BindPat,