Skip to content

Commit 759100f

Browse files
bors[bot]jplatte
andauthored
Merge #3062
3062: Implement slice pattern AST > HIR lowering r=jplatte a=jplatte WIP. The necessary changes for parsing are implemented, but actual inference is not yet. Just wanted to upload what I've got so far so it doesn't get duplicated :) Will fix #3043 Co-authored-by: Jonas Platte <[email protected]>
2 parents af5042b + a3b104a commit 759100f

File tree

8 files changed

+64
-13
lines changed

8 files changed

+64
-13
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir_def/Cargo.toml

+1
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

+12-4
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
};
@@ -596,7 +596,7 @@ where
596596
let args = p.args().map(|p| self.collect_pat(p)).collect();
597597
Pat::Tuple(args)
598598
}
599-
ast::Pat::PlaceholderPat(_) => Pat::Wild,
599+
ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild,
600600
ast::Pat::RecordPat(p) => {
601601
let path = p.path().and_then(|path| self.expander.parse_path(path));
602602
let record_field_pat_list =
@@ -621,12 +621,20 @@ where
621621

622622
Pat::Record { path, args: fields }
623623
}
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+
}
624633

625634
// FIXME: implement
626-
ast::Pat::DotDotPat(_) => Pat::Missing,
627635
ast::Pat::BoxPat(_) => Pat::Missing,
628636
ast::Pat::LiteralPat(_) => Pat::Missing,
629-
ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing,
637+
ast::Pat::RangePat(_) => Pat::Missing,
630638
};
631639
let ptr = AstPtr::new(&pat);
632640
self.alloc_pat(pattern, Either::Left(ptr))

crates/ra_hir_def/src/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ pub enum Pat {
394394
},
395395
Slice {
396396
prefix: Vec<PatId>,
397-
rest: Option<PatId>,
397+
slice: Option<PatId>,
398398
suffix: Vec<PatId>,
399399
},
400400
Path(Path),
@@ -425,8 +425,8 @@ impl Pat {
425425
args.iter().copied().for_each(f);
426426
}
427427
Pat::Ref { pat, .. } => f(*pat),
428-
Pat::Slice { prefix, rest, suffix } => {
429-
let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter());
428+
Pat::Slice { prefix, slice, suffix } => {
429+
let total_iter = prefix.iter().chain(slice.iter()).chain(suffix.iter());
430430
total_iter.copied().for_each(f);
431431
}
432432
Pat::Record { args, .. } => {

crates/ra_syntax/src/ast.rs

+2-1
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

+36
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

+5-1
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,11 @@ impl AstNode for SlicePat {
21172117
&self.syntax
21182118
}
21192119
}
2120-
impl SlicePat {}
2120+
impl SlicePat {
2121+
pub fn args(&self) -> AstChildren<Pat> {
2122+
AstChildren::new(&self.syntax)
2123+
}
2124+
}
21212125
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21222126
pub struct RangePat {
21232127
pub(crate) syntax: SyntaxNode,

xtask/src/ast_src.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
417417
pat: Pat,
418418
guard: MatchGuard,
419419
Expr,
420-
}
420+
}
421421
struct MatchGuard { Expr }
422422

423423
struct RecordLit { Path, RecordFieldList }
424424
struct RecordFieldList {
425425
fields: [RecordField],
426426
spread: Expr,
427-
}
427+
}
428428
struct RecordField { NameRef, Expr }
429429

430430
struct OrPat { pats: [Pat] }
@@ -434,8 +434,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
434434
struct BindPat: NameOwner { Pat }
435435
struct PlaceholderPat { }
436436
struct DotDotPat { }
437-
struct PathPat { Path }
438-
struct SlicePat {}
437+
struct PathPat { Path }
438+
struct SlicePat { args: [Pat] }
439439
struct RangePat {}
440440
struct LiteralPat { Literal }
441441

0 commit comments

Comments
 (0)