diff options
author | Jonas Platte <[email protected]> | 2020-02-11 21:33:11 +0000 |
---|---|---|
committer | Jonas Platte <[email protected]> | 2020-02-11 21:33:11 +0000 |
commit | a3b104aa6df205e74c116d8c9e41900807924e70 (patch) | |
tree | ac3cb2695fba41813b70cadee3e624f71dfa2fd3 | |
parent | 3e1d97790be166f8735607c552a94a28ab9b09b8 (diff) |
Implement slice pattern AST > HIR lowering
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_def/src/expr.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 3 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 36 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 6 | ||||
-rw-r--r-- | xtask/src/ast_src.rs | 8 |
8 files changed, 64 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock index e29ff898d..478c706be 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" | |||
14 | either = "1.5" | 14 | either = "1.5" |
15 | anymap = "0.12" | 15 | anymap = "0.12" |
16 | drop_bomb = "0.1.4" | 16 | drop_bomb = "0.1.4" |
17 | itertools = "0.8.2" | ||
17 | 18 | ||
18 | ra_arena = { path = "../ra_arena" } | 19 | ra_arena = { path = "../ra_arena" } |
19 | ra_db = { path = "../ra_db" } | 20 | ra_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 e656f9a41..5c779521b 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; | |||
8 | use ra_syntax::{ | 8 | use 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 | }; |
@@ -591,7 +591,7 @@ where | |||
591 | let args = p.args().map(|p| self.collect_pat(p)).collect(); | 591 | let args = p.args().map(|p| self.collect_pat(p)).collect(); |
592 | Pat::Tuple(args) | 592 | Pat::Tuple(args) |
593 | } | 593 | } |
594 | ast::Pat::PlaceholderPat(_) => Pat::Wild, | 594 | ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild, |
595 | ast::Pat::RecordPat(p) => { | 595 | ast::Pat::RecordPat(p) => { |
596 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 596 | let path = p.path().and_then(|path| self.expander.parse_path(path)); |
597 | let record_field_pat_list = | 597 | let record_field_pat_list = |
@@ -616,12 +616,20 @@ where | |||
616 | 616 | ||
617 | Pat::Record { path, args: fields } | 617 | Pat::Record { path, args: fields } |
618 | } | 618 | } |
619 | ast::Pat::SlicePat(p) => { | ||
620 | let SlicePatComponents { prefix, slice, suffix } = p.components(); | ||
621 | |||
622 | Pat::Slice { | ||
623 | prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), | ||
624 | slice: slice.map(|p| self.collect_pat(p)), | ||
625 | suffix: suffix.into_iter().map(|p| self.collect_pat(p)).collect(), | ||
626 | } | ||
627 | } | ||
619 | 628 | ||
620 | // FIXME: implement | 629 | // FIXME: implement |
621 | ast::Pat::DotDotPat(_) => Pat::Missing, | ||
622 | ast::Pat::BoxPat(_) => Pat::Missing, | 630 | ast::Pat::BoxPat(_) => Pat::Missing, |
623 | ast::Pat::LiteralPat(_) => Pat::Missing, | 631 | ast::Pat::LiteralPat(_) => Pat::Missing, |
624 | ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, | 632 | ast::Pat::RangePat(_) => Pat::Missing, |
625 | }; | 633 | }; |
626 | let ptr = AstPtr::new(&pat); | 634 | let ptr = AstPtr::new(&pat); |
627 | self.alloc_pat(pattern, Either::Left(ptr)) | 635 | 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 a75ef9970..035824403 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs | |||
@@ -393,7 +393,7 @@ pub enum Pat { | |||
393 | }, | 393 | }, |
394 | Slice { | 394 | Slice { |
395 | prefix: Vec<PatId>, | 395 | prefix: Vec<PatId>, |
396 | rest: Option<PatId>, | 396 | slice: Option<PatId>, |
397 | suffix: Vec<PatId>, | 397 | suffix: Vec<PatId>, |
398 | }, | 398 | }, |
399 | Path(Path), | 399 | Path(Path), |
@@ -424,8 +424,8 @@ impl Pat { | |||
424 | args.iter().copied().for_each(f); | 424 | args.iter().copied().for_each(f); |
425 | } | 425 | } |
426 | Pat::Ref { pat, .. } => f(*pat), | 426 | Pat::Ref { pat, .. } => f(*pat), |
427 | Pat::Slice { prefix, rest, suffix } => { | 427 | Pat::Slice { prefix, slice, suffix } => { |
428 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); | 428 | let total_iter = prefix.iter().chain(slice.iter()).chain(suffix.iter()); |
429 | total_iter.copied().for_each(f); | 429 | total_iter.copied().for_each(f); |
430 | } | 430 | } |
431 | Pat::Record { args, .. } => { | 431 | 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::{ | |||
18 | pub use self::{ | 18 | pub 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 | ||
4 | use itertools::Itertools; | ||
5 | |||
4 | use crate::{ | 6 | use 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 | ||
298 | pub struct SlicePatComponents { | ||
299 | pub prefix: Vec<ast::Pat>, | ||
300 | pub slice: Option<ast::Pat>, | ||
301 | pub suffix: Vec<ast::Pat>, | ||
302 | } | ||
303 | |||
304 | impl 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 | |||
296 | impl ast::PointerType { | 332 | impl 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 33d5578e7..8a3669bd1 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -2063,7 +2063,11 @@ impl AstNode for SlicePat { | |||
2063 | &self.syntax | 2063 | &self.syntax |
2064 | } | 2064 | } |
2065 | } | 2065 | } |
2066 | impl SlicePat {} | 2066 | impl SlicePat { |
2067 | pub fn args(&self) -> AstChildren<Pat> { | ||
2068 | AstChildren::new(&self.syntax) | ||
2069 | } | ||
2070 | } | ||
2067 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2071 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2068 | pub struct RangePat { | 2072 | pub struct RangePat { |
2069 | pub(crate) syntax: SyntaxNode, | 2073 | pub(crate) syntax: SyntaxNode, |
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 67d1f41bc..efe1e795b 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -415,14 +415,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
415 | pats: [Pat], | 415 | pats: [Pat], |
416 | guard: MatchGuard, | 416 | guard: MatchGuard, |
417 | Expr, | 417 | Expr, |
418 | } | 418 | } |
419 | struct MatchGuard { Expr } | 419 | struct MatchGuard { Expr } |
420 | 420 | ||
421 | struct RecordLit { Path, RecordFieldList } | 421 | struct RecordLit { Path, RecordFieldList } |
422 | struct RecordFieldList { | 422 | struct RecordFieldList { |
423 | fields: [RecordField], | 423 | fields: [RecordField], |
424 | spread: Expr, | 424 | spread: Expr, |
425 | } | 425 | } |
426 | struct RecordField { NameRef, Expr } | 426 | struct RecordField { NameRef, Expr } |
427 | 427 | ||
428 | struct RefPat { Pat } | 428 | struct RefPat { Pat } |
@@ -430,8 +430,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
430 | struct BindPat: NameOwner { Pat } | 430 | struct BindPat: NameOwner { Pat } |
431 | struct PlaceholderPat { } | 431 | struct PlaceholderPat { } |
432 | struct DotDotPat { } | 432 | struct DotDotPat { } |
433 | struct PathPat { Path } | 433 | struct PathPat { Path } |
434 | struct SlicePat {} | 434 | struct SlicePat { args: [Pat] } |
435 | struct RangePat {} | 435 | struct RangePat {} |
436 | struct LiteralPat { Literal } | 436 | struct LiteralPat { Literal } |
437 | 437 | ||