Skip to content

Commit a3b104a

Browse files
committed
Implement slice pattern AST > HIR lowering
1 parent 3e1d977 commit a3b104a

File tree

8 files changed

+64
-13
lines changed

8 files changed

+64
-13
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir_def/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rustc-hash = "1.0"
1414
either = "1.5"
1515
anymap = "0.12"
1616
drop_bomb = "0.1.4"
17+
itertools = "0.8.2"
1718

1819
ra_arena = { path = "../ra_arena" }
1920
ra_db = { path = "../ra_db" }

crates/ra_hir_def/src/body/lower.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ra_arena::Arena;
88
use ra_syntax::{
99
ast::{
1010
self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
11-
TypeAscriptionOwner,
11+
SlicePatComponents, TypeAscriptionOwner,
1212
},
1313
AstNode, AstPtr,
1414
};
@@ -591,7 +591,7 @@ where
591591
let args = p.args().map(|p| self.collect_pat(p)).collect();
592592
Pat::Tuple(args)
593593
}
594-
ast::Pat::PlaceholderPat(_) => Pat::Wild,
594+
ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild,
595595
ast::Pat::RecordPat(p) => {
596596
let path = p.path().and_then(|path| self.expander.parse_path(path));
597597
let record_field_pat_list =
@@ -616,12 +616,20 @@ where
616616

617617
Pat::Record { path, args: fields }
618618
}
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+
}
619628

620629
// FIXME: implement
621-
ast::Pat::DotDotPat(_) => Pat::Missing,
622630
ast::Pat::BoxPat(_) => Pat::Missing,
623631
ast::Pat::LiteralPat(_) => Pat::Missing,
624-
ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing,
632+
ast::Pat::RangePat(_) => Pat::Missing,
625633
};
626634
let ptr = AstPtr::new(&pat);
627635
self.alloc_pat(pattern, Either::Left(ptr))

crates/ra_hir_def/src/expr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ pub enum Pat {
393393
},
394394
Slice {
395395
prefix: Vec<PatId>,
396-
rest: Option<PatId>,
396+
slice: Option<PatId>,
397397
suffix: Vec<PatId>,
398398
},
399399
Path(Path),
@@ -424,8 +424,8 @@ impl Pat {
424424
args.iter().copied().for_each(f);
425425
}
426426
Pat::Ref { pat, .. } => f(*pat),
427-
Pat::Slice { prefix, rest, suffix } => {
428-
let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter());
427+
Pat::Slice { prefix, slice, suffix } => {
428+
let total_iter = prefix.iter().chain(slice.iter()).chain(suffix.iter());
429429
total_iter.copied().for_each(f);
430430
}
431431
Pat::Record { args, .. } => {

crates/ra_syntax/src/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::{
1818
pub use self::{
1919
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
2020
extensions::{
21-
FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind, VisibilityKind,
21+
FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind,
22+
VisibilityKind,
2223
},
2324
generated::*,
2425
tokens::*,

crates/ra_syntax/src/ast/extensions.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Various extension methods to ast Nodes, which are hard to code-generate.
22
//! Extensions for various expressions live in a sibling `expr_extensions` module.
33
4+
use itertools::Itertools;
5+
46
use crate::{
57
ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode},
68
SmolStr, SyntaxElement,
@@ -293,6 +295,40 @@ impl ast::BindPat {
293295
}
294296
}
295297

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+
296332
impl ast::PointerType {
297333
pub fn is_mut(&self) -> bool {
298334
self.syntax().children_with_tokens().any(|n| n.kind() == T![mut])

crates/ra_syntax/src/ast/generated.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2063,7 +2063,11 @@ impl AstNode for SlicePat {
20632063
&self.syntax
20642064
}
20652065
}
2066-
impl SlicePat {}
2066+
impl SlicePat {
2067+
pub fn args(&self) -> AstChildren<Pat> {
2068+
AstChildren::new(&self.syntax)
2069+
}
2070+
}
20672071
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20682072
pub struct RangePat {
20692073
pub(crate) syntax: SyntaxNode,

xtask/src/ast_src.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,23 +415,23 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
415415
pats: [Pat],
416416
guard: MatchGuard,
417417
Expr,
418-
}
418+
}
419419
struct MatchGuard { Expr }
420420

421421
struct RecordLit { Path, RecordFieldList }
422422
struct RecordFieldList {
423423
fields: [RecordField],
424424
spread: Expr,
425-
}
425+
}
426426
struct RecordField { NameRef, Expr }
427427

428428
struct RefPat { Pat }
429429
struct BoxPat { Pat }
430430
struct BindPat: NameOwner { Pat }
431431
struct PlaceholderPat { }
432432
struct DotDotPat { }
433-
struct PathPat { Path }
434-
struct SlicePat {}
433+
struct PathPat { Path }
434+
struct SlicePat { args: [Pat] }
435435
struct RangePat {}
436436
struct LiteralPat { Literal }
437437

0 commit comments

Comments
 (0)