diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-10 20:14:08 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-10 20:14:08 +0000 |
commit | f8d6d6f23bfb15021be91031ba983da19f0d3ada (patch) | |
tree | 9c6ab9425ba72c440b2a475d92ed984ccf1aebcc | |
parent | 29f5e7eebf606c1929d5a77ad66624cd4f3fcf49 (diff) | |
parent | 49b53cd7a0861cdba65643e3da441eefbe18d6e6 (diff) |
Merge #3074
3074: Or patterns r=matthewjasper a=matthewjasper
Works towards #2458
Co-authored-by: Matthew Jasper <[email protected]>
21 files changed, 427 insertions, 113 deletions
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs index 0908fc246..ae2437ed3 100644 --- a/crates/ra_assists/src/handlers/fill_match_arms.rs +++ b/crates/ra_assists/src/handlers/fill_match_arms.rs | |||
@@ -75,10 +75,10 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx) -> Option<Assist> { | |||
75 | } | 75 | } |
76 | 76 | ||
77 | fn is_trivial(arm: &ast::MatchArm) -> bool { | 77 | fn is_trivial(arm: &ast::MatchArm) -> bool { |
78 | arm.pats().any(|pat| match pat { | 78 | match arm.pat() { |
79 | ast::Pat::PlaceholderPat(..) => true, | 79 | Some(ast::Pat::PlaceholderPat(..)) => true, |
80 | _ => false, | 80 | _ => false, |
81 | }) | 81 | } |
82 | } | 82 | } |
83 | 83 | ||
84 | fn resolve_enum_def( | 84 | fn resolve_enum_def( |
diff --git a/crates/ra_assists/src/handlers/merge_match_arms.rs b/crates/ra_assists/src/handlers/merge_match_arms.rs index 670614dd8..b2a194cb5 100644 --- a/crates/ra_assists/src/handlers/merge_match_arms.rs +++ b/crates/ra_assists/src/handlers/merge_match_arms.rs | |||
@@ -75,7 +75,7 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> { | |||
75 | } else { | 75 | } else { |
76 | arms_to_merge | 76 | arms_to_merge |
77 | .iter() | 77 | .iter() |
78 | .flat_map(ast::MatchArm::pats) | 78 | .filter_map(ast::MatchArm::pat) |
79 | .map(|x| x.syntax().to_string()) | 79 | .map(|x| x.syntax().to_string()) |
80 | .collect::<Vec<String>>() | 80 | .collect::<Vec<String>>() |
81 | .join(" | ") | 81 | .join(" | ") |
@@ -96,10 +96,10 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx) -> Option<Assist> { | |||
96 | } | 96 | } |
97 | 97 | ||
98 | fn contains_placeholder(a: &ast::MatchArm) -> bool { | 98 | fn contains_placeholder(a: &ast::MatchArm) -> bool { |
99 | a.pats().any(|x| match x { | 99 | match a.pat() { |
100 | ra_syntax::ast::Pat::PlaceholderPat(..) => true, | 100 | Some(ra_syntax::ast::Pat::PlaceholderPat(..)) => true, |
101 | _ => false, | 101 | _ => false, |
102 | }) | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | fn next_arm(arm: &ast::MatchArm) -> Option<ast::MatchArm> { | 105 | fn next_arm(arm: &ast::MatchArm) -> Option<ast::MatchArm> { |
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs index 2b91ce7c4..a61a2ba3e 100644 --- a/crates/ra_assists/src/handlers/move_guard.rs +++ b/crates/ra_assists/src/handlers/move_guard.rs | |||
@@ -90,7 +90,7 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx) -> Option<Assist> { | |||
90 | // ``` | 90 | // ``` |
91 | pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> { | 91 | pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> { |
92 | let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?; | 92 | let match_arm: MatchArm = ctx.find_node_at_offset::<MatchArm>()?; |
93 | let last_match_pat = match_arm.pats().last()?; | 93 | let match_pat = match_arm.pat()?; |
94 | 94 | ||
95 | let arm_body = match_arm.expr()?; | 95 | let arm_body = match_arm.expr()?; |
96 | let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone())?; | 96 | 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> { | |||
122 | _ => edit.replace(if_expr.syntax().text_range(), then_block.syntax().text()), | 122 | _ => edit.replace(if_expr.syntax().text_range(), then_block.syntax().text()), |
123 | } | 123 | } |
124 | 124 | ||
125 | edit.insert(last_match_pat.syntax().text_range().end(), buf); | 125 | edit.insert(match_pat.syntax().text_range().end(), buf); |
126 | edit.set_cursor(last_match_pat.syntax().text_range().end() + TextUnit::from(1)); | 126 | edit.set_cursor(match_pat.syntax().text_range().end() + TextUnit::from(1)); |
127 | }, | 127 | }, |
128 | ) | 128 | ) |
129 | } | 129 | } |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e656f9a41..fe0973fc7 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -164,9 +164,9 @@ where | |||
164 | let match_expr = self.collect_expr_opt(condition.expr()); | 164 | let match_expr = self.collect_expr_opt(condition.expr()); |
165 | let placeholder_pat = self.missing_pat(); | 165 | let placeholder_pat = self.missing_pat(); |
166 | let arms = vec![ | 166 | let arms = vec![ |
167 | MatchArm { pats: vec![pat], expr: then_branch, guard: None }, | 167 | MatchArm { pat, expr: then_branch, guard: None }, |
168 | MatchArm { | 168 | MatchArm { |
169 | pats: vec![placeholder_pat], | 169 | pat: placeholder_pat, |
170 | expr: else_branch.unwrap_or_else(|| self.empty_block()), | 170 | expr: else_branch.unwrap_or_else(|| self.empty_block()), |
171 | guard: None, | 171 | guard: None, |
172 | }, | 172 | }, |
@@ -203,8 +203,8 @@ where | |||
203 | let placeholder_pat = self.missing_pat(); | 203 | let placeholder_pat = self.missing_pat(); |
204 | let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); | 204 | let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); |
205 | let arms = vec![ | 205 | let arms = vec![ |
206 | MatchArm { pats: vec![pat], expr: body, guard: None }, | 206 | MatchArm { pat, expr: body, guard: None }, |
207 | MatchArm { pats: vec![placeholder_pat], expr: break_, guard: None }, | 207 | MatchArm { pat: placeholder_pat, expr: break_, guard: None }, |
208 | ]; | 208 | ]; |
209 | let match_expr = | 209 | let match_expr = |
210 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); | 210 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); |
@@ -250,7 +250,7 @@ where | |||
250 | match_arm_list | 250 | match_arm_list |
251 | .arms() | 251 | .arms() |
252 | .map(|arm| MatchArm { | 252 | .map(|arm| MatchArm { |
253 | pats: arm.pats().map(|p| self.collect_pat(p)).collect(), | 253 | pat: self.collect_pat_opt(arm.pat()), |
254 | expr: self.collect_expr_opt(arm.expr()), | 254 | expr: self.collect_expr_opt(arm.expr()), |
255 | guard: arm | 255 | guard: arm |
256 | .guard() | 256 | .guard() |
@@ -587,6 +587,11 @@ where | |||
587 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 587 | let path = p.path().and_then(|path| self.expander.parse_path(path)); |
588 | path.map(Pat::Path).unwrap_or(Pat::Missing) | 588 | path.map(Pat::Path).unwrap_or(Pat::Missing) |
589 | } | 589 | } |
590 | ast::Pat::OrPat(p) => { | ||
591 | let pats = p.pats().map(|p| self.collect_pat(p)).collect(); | ||
592 | Pat::Or(pats) | ||
593 | } | ||
594 | ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()), | ||
590 | ast::Pat::TuplePat(p) => { | 595 | ast::Pat::TuplePat(p) => { |
591 | let args = p.args().map(|p| self.collect_pat(p)).collect(); | 596 | let args = p.args().map(|p| self.collect_pat(p)).collect(); |
592 | Pat::Tuple(args) | 597 | Pat::Tuple(args) |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 5d0279945..a58a7b21f 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -158,9 +158,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope | |||
158 | compute_expr_scopes(*expr, body, scopes, scope); | 158 | compute_expr_scopes(*expr, body, scopes, scope); |
159 | for arm in arms { | 159 | for arm in arms { |
160 | let scope = scopes.new_scope(scope); | 160 | let scope = scopes.new_scope(scope); |
161 | for pat in &arm.pats { | 161 | scopes.add_bindings(body, scope, arm.pat); |
162 | scopes.add_bindings(body, scope, *pat); | ||
163 | } | ||
164 | scopes.set_scope(arm.expr, scope); | 162 | scopes.set_scope(arm.expr, scope); |
165 | compute_expr_scopes(arm.expr, body, scopes, scope); | 163 | compute_expr_scopes(arm.expr, body, scopes, scope); |
166 | } | 164 | } |
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index a75ef9970..5a84e08ed 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs | |||
@@ -202,7 +202,7 @@ pub enum Array { | |||
202 | 202 | ||
203 | #[derive(Debug, Clone, Eq, PartialEq)] | 203 | #[derive(Debug, Clone, Eq, PartialEq)] |
204 | pub struct MatchArm { | 204 | pub struct MatchArm { |
205 | pub pats: Vec<PatId>, | 205 | pub pat: PatId, |
206 | pub guard: Option<ExprId>, | 206 | pub guard: Option<ExprId>, |
207 | pub expr: ExprId, | 207 | pub expr: ExprId, |
208 | } | 208 | } |
@@ -382,6 +382,7 @@ pub enum Pat { | |||
382 | Missing, | 382 | Missing, |
383 | Wild, | 383 | Wild, |
384 | Tuple(Vec<PatId>), | 384 | Tuple(Vec<PatId>), |
385 | Or(Vec<PatId>), | ||
385 | Record { | 386 | Record { |
386 | path: Option<Path>, | 387 | path: Option<Path>, |
387 | args: Vec<RecordFieldPat>, | 388 | args: Vec<RecordFieldPat>, |
@@ -420,7 +421,7 @@ impl Pat { | |||
420 | Pat::Bind { subpat, .. } => { | 421 | Pat::Bind { subpat, .. } => { |
421 | subpat.iter().copied().for_each(f); | 422 | subpat.iter().copied().for_each(f); |
422 | } | 423 | } |
423 | Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { | 424 | Pat::Or(args) | Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { |
424 | args.iter().copied().for_each(f); | 425 | args.iter().copied().for_each(f); |
425 | } | 426 | } |
426 | Pat::Ref { pat, .. } => f(*pat), | 427 | Pat::Ref { pat, .. } => f(*pat), |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 3c9c02d03..186857b8b 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -168,9 +168,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
168 | let mut result_ty = self.table.new_maybe_never_type_var(); | 168 | let mut result_ty = self.table.new_maybe_never_type_var(); |
169 | 169 | ||
170 | for arm in arms { | 170 | for arm in arms { |
171 | for &pat in &arm.pats { | 171 | let _pat_ty = self.infer_pat(arm.pat, &input_ty, BindingMode::default()); |
172 | let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default()); | ||
173 | } | ||
174 | if let Some(guard_expr) = arm.guard { | 172 | if let Some(guard_expr) = arm.guard { |
175 | self.infer_expr( | 173 | self.infer_expr( |
176 | guard_expr, | 174 | guard_expr, |
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index e7283f24c..a5dfdf6c4 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -82,6 +82,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
82 | 82 | ||
83 | let is_non_ref_pat = match &body[pat] { | 83 | let is_non_ref_pat = match &body[pat] { |
84 | Pat::Tuple(..) | 84 | Pat::Tuple(..) |
85 | | Pat::Or(..) | ||
85 | | Pat::TupleStruct { .. } | 86 | | Pat::TupleStruct { .. } |
86 | | Pat::Record { .. } | 87 | | Pat::Record { .. } |
87 | | Pat::Range { .. } | 88 | | Pat::Range { .. } |
@@ -126,6 +127,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
126 | 127 | ||
127 | Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys)) | 128 | Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys)) |
128 | } | 129 | } |
130 | Pat::Or(ref pats) => { | ||
131 | if let Some((first_pat, rest)) = pats.split_first() { | ||
132 | let ty = self.infer_pat(*first_pat, expected, default_bm); | ||
133 | for pat in rest { | ||
134 | self.infer_pat(*pat, expected, default_bm); | ||
135 | } | ||
136 | ty | ||
137 | } else { | ||
138 | Ty::Unknown | ||
139 | } | ||
140 | } | ||
129 | Pat::Ref { pat, mutability } => { | 141 | Pat::Ref { pat, mutability } => { |
130 | let expectation = match expected.as_reference() { | 142 | let expectation = match expected.as_reference() { |
131 | Some((inner_ty, exp_mut)) => { | 143 | Some((inner_ty, exp_mut)) => { |
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 6b0d3d996..2ae97e65f 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -80,8 +80,7 @@ fn get_inlay_hints( | |||
80 | }, | 80 | }, |
81 | ast::MatchArmList(it) => { | 81 | ast::MatchArmList(it) => { |
82 | it.arms() | 82 | it.arms() |
83 | .map(|match_arm| match_arm.pats()) | 83 | .filter_map(|match_arm| match_arm.pat()) |
84 | .flatten() | ||
85 | .for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length)); | 84 | .for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length)); |
86 | }, | 85 | }, |
87 | ast::CallExpr(it) => { | 86 | ast::CallExpr(it) => { |
@@ -202,6 +201,7 @@ fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> { | |||
202 | Some(pat) => pats_to_process.push_back(pat), | 201 | Some(pat) => pats_to_process.push_back(pat), |
203 | _ => leaf_pats.push(maybe_leaf_pat), | 202 | _ => leaf_pats.push(maybe_leaf_pat), |
204 | }, | 203 | }, |
204 | ast::Pat::OrPat(ref_pat) => pats_to_process.extend(ref_pat.pats()), | ||
205 | ast::Pat::TuplePat(tuple_pat) => pats_to_process.extend(tuple_pat.args()), | 205 | ast::Pat::TuplePat(tuple_pat) => pats_to_process.extend(tuple_pat.args()), |
206 | ast::Pat::RecordPat(record_pat) => { | 206 | ast::Pat::RecordPat(record_pat) => { |
207 | if let Some(pat_list) = record_pat.record_field_pat_list() { | 207 | 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> { | |||
222 | ast::Pat::TupleStructPat(tuple_struct_pat) => { | 222 | ast::Pat::TupleStructPat(tuple_struct_pat) => { |
223 | pats_to_process.extend(tuple_struct_pat.args()) | 223 | pats_to_process.extend(tuple_struct_pat.args()) |
224 | } | 224 | } |
225 | ast::Pat::ParenPat(inner_pat) => pats_to_process.extend(inner_pat.pat()), | ||
225 | ast::Pat::RefPat(ref_pat) => pats_to_process.extend(ref_pat.pat()), | 226 | ast::Pat::RefPat(ref_pat) => pats_to_process.extend(ref_pat.pat()), |
226 | _ => (), | 227 | _ => (), |
227 | } | 228 | } |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index f154077a8..b72d2e9e6 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -336,7 +336,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | |||
336 | fn cond(p: &mut Parser) { | 336 | fn cond(p: &mut Parser) { |
337 | let m = p.start(); | 337 | let m = p.start(); |
338 | if p.eat(T![let]) { | 338 | if p.eat(T![let]) { |
339 | patterns::pattern_list(p); | 339 | patterns::pattern_top(p); |
340 | p.expect(T![=]); | 340 | p.expect(T![=]); |
341 | } | 341 | } |
342 | expr_no_struct(p); | 342 | expr_no_struct(p); |
@@ -430,7 +430,7 @@ fn match_arm(p: &mut Parser) -> BlockLike { | |||
430 | // } | 430 | // } |
431 | attributes::outer_attributes(p); | 431 | attributes::outer_attributes(p); |
432 | 432 | ||
433 | patterns::pattern_list_r(p, TokenSet::EMPTY); | 433 | patterns::pattern_top_r(p, TokenSet::EMPTY); |
434 | if p.at(T![if]) { | 434 | if p.at(T![if]) { |
435 | match_guard(p); | 435 | match_guard(p); |
436 | } | 436 | } |
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index 94edc7f35..ed4f93347 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs | |||
@@ -116,7 +116,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
116 | // type Qux = fn(baz: Bar::Baz); | 116 | // type Qux = fn(baz: Bar::Baz); |
117 | Flavor::FnPointer => { | 117 | Flavor::FnPointer => { |
118 | if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { | 118 | if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { |
119 | patterns::pattern(p); | 119 | patterns::pattern_single(p); |
120 | types::ascription(p); | 120 | types::ascription(p); |
121 | } else { | 121 | } else { |
122 | types::type_(p); | 122 | types::type_(p); |
@@ -127,7 +127,7 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
127 | // let foo = |bar, baz: Baz, qux: Qux::Quux| (); | 127 | // let foo = |bar, baz: Baz, qux: Qux::Quux| (); |
128 | // } | 128 | // } |
129 | Flavor::Closure => { | 129 | Flavor::Closure => { |
130 | patterns::pattern(p); | 130 | patterns::pattern_single(p); |
131 | if p.at(T![:]) && !p.at(T![::]) { | 131 | if p.at(T![:]) && !p.at(T![::]) { |
132 | types::ascription(p); | 132 | types::ascription(p); |
133 | } | 133 | } |
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 422a4e3dc..3afbaa82b 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -11,22 +11,47 @@ pub(crate) fn pattern(p: &mut Parser) { | |||
11 | } | 11 | } |
12 | 12 | ||
13 | /// Parses a pattern list separated by pipes `|` | 13 | /// Parses a pattern list separated by pipes `|` |
14 | pub(super) fn pattern_list(p: &mut Parser) { | 14 | pub(super) fn pattern_top(p: &mut Parser) { |
15 | pattern_list_r(p, PAT_RECOVERY_SET) | 15 | pattern_top_r(p, PAT_RECOVERY_SET) |
16 | } | ||
17 | |||
18 | pub(crate) fn pattern_single(p: &mut Parser) { | ||
19 | pattern_single_r(p, PAT_RECOVERY_SET); | ||
16 | } | 20 | } |
17 | 21 | ||
18 | /// Parses a pattern list separated by pipes `|` | 22 | /// Parses a pattern list separated by pipes `|` |
19 | /// using the given `recovery_set` | 23 | /// using the given `recovery_set` |
20 | pub(super) fn pattern_list_r(p: &mut Parser, recovery_set: TokenSet) { | 24 | pub(super) fn pattern_top_r(p: &mut Parser, recovery_set: TokenSet) { |
21 | p.eat(T![|]); | 25 | p.eat(T![|]); |
22 | pattern_r(p, recovery_set); | 26 | pattern_r(p, recovery_set); |
27 | } | ||
23 | 28 | ||
29 | /// Parses a pattern list separated by pipes `|`, with no leading `|`,using the | ||
30 | /// given `recovery_set` | ||
31 | // test or_pattern | ||
32 | // fn main() { | ||
33 | // match () { | ||
34 | // (_ | _) => (), | ||
35 | // &(_ | _) => (), | ||
36 | // (_ | _,) => (), | ||
37 | // [_ | _,] => (), | ||
38 | // } | ||
39 | // } | ||
40 | fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { | ||
41 | let m = p.start(); | ||
42 | pattern_single_r(p, recovery_set); | ||
43 | |||
44 | if !p.at(T![|]) { | ||
45 | m.abandon(p); | ||
46 | return; | ||
47 | } | ||
24 | while p.eat(T![|]) { | 48 | while p.eat(T![|]) { |
25 | pattern_r(p, recovery_set); | 49 | pattern_single_r(p, recovery_set); |
26 | } | 50 | } |
51 | m.complete(p, OR_PAT); | ||
27 | } | 52 | } |
28 | 53 | ||
29 | pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { | 54 | fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) { |
30 | if let Some(lhs) = atom_pat(p, recovery_set) { | 55 | if let Some(lhs) = atom_pat(p, recovery_set) { |
31 | // test range_pat | 56 | // test range_pat |
32 | // fn main() { | 57 | // fn main() { |
@@ -258,19 +283,41 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker { | |||
258 | let m = p.start(); | 283 | let m = p.start(); |
259 | p.bump(T![&]); | 284 | p.bump(T![&]); |
260 | p.eat(T![mut]); | 285 | p.eat(T![mut]); |
261 | pattern(p); | 286 | pattern_single(p); |
262 | m.complete(p, REF_PAT) | 287 | m.complete(p, REF_PAT) |
263 | } | 288 | } |
264 | 289 | ||
265 | // test tuple_pat | 290 | // test tuple_pat |
266 | // fn main() { | 291 | // fn main() { |
267 | // let (a, b, ..) = (); | 292 | // let (a, b, ..) = (); |
293 | // let (a,) = (); | ||
294 | // let (..) = (); | ||
295 | // let () = (); | ||
268 | // } | 296 | // } |
269 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { | 297 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { |
270 | assert!(p.at(T!['('])); | 298 | assert!(p.at(T!['('])); |
271 | let m = p.start(); | 299 | let m = p.start(); |
272 | tuple_pat_fields(p); | 300 | p.bump(T!['(']); |
273 | m.complete(p, TUPLE_PAT) | 301 | let mut has_comma = false; |
302 | let mut has_pat = false; | ||
303 | let mut has_rest = false; | ||
304 | while !p.at(EOF) && !p.at(T![')']) { | ||
305 | has_pat = true; | ||
306 | if !p.at_ts(PATTERN_FIRST) { | ||
307 | p.error("expected a pattern"); | ||
308 | break; | ||
309 | } | ||
310 | has_rest |= p.at(T![..]); | ||
311 | |||
312 | pattern(p); | ||
313 | if !p.at(T![')']) { | ||
314 | has_comma = true; | ||
315 | p.expect(T![,]); | ||
316 | } | ||
317 | } | ||
318 | p.expect(T![')']); | ||
319 | |||
320 | m.complete(p, if !has_comma && !has_rest && has_pat { PAREN_PAT } else { TUPLE_PAT }) | ||
274 | } | 321 | } |
275 | 322 | ||
276 | // test slice_pat | 323 | // test slice_pat |
@@ -315,7 +362,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { | |||
315 | p.eat(T![mut]); | 362 | p.eat(T![mut]); |
316 | name(p); | 363 | name(p); |
317 | if with_at && p.eat(T![@]) { | 364 | if with_at && p.eat(T![@]) { |
318 | pattern(p); | 365 | pattern_single(p); |
319 | } | 366 | } |
320 | m.complete(p, BIND_PAT) | 367 | m.complete(p, BIND_PAT) |
321 | } | 368 | } |
@@ -330,6 +377,6 @@ fn box_pat(p: &mut Parser) -> CompletedMarker { | |||
330 | assert!(p.at(T![box])); | 377 | assert!(p.at(T![box])); |
331 | let m = p.start(); | 378 | let m = p.start(); |
332 | p.bump(T![box]); | 379 | p.bump(T![box]); |
333 | pattern(p); | 380 | pattern_single(p); |
334 | m.complete(p, BOX_PAT) | 381 | m.complete(p, BOX_PAT) |
335 | } | 382 | } |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index e27b27ffa..1068da0a0 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -151,6 +151,8 @@ pub enum SyntaxKind { | |||
151 | FOR_TYPE, | 151 | FOR_TYPE, |
152 | IMPL_TRAIT_TYPE, | 152 | IMPL_TRAIT_TYPE, |
153 | DYN_TRAIT_TYPE, | 153 | DYN_TRAIT_TYPE, |
154 | OR_PAT, | ||
155 | PAREN_PAT, | ||
154 | REF_PAT, | 156 | REF_PAT, |
155 | BOX_PAT, | 157 | BOX_PAT, |
156 | BIND_PAT, | 158 | BIND_PAT, |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 435135f92..8d640642d 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1759,8 +1759,8 @@ impl AstNode for MatchArm { | |||
1759 | } | 1759 | } |
1760 | impl ast::AttrsOwner for MatchArm {} | 1760 | impl ast::AttrsOwner for MatchArm {} |
1761 | impl MatchArm { | 1761 | impl MatchArm { |
1762 | pub fn pats(&self) -> AstChildren<Pat> { | 1762 | pub fn pat(&self) -> Option<Pat> { |
1763 | AstChildren::new(&self.syntax) | 1763 | AstChildren::new(&self.syntax).next() |
1764 | } | 1764 | } |
1765 | pub fn guard(&self) -> Option<MatchGuard> { | 1765 | pub fn guard(&self) -> Option<MatchGuard> { |
1766 | AstChildren::new(&self.syntax).next() | 1766 | AstChildren::new(&self.syntax).next() |
@@ -1887,6 +1887,60 @@ impl RecordField { | |||
1887 | } | 1887 | } |
1888 | } | 1888 | } |
1889 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1889 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1890 | pub struct OrPat { | ||
1891 | pub(crate) syntax: SyntaxNode, | ||
1892 | } | ||
1893 | impl AstNode for OrPat { | ||
1894 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1895 | match kind { | ||
1896 | OR_PAT => true, | ||
1897 | _ => false, | ||
1898 | } | ||
1899 | } | ||
1900 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1901 | if Self::can_cast(syntax.kind()) { | ||
1902 | Some(Self { syntax }) | ||
1903 | } else { | ||
1904 | None | ||
1905 | } | ||
1906 | } | ||
1907 | fn syntax(&self) -> &SyntaxNode { | ||
1908 | &self.syntax | ||
1909 | } | ||
1910 | } | ||
1911 | impl OrPat { | ||
1912 | pub fn pats(&self) -> AstChildren<Pat> { | ||
1913 | AstChildren::new(&self.syntax) | ||
1914 | } | ||
1915 | } | ||
1916 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1917 | pub struct ParenPat { | ||
1918 | pub(crate) syntax: SyntaxNode, | ||
1919 | } | ||
1920 | impl AstNode for ParenPat { | ||
1921 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1922 | match kind { | ||
1923 | PAREN_PAT => true, | ||
1924 | _ => false, | ||
1925 | } | ||
1926 | } | ||
1927 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1928 | if Self::can_cast(syntax.kind()) { | ||
1929 | Some(Self { syntax }) | ||
1930 | } else { | ||
1931 | None | ||
1932 | } | ||
1933 | } | ||
1934 | fn syntax(&self) -> &SyntaxNode { | ||
1935 | &self.syntax | ||
1936 | } | ||
1937 | } | ||
1938 | impl ParenPat { | ||
1939 | pub fn pat(&self) -> Option<Pat> { | ||
1940 | AstChildren::new(&self.syntax).next() | ||
1941 | } | ||
1942 | } | ||
1943 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1890 | pub struct RefPat { | 1944 | pub struct RefPat { |
1891 | pub(crate) syntax: SyntaxNode, | 1945 | pub(crate) syntax: SyntaxNode, |
1892 | } | 1946 | } |
@@ -3900,6 +3954,8 @@ impl AstNode for Expr { | |||
3900 | } | 3954 | } |
3901 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3955 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3902 | pub enum Pat { | 3956 | pub enum Pat { |
3957 | OrPat(OrPat), | ||
3958 | ParenPat(ParenPat), | ||
3903 | RefPat(RefPat), | 3959 | RefPat(RefPat), |
3904 | BoxPat(BoxPat), | 3960 | BoxPat(BoxPat), |
3905 | BindPat(BindPat), | 3961 | BindPat(BindPat), |
@@ -3913,6 +3969,16 @@ pub enum Pat { | |||
3913 | RangePat(RangePat), | 3969 | RangePat(RangePat), |
3914 | LiteralPat(LiteralPat), | 3970 | LiteralPat(LiteralPat), |
3915 | } | 3971 | } |
3972 | impl From<OrPat> for Pat { | ||
3973 | fn from(node: OrPat) -> Pat { | ||
3974 | Pat::OrPat(node) | ||
3975 | } | ||
3976 | } | ||
3977 | impl From<ParenPat> for Pat { | ||
3978 | fn from(node: ParenPat) -> Pat { | ||
3979 | Pat::ParenPat(node) | ||
3980 | } | ||
3981 | } | ||
3916 | impl From<RefPat> for Pat { | 3982 | impl From<RefPat> for Pat { |
3917 | fn from(node: RefPat) -> Pat { | 3983 | fn from(node: RefPat) -> Pat { |
3918 | Pat::RefPat(node) | 3984 | Pat::RefPat(node) |
@@ -3976,15 +4042,16 @@ impl From<LiteralPat> for Pat { | |||
3976 | impl AstNode for Pat { | 4042 | impl AstNode for Pat { |
3977 | fn can_cast(kind: SyntaxKind) -> bool { | 4043 | fn can_cast(kind: SyntaxKind) -> bool { |
3978 | match kind { | 4044 | match kind { |
3979 | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT | 4045 | OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT |
3980 | | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => { | 4046 | | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT |
3981 | true | 4047 | | LITERAL_PAT => true, |
3982 | } | ||
3983 | _ => false, | 4048 | _ => false, |
3984 | } | 4049 | } |
3985 | } | 4050 | } |
3986 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 4051 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
3987 | let res = match syntax.kind() { | 4052 | let res = match syntax.kind() { |
4053 | OR_PAT => Pat::OrPat(OrPat { syntax }), | ||
4054 | PAREN_PAT => Pat::ParenPat(ParenPat { syntax }), | ||
3988 | REF_PAT => Pat::RefPat(RefPat { syntax }), | 4055 | REF_PAT => Pat::RefPat(RefPat { syntax }), |
3989 | BOX_PAT => Pat::BoxPat(BoxPat { syntax }), | 4056 | BOX_PAT => Pat::BoxPat(BoxPat { syntax }), |
3990 | BIND_PAT => Pat::BindPat(BindPat { syntax }), | 4057 | BIND_PAT => Pat::BindPat(BindPat { syntax }), |
@@ -4003,6 +4070,8 @@ impl AstNode for Pat { | |||
4003 | } | 4070 | } |
4004 | fn syntax(&self) -> &SyntaxNode { | 4071 | fn syntax(&self) -> &SyntaxNode { |
4005 | match self { | 4072 | match self { |
4073 | Pat::OrPat(it) => &it.syntax, | ||
4074 | Pat::ParenPat(it) => &it.syntax, | ||
4006 | Pat::RefPat(it) => &it.syntax, | 4075 | Pat::RefPat(it) => &it.syntax, |
4007 | Pat::BoxPat(it) => &it.syntax, | 4076 | Pat::BoxPat(it) => &it.syntax, |
4008 | Pat::BindPat(it) => &it.syntax, | 4077 | Pat::BindPat(it) => &it.syntax, |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt b/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt index 4028ca243..6fd49c7bc 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0030_cond.txt | |||
@@ -63,27 +63,28 @@ SOURCE_FILE@[0; 197) | |||
63 | CONDITION@[56; 84) | 63 | CONDITION@[56; 84) |
64 | LET_KW@[56; 59) "let" | 64 | LET_KW@[56; 59) "let" |
65 | WHITESPACE@[59; 60) " " | 65 | WHITESPACE@[59; 60) " " |
66 | TUPLE_STRUCT_PAT@[60; 67) | 66 | OR_PAT@[60; 77) |
67 | PATH@[60; 64) | 67 | TUPLE_STRUCT_PAT@[60; 67) |
68 | PATH_SEGMENT@[60; 64) | 68 | PATH@[60; 64) |
69 | NAME_REF@[60; 64) | 69 | PATH_SEGMENT@[60; 64) |
70 | IDENT@[60; 64) "Some" | 70 | NAME_REF@[60; 64) |
71 | L_PAREN@[64; 65) "(" | 71 | IDENT@[60; 64) "Some" |
72 | PLACEHOLDER_PAT@[65; 66) | 72 | L_PAREN@[64; 65) "(" |
73 | UNDERSCORE@[65; 66) "_" | 73 | PLACEHOLDER_PAT@[65; 66) |
74 | R_PAREN@[66; 67) ")" | 74 | UNDERSCORE@[65; 66) "_" |
75 | WHITESPACE@[67; 68) " " | 75 | R_PAREN@[66; 67) ")" |
76 | PIPE@[68; 69) "|" | 76 | WHITESPACE@[67; 68) " " |
77 | WHITESPACE@[69; 70) " " | 77 | PIPE@[68; 69) "|" |
78 | TUPLE_STRUCT_PAT@[70; 77) | 78 | WHITESPACE@[69; 70) " " |
79 | PATH@[70; 74) | 79 | TUPLE_STRUCT_PAT@[70; 77) |
80 | PATH_SEGMENT@[70; 74) | 80 | PATH@[70; 74) |
81 | NAME_REF@[70; 74) | 81 | PATH_SEGMENT@[70; 74) |
82 | IDENT@[70; 74) "Some" | 82 | NAME_REF@[70; 74) |
83 | L_PAREN@[74; 75) "(" | 83 | IDENT@[70; 74) "Some" |
84 | PLACEHOLDER_PAT@[75; 76) | 84 | L_PAREN@[74; 75) "(" |
85 | UNDERSCORE@[75; 76) "_" | 85 | PLACEHOLDER_PAT@[75; 76) |
86 | R_PAREN@[76; 77) ")" | 86 | UNDERSCORE@[75; 76) "_" |
87 | R_PAREN@[76; 77) ")" | ||
87 | WHITESPACE@[77; 78) " " | 88 | WHITESPACE@[77; 78) " " |
88 | EQ@[78; 79) "=" | 89 | EQ@[78; 79) "=" |
89 | WHITESPACE@[79; 80) " " | 90 | WHITESPACE@[79; 80) " " |
@@ -137,27 +138,28 @@ SOURCE_FILE@[0; 197) | |||
137 | CONDITION@[129; 157) | 138 | CONDITION@[129; 157) |
138 | LET_KW@[129; 132) "let" | 139 | LET_KW@[129; 132) "let" |
139 | WHITESPACE@[132; 133) " " | 140 | WHITESPACE@[132; 133) " " |
140 | TUPLE_STRUCT_PAT@[133; 140) | 141 | OR_PAT@[133; 150) |
141 | PATH@[133; 137) | 142 | TUPLE_STRUCT_PAT@[133; 140) |
142 | PATH_SEGMENT@[133; 137) | 143 | PATH@[133; 137) |
143 | NAME_REF@[133; 137) | 144 | PATH_SEGMENT@[133; 137) |
144 | IDENT@[133; 137) "Some" | 145 | NAME_REF@[133; 137) |
145 | L_PAREN@[137; 138) "(" | 146 | IDENT@[133; 137) "Some" |
146 | PLACEHOLDER_PAT@[138; 139) | 147 | L_PAREN@[137; 138) "(" |
147 | UNDERSCORE@[138; 139) "_" | 148 | PLACEHOLDER_PAT@[138; 139) |
148 | R_PAREN@[139; 140) ")" | 149 | UNDERSCORE@[138; 139) "_" |
149 | WHITESPACE@[140; 141) " " | 150 | R_PAREN@[139; 140) ")" |
150 | PIPE@[141; 142) "|" | 151 | WHITESPACE@[140; 141) " " |
151 | WHITESPACE@[142; 143) " " | 152 | PIPE@[141; 142) "|" |
152 | TUPLE_STRUCT_PAT@[143; 150) | 153 | WHITESPACE@[142; 143) " " |
153 | PATH@[143; 147) | 154 | TUPLE_STRUCT_PAT@[143; 150) |
154 | PATH_SEGMENT@[143; 147) | 155 | PATH@[143; 147) |
155 | NAME_REF@[143; 147) | 156 | PATH_SEGMENT@[143; 147) |
156 | IDENT@[143; 147) "Some" | 157 | NAME_REF@[143; 147) |
157 | L_PAREN@[147; 148) "(" | 158 | IDENT@[143; 147) "Some" |
158 | PLACEHOLDER_PAT@[148; 149) | 159 | L_PAREN@[147; 148) "(" |
159 | UNDERSCORE@[148; 149) "_" | 160 | PLACEHOLDER_PAT@[148; 149) |
160 | R_PAREN@[149; 150) ")" | 161 | UNDERSCORE@[148; 149) "_" |
162 | R_PAREN@[149; 150) ")" | ||
161 | WHITESPACE@[150; 151) " " | 163 | WHITESPACE@[150; 151) " " |
162 | EQ@[151; 152) "=" | 164 | EQ@[151; 152) "=" |
163 | WHITESPACE@[152; 153) " " | 165 | WHITESPACE@[152; 153) " " |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt b/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt index 87272917b..2f07af4e1 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0066_match_arm.txt | |||
@@ -74,15 +74,16 @@ SOURCE_FILE@[0; 167) | |||
74 | COMMA@[83; 84) "," | 74 | COMMA@[83; 84) "," |
75 | WHITESPACE@[84; 93) "\n " | 75 | WHITESPACE@[84; 93) "\n " |
76 | MATCH_ARM@[93; 109) | 76 | MATCH_ARM@[93; 109) |
77 | BIND_PAT@[93; 94) | 77 | OR_PAT@[93; 98) |
78 | NAME@[93; 94) | 78 | BIND_PAT@[93; 94) |
79 | IDENT@[93; 94) "X" | 79 | NAME@[93; 94) |
80 | WHITESPACE@[94; 95) " " | 80 | IDENT@[93; 94) "X" |
81 | PIPE@[95; 96) "|" | 81 | WHITESPACE@[94; 95) " " |
82 | WHITESPACE@[96; 97) " " | 82 | PIPE@[95; 96) "|" |
83 | BIND_PAT@[97; 98) | 83 | WHITESPACE@[96; 97) " " |
84 | NAME@[97; 98) | 84 | BIND_PAT@[97; 98) |
85 | IDENT@[97; 98) "Y" | 85 | NAME@[97; 98) |
86 | IDENT@[97; 98) "Y" | ||
86 | WHITESPACE@[98; 99) " " | 87 | WHITESPACE@[98; 99) " " |
87 | MATCH_GUARD@[99; 103) | 88 | MATCH_GUARD@[99; 103) |
88 | IF_KW@[99; 101) "if" | 89 | IF_KW@[99; 101) "if" |
@@ -103,15 +104,16 @@ SOURCE_FILE@[0; 167) | |||
103 | MATCH_ARM@[119; 137) | 104 | MATCH_ARM@[119; 137) |
104 | PIPE@[119; 120) "|" | 105 | PIPE@[119; 120) "|" |
105 | WHITESPACE@[120; 121) " " | 106 | WHITESPACE@[120; 121) " " |
106 | BIND_PAT@[121; 122) | 107 | OR_PAT@[121; 126) |
107 | NAME@[121; 122) | 108 | BIND_PAT@[121; 122) |
108 | IDENT@[121; 122) "X" | 109 | NAME@[121; 122) |
109 | WHITESPACE@[122; 123) " " | 110 | IDENT@[121; 122) "X" |
110 | PIPE@[123; 124) "|" | 111 | WHITESPACE@[122; 123) " " |
111 | WHITESPACE@[124; 125) " " | 112 | PIPE@[123; 124) "|" |
112 | BIND_PAT@[125; 126) | 113 | WHITESPACE@[124; 125) " " |
113 | NAME@[125; 126) | 114 | BIND_PAT@[125; 126) |
114 | IDENT@[125; 126) "Y" | 115 | NAME@[125; 126) |
116 | IDENT@[125; 126) "Y" | ||
115 | WHITESPACE@[126; 127) " " | 117 | WHITESPACE@[126; 127) " " |
116 | MATCH_GUARD@[127; 131) | 118 | MATCH_GUARD@[127; 131) |
117 | IF_KW@[127; 129) "if" | 119 | IF_KW@[127; 129) "if" |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rs b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rs index f785acd36..ba719879d 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rs +++ b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.rs | |||
@@ -1,3 +1,6 @@ | |||
1 | fn main() { | 1 | fn main() { |
2 | let (a, b, ..) = (); | 2 | let (a, b, ..) = (); |
3 | let (a,) = (); | ||
4 | let (..) = (); | ||
5 | let () = (); | ||
3 | } | 6 | } |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt index 674dec493..4680c267e 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0111_tuple_pat.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 39) | 1 | SOURCE_FILE@[0; 94) |
2 | FN_DEF@[0; 38) | 2 | FN_DEF@[0; 93) |
3 | FN_KW@[0; 2) "fn" | 3 | FN_KW@[0; 2) "fn" |
4 | WHITESPACE@[2; 3) " " | 4 | WHITESPACE@[2; 3) " " |
5 | NAME@[3; 7) | 5 | NAME@[3; 7) |
@@ -8,8 +8,8 @@ SOURCE_FILE@[0; 39) | |||
8 | L_PAREN@[7; 8) "(" | 8 | L_PAREN@[7; 8) "(" |
9 | R_PAREN@[8; 9) ")" | 9 | R_PAREN@[8; 9) ")" |
10 | WHITESPACE@[9; 10) " " | 10 | WHITESPACE@[9; 10) " " |
11 | BLOCK_EXPR@[10; 38) | 11 | BLOCK_EXPR@[10; 93) |
12 | BLOCK@[10; 38) | 12 | BLOCK@[10; 93) |
13 | L_CURLY@[10; 11) "{" | 13 | L_CURLY@[10; 11) "{" |
14 | WHITESPACE@[11; 16) "\n " | 14 | WHITESPACE@[11; 16) "\n " |
15 | LET_STMT@[16; 36) | 15 | LET_STMT@[16; 36) |
@@ -37,6 +37,54 @@ SOURCE_FILE@[0; 39) | |||
37 | L_PAREN@[33; 34) "(" | 37 | L_PAREN@[33; 34) "(" |
38 | R_PAREN@[34; 35) ")" | 38 | R_PAREN@[34; 35) ")" |
39 | SEMI@[35; 36) ";" | 39 | SEMI@[35; 36) ";" |
40 | WHITESPACE@[36; 37) "\n" | 40 | WHITESPACE@[36; 41) "\n " |
41 | R_CURLY@[37; 38) "}" | 41 | LET_STMT@[41; 55) |
42 | WHITESPACE@[38; 39) "\n" | 42 | LET_KW@[41; 44) "let" |
43 | WHITESPACE@[44; 45) " " | ||
44 | TUPLE_PAT@[45; 49) | ||
45 | L_PAREN@[45; 46) "(" | ||
46 | BIND_PAT@[46; 47) | ||
47 | NAME@[46; 47) | ||
48 | IDENT@[46; 47) "a" | ||
49 | COMMA@[47; 48) "," | ||
50 | R_PAREN@[48; 49) ")" | ||
51 | WHITESPACE@[49; 50) " " | ||
52 | EQ@[50; 51) "=" | ||
53 | WHITESPACE@[51; 52) " " | ||
54 | TUPLE_EXPR@[52; 54) | ||
55 | L_PAREN@[52; 53) "(" | ||
56 | R_PAREN@[53; 54) ")" | ||
57 | SEMI@[54; 55) ";" | ||
58 | WHITESPACE@[55; 60) "\n " | ||
59 | LET_STMT@[60; 74) | ||
60 | LET_KW@[60; 63) "let" | ||
61 | WHITESPACE@[63; 64) " " | ||
62 | TUPLE_PAT@[64; 68) | ||
63 | L_PAREN@[64; 65) "(" | ||
64 | DOT_DOT_PAT@[65; 67) | ||
65 | DOTDOT@[65; 67) ".." | ||
66 | R_PAREN@[67; 68) ")" | ||
67 | WHITESPACE@[68; 69) " " | ||
68 | EQ@[69; 70) "=" | ||
69 | WHITESPACE@[70; 71) " " | ||
70 | TUPLE_EXPR@[71; 73) | ||
71 | L_PAREN@[71; 72) "(" | ||
72 | R_PAREN@[72; 73) ")" | ||
73 | SEMI@[73; 74) ";" | ||
74 | WHITESPACE@[74; 79) "\n " | ||
75 | LET_STMT@[79; 91) | ||
76 | LET_KW@[79; 82) "let" | ||
77 | WHITESPACE@[82; 83) " " | ||
78 | TUPLE_PAT@[83; 85) | ||
79 | L_PAREN@[83; 84) "(" | ||
80 | R_PAREN@[84; 85) ")" | ||
81 | WHITESPACE@[85; 86) " " | ||
82 | EQ@[86; 87) "=" | ||
83 | WHITESPACE@[87; 88) " " | ||
84 | TUPLE_EXPR@[88; 90) | ||
85 | L_PAREN@[88; 89) "(" | ||
86 | R_PAREN@[89; 90) ")" | ||
87 | SEMI@[90; 91) ";" | ||
88 | WHITESPACE@[91; 92) "\n" | ||
89 | R_CURLY@[92; 93) "}" | ||
90 | WHITESPACE@[93; 94) "\n" | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rs b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rs new file mode 100644 index 000000000..a26316605 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | fn main() { | ||
2 | match () { | ||
3 | (_ | _) => (), | ||
4 | &(_ | _) => (), | ||
5 | (_ | _,) => (), | ||
6 | [_ | _,] => (), | ||
7 | } | ||
8 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt new file mode 100644 index 000000000..3a196d3c0 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_or_pattern.txt | |||
@@ -0,0 +1,112 @@ | |||
1 | SOURCE_FILE@[0; 130) | ||
2 | FN_DEF@[0; 129) | ||
3 | FN_KW@[0; 2) "fn" | ||
4 | WHITESPACE@[2; 3) " " | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) "(" | ||
9 | R_PAREN@[8; 9) ")" | ||
10 | WHITESPACE@[9; 10) " " | ||
11 | BLOCK_EXPR@[10; 129) | ||
12 | BLOCK@[10; 129) | ||
13 | L_CURLY@[10; 11) "{" | ||
14 | WHITESPACE@[11; 16) "\n " | ||
15 | MATCH_EXPR@[16; 127) | ||
16 | MATCH_KW@[16; 21) "match" | ||
17 | WHITESPACE@[21; 22) " " | ||
18 | TUPLE_EXPR@[22; 24) | ||
19 | L_PAREN@[22; 23) "(" | ||
20 | R_PAREN@[23; 24) ")" | ||
21 | WHITESPACE@[24; 25) " " | ||
22 | MATCH_ARM_LIST@[25; 127) | ||
23 | L_CURLY@[25; 26) "{" | ||
24 | WHITESPACE@[26; 35) "\n " | ||
25 | MATCH_ARM@[35; 48) | ||
26 | PAREN_PAT@[35; 42) | ||
27 | L_PAREN@[35; 36) "(" | ||
28 | OR_PAT@[36; 41) | ||
29 | PLACEHOLDER_PAT@[36; 37) | ||
30 | UNDERSCORE@[36; 37) "_" | ||
31 | WHITESPACE@[37; 38) " " | ||
32 | PIPE@[38; 39) "|" | ||
33 | WHITESPACE@[39; 40) " " | ||
34 | PLACEHOLDER_PAT@[40; 41) | ||
35 | UNDERSCORE@[40; 41) "_" | ||
36 | R_PAREN@[41; 42) ")" | ||
37 | WHITESPACE@[42; 43) " " | ||
38 | FAT_ARROW@[43; 45) "=>" | ||
39 | WHITESPACE@[45; 46) " " | ||
40 | TUPLE_EXPR@[46; 48) | ||
41 | L_PAREN@[46; 47) "(" | ||
42 | R_PAREN@[47; 48) ")" | ||
43 | COMMA@[48; 49) "," | ||
44 | WHITESPACE@[49; 58) "\n " | ||
45 | MATCH_ARM@[58; 72) | ||
46 | REF_PAT@[58; 66) | ||
47 | AMP@[58; 59) "&" | ||
48 | PAREN_PAT@[59; 66) | ||
49 | L_PAREN@[59; 60) "(" | ||
50 | OR_PAT@[60; 65) | ||
51 | PLACEHOLDER_PAT@[60; 61) | ||
52 | UNDERSCORE@[60; 61) "_" | ||
53 | WHITESPACE@[61; 62) " " | ||
54 | PIPE@[62; 63) "|" | ||
55 | WHITESPACE@[63; 64) " " | ||
56 | PLACEHOLDER_PAT@[64; 65) | ||
57 | UNDERSCORE@[64; 65) "_" | ||
58 | R_PAREN@[65; 66) ")" | ||
59 | WHITESPACE@[66; 67) " " | ||
60 | FAT_ARROW@[67; 69) "=>" | ||
61 | WHITESPACE@[69; 70) " " | ||
62 | TUPLE_EXPR@[70; 72) | ||
63 | L_PAREN@[70; 71) "(" | ||
64 | R_PAREN@[71; 72) ")" | ||
65 | COMMA@[72; 73) "," | ||
66 | WHITESPACE@[73; 82) "\n " | ||
67 | MATCH_ARM@[82; 96) | ||
68 | TUPLE_PAT@[82; 90) | ||
69 | L_PAREN@[82; 83) "(" | ||
70 | OR_PAT@[83; 88) | ||
71 | PLACEHOLDER_PAT@[83; 84) | ||
72 | UNDERSCORE@[83; 84) "_" | ||
73 | WHITESPACE@[84; 85) " " | ||
74 | PIPE@[85; 86) "|" | ||
75 | WHITESPACE@[86; 87) " " | ||
76 | PLACEHOLDER_PAT@[87; 88) | ||
77 | UNDERSCORE@[87; 88) "_" | ||
78 | COMMA@[88; 89) "," | ||
79 | R_PAREN@[89; 90) ")" | ||
80 | WHITESPACE@[90; 91) " " | ||
81 | FAT_ARROW@[91; 93) "=>" | ||
82 | WHITESPACE@[93; 94) " " | ||
83 | TUPLE_EXPR@[94; 96) | ||
84 | L_PAREN@[94; 95) "(" | ||
85 | R_PAREN@[95; 96) ")" | ||
86 | COMMA@[96; 97) "," | ||
87 | WHITESPACE@[97; 106) "\n " | ||
88 | MATCH_ARM@[106; 120) | ||
89 | SLICE_PAT@[106; 114) | ||
90 | L_BRACK@[106; 107) "[" | ||
91 | OR_PAT@[107; 112) | ||
92 | PLACEHOLDER_PAT@[107; 108) | ||
93 | UNDERSCORE@[107; 108) "_" | ||
94 | WHITESPACE@[108; 109) " " | ||
95 | PIPE@[109; 110) "|" | ||
96 | WHITESPACE@[110; 111) " " | ||
97 | PLACEHOLDER_PAT@[111; 112) | ||
98 | UNDERSCORE@[111; 112) "_" | ||
99 | COMMA@[112; 113) "," | ||
100 | R_BRACK@[113; 114) "]" | ||
101 | WHITESPACE@[114; 115) " " | ||
102 | FAT_ARROW@[115; 117) "=>" | ||
103 | WHITESPACE@[117; 118) " " | ||
104 | TUPLE_EXPR@[118; 120) | ||
105 | L_PAREN@[118; 119) "(" | ||
106 | R_PAREN@[119; 120) ")" | ||
107 | COMMA@[120; 121) "," | ||
108 | WHITESPACE@[121; 126) "\n " | ||
109 | R_CURLY@[126; 127) "}" | ||
110 | WHITESPACE@[127; 128) "\n" | ||
111 | R_CURLY@[128; 129) "}" | ||
112 | WHITESPACE@[129; 130) "\n" | ||
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 67d1f41bc..3f530e489 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -120,6 +120,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { | |||
120 | "FOR_TYPE", | 120 | "FOR_TYPE", |
121 | "IMPL_TRAIT_TYPE", | 121 | "IMPL_TRAIT_TYPE", |
122 | "DYN_TRAIT_TYPE", | 122 | "DYN_TRAIT_TYPE", |
123 | "OR_PAT", | ||
124 | "PAREN_PAT", | ||
123 | "REF_PAT", | 125 | "REF_PAT", |
124 | "BOX_PAT", | 126 | "BOX_PAT", |
125 | "BIND_PAT", | 127 | "BIND_PAT", |
@@ -412,7 +414,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
412 | struct MatchExpr { Expr, MatchArmList } | 414 | struct MatchExpr { Expr, MatchArmList } |
413 | struct MatchArmList: AttrsOwner { arms: [MatchArm] } | 415 | struct MatchArmList: AttrsOwner { arms: [MatchArm] } |
414 | struct MatchArm: AttrsOwner { | 416 | struct MatchArm: AttrsOwner { |
415 | pats: [Pat], | 417 | pat: Pat, |
416 | guard: MatchGuard, | 418 | guard: MatchGuard, |
417 | Expr, | 419 | Expr, |
418 | } | 420 | } |
@@ -425,6 +427,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
425 | } | 427 | } |
426 | struct RecordField { NameRef, Expr } | 428 | struct RecordField { NameRef, Expr } |
427 | 429 | ||
430 | struct OrPat { pats: [Pat] } | ||
431 | struct ParenPat { Pat } | ||
428 | struct RefPat { Pat } | 432 | struct RefPat { Pat } |
429 | struct BoxPat { Pat } | 433 | struct BoxPat { Pat } |
430 | struct BindPat: NameOwner { Pat } | 434 | struct BindPat: NameOwner { Pat } |
@@ -601,6 +605,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
601 | } | 605 | } |
602 | 606 | ||
603 | enum Pat { | 607 | enum Pat { |
608 | OrPat, | ||
609 | ParenPat, | ||
604 | RefPat, | 610 | RefPat, |
605 | BoxPat, | 611 | BoxPat, |
606 | BindPat, | 612 | BindPat, |