aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_hir_def/Cargo.toml1
-rw-r--r--crates/ra_hir_def/src/body/lower.rs16
-rw-r--r--crates/ra_hir_def/src/expr.rs6
-rw-r--r--crates/ra_syntax/src/ast.rs3
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs36
-rw-r--r--crates/ra_syntax/src/ast/generated.rs6
-rw-r--r--xtask/src/ast_src.rs8
8 files changed, 64 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 847653696..45804c087 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1070,6 +1070,7 @@ dependencies = [
1070 "drop_bomb", 1070 "drop_bomb",
1071 "either", 1071 "either",
1072 "insta", 1072 "insta",
1073 "itertools",
1073 "log", 1074 "log",
1074 "once_cell", 1075 "once_cell",
1075 "ra_arena", 1076 "ra_arena",
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 1efa00fe0..6b9be9948 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -14,6 +14,7 @@ rustc-hash = "1.0"
14either = "1.5" 14either = "1.5"
15anymap = "0.12" 15anymap = "0.12"
16drop_bomb = "0.1.4" 16drop_bomb = "0.1.4"
17itertools = "0.8.2"
17 18
18ra_arena = { path = "../ra_arena" } 19ra_arena = { path = "../ra_arena" }
19ra_db = { path = "../ra_db" } 20ra_db = { path = "../ra_db" }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index fe0973fc7..1fc892362 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -8,7 +8,7 @@ use ra_arena::Arena;
8use ra_syntax::{ 8use ra_syntax::{
9 ast::{ 9 ast::{
10 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, 10 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
11 TypeAscriptionOwner, 11 SlicePatComponents, TypeAscriptionOwner,
12 }, 12 },
13 AstNode, AstPtr, 13 AstNode, AstPtr,
14}; 14};
@@ -596,7 +596,7 @@ where
596 let args = p.args().map(|p| self.collect_pat(p)).collect(); 596 let args = p.args().map(|p| self.collect_pat(p)).collect();
597 Pat::Tuple(args) 597 Pat::Tuple(args)
598 } 598 }
599 ast::Pat::PlaceholderPat(_) => Pat::Wild, 599 ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild,
600 ast::Pat::RecordPat(p) => { 600 ast::Pat::RecordPat(p) => {
601 let path = p.path().and_then(|path| self.expander.parse_path(path)); 601 let path = p.path().and_then(|path| self.expander.parse_path(path));
602 let record_field_pat_list = 602 let record_field_pat_list =
@@ -621,12 +621,20 @@ where
621 621
622 Pat::Record { path, args: fields } 622 Pat::Record { path, args: fields }
623 } 623 }
624 ast::Pat::SlicePat(p) => {
625 let SlicePatComponents { prefix, slice, suffix } = p.components();
626
627 Pat::Slice {
628 prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(),
629 slice: slice.map(|p| self.collect_pat(p)),
630 suffix: suffix.into_iter().map(|p| self.collect_pat(p)).collect(),
631 }
632 }
624 633
625 // FIXME: implement 634 // FIXME: implement
626 ast::Pat::DotDotPat(_) => Pat::Missing,
627 ast::Pat::BoxPat(_) => Pat::Missing, 635 ast::Pat::BoxPat(_) => Pat::Missing,
628 ast::Pat::LiteralPat(_) => Pat::Missing, 636 ast::Pat::LiteralPat(_) => Pat::Missing,
629 ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, 637 ast::Pat::RangePat(_) => Pat::Missing,
630 }; 638 };
631 let ptr = AstPtr::new(&pat); 639 let ptr = AstPtr::new(&pat);
632 self.alloc_pat(pattern, Either::Left(ptr)) 640 self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index 5a84e08ed..9707c5527 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -394,7 +394,7 @@ pub enum Pat {
394 }, 394 },
395 Slice { 395 Slice {
396 prefix: Vec<PatId>, 396 prefix: Vec<PatId>,
397 rest: Option<PatId>, 397 slice: Option<PatId>,
398 suffix: Vec<PatId>, 398 suffix: Vec<PatId>,
399 }, 399 },
400 Path(Path), 400 Path(Path),
@@ -425,8 +425,8 @@ impl Pat {
425 args.iter().copied().for_each(f); 425 args.iter().copied().for_each(f);
426 } 426 }
427 Pat::Ref { pat, .. } => f(*pat), 427 Pat::Ref { pat, .. } => f(*pat),
428 Pat::Slice { prefix, rest, suffix } => { 428 Pat::Slice { prefix, slice, suffix } => {
429 let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); 429 let total_iter = prefix.iter().chain(slice.iter()).chain(suffix.iter());
430 total_iter.copied().for_each(f); 430 total_iter.copied().for_each(f);
431 } 431 }
432 Pat::Record { args, .. } => { 432 Pat::Record { args, .. } => {
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 89cb9a9f3..d3e8888bd 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -18,7 +18,8 @@ use crate::{
18pub use self::{ 18pub use self::{
19 expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, 19 expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 extensions::{ 20 extensions::{
21 FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind, VisibilityKind, 21 FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind,
22 VisibilityKind,
22 }, 23 },
23 generated::*, 24 generated::*,
24 tokens::*, 25 tokens::*,
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index cb0aee422..7dcf084de 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -1,6 +1,8 @@
1//! Various extension methods to ast Nodes, which are hard to code-generate. 1//! Various extension methods to ast Nodes, which are hard to code-generate.
2//! Extensions for various expressions live in a sibling `expr_extensions` module. 2//! Extensions for various expressions live in a sibling `expr_extensions` module.
3 3
4use itertools::Itertools;
5
4use crate::{ 6use crate::{
5 ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode}, 7 ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode},
6 SmolStr, SyntaxElement, 8 SmolStr, SyntaxElement,
@@ -293,6 +295,40 @@ impl ast::BindPat {
293 } 295 }
294} 296}
295 297
298pub struct SlicePatComponents {
299 pub prefix: Vec<ast::Pat>,
300 pub slice: Option<ast::Pat>,
301 pub suffix: Vec<ast::Pat>,
302}
303
304impl ast::SlicePat {
305 pub fn components(&self) -> SlicePatComponents {
306 let mut args = self.args().peekable();
307 let prefix = args
308 .peeking_take_while(|p| match p {
309 ast::Pat::DotDotPat(_) => false,
310 ast::Pat::BindPat(bp) => match bp.pat() {
311 Some(ast::Pat::DotDotPat(_)) => false,
312 _ => true,
313 },
314 ast::Pat::RefPat(rp) => match rp.pat() {
315 Some(ast::Pat::DotDotPat(_)) => false,
316 Some(ast::Pat::BindPat(bp)) => match bp.pat() {
317 Some(ast::Pat::DotDotPat(_)) => false,
318 _ => true,
319 },
320 _ => true,
321 },
322 _ => true,
323 })
324 .collect();
325 let slice = args.next();
326 let suffix = args.collect();
327
328 SlicePatComponents { prefix, slice, suffix }
329 }
330}
331
296impl ast::PointerType { 332impl ast::PointerType {
297 pub fn is_mut(&self) -> bool { 333 pub fn is_mut(&self) -> bool {
298 self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) 334 self.syntax().children_with_tokens().any(|n| n.kind() == T![mut])
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 8d640642d..8eb240801 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -2117,7 +2117,11 @@ impl AstNode for SlicePat {
2117 &self.syntax 2117 &self.syntax
2118 } 2118 }
2119} 2119}
2120impl SlicePat {} 2120impl SlicePat {
2121 pub fn args(&self) -> AstChildren<Pat> {
2122 AstChildren::new(&self.syntax)
2123 }
2124}
2121#[derive(Debug, Clone, PartialEq, Eq, Hash)] 2125#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2122pub struct RangePat { 2126pub struct RangePat {
2123 pub(crate) syntax: SyntaxNode, 2127 pub(crate) syntax: SyntaxNode,
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 3f530e489..2d9ae904b 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -417,14 +417,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
417 pat: Pat, 417 pat: Pat,
418 guard: MatchGuard, 418 guard: MatchGuard,
419 Expr, 419 Expr,
420 } 420 }
421 struct MatchGuard { Expr } 421 struct MatchGuard { Expr }
422 422
423 struct RecordLit { Path, RecordFieldList } 423 struct RecordLit { Path, RecordFieldList }
424 struct RecordFieldList { 424 struct RecordFieldList {
425 fields: [RecordField], 425 fields: [RecordField],
426 spread: Expr, 426 spread: Expr,
427 } 427 }
428 struct RecordField { NameRef, Expr } 428 struct RecordField { NameRef, Expr }
429 429
430 struct OrPat { pats: [Pat] } 430 struct OrPat { pats: [Pat] }
@@ -434,8 +434,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
434 struct BindPat: NameOwner { Pat } 434 struct BindPat: NameOwner { Pat }
435 struct PlaceholderPat { } 435 struct PlaceholderPat { }
436 struct DotDotPat { } 436 struct DotDotPat { }
437 struct PathPat { Path } 437 struct PathPat { Path }
438 struct SlicePat {} 438 struct SlicePat { args: [Pat] }
439 struct RangePat {} 439 struct RangePat {}
440 struct LiteralPat { Literal } 440 struct LiteralPat { Literal }
441 441