Skip to content

Commit

Permalink
Merge #3062
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors[bot] and jplatte authored Feb 11, 2020
2 parents af5042b + a3b104a commit 759100f
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/ra_hir_def/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ rustc-hash = "1.0"
either = "1.5"
anymap = "0.12"
drop_bomb = "0.1.4"
itertools = "0.8.2"

ra_arena = { path = "../ra_arena" }
ra_db = { path = "../ra_db" }
Expand Down
16 changes: 12 additions & 4 deletions crates/ra_hir_def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ra_arena::Arena;
use ra_syntax::{
ast::{
self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
TypeAscriptionOwner,
SlicePatComponents, TypeAscriptionOwner,
},
AstNode, AstPtr,
};
Expand Down Expand Up @@ -596,7 +596,7 @@ where
let args = p.args().map(|p| self.collect_pat(p)).collect();
Pat::Tuple(args)
}
ast::Pat::PlaceholderPat(_) => Pat::Wild,
ast::Pat::PlaceholderPat(_) | ast::Pat::DotDotPat(_) => Pat::Wild,
ast::Pat::RecordPat(p) => {
let path = p.path().and_then(|path| self.expander.parse_path(path));
let record_field_pat_list =
Expand All @@ -621,12 +621,20 @@ where

Pat::Record { path, args: fields }
}
ast::Pat::SlicePat(p) => {
let SlicePatComponents { prefix, slice, suffix } = p.components();

Pat::Slice {
prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(),
slice: slice.map(|p| self.collect_pat(p)),
suffix: suffix.into_iter().map(|p| self.collect_pat(p)).collect(),
}
}

// FIXME: implement
ast::Pat::DotDotPat(_) => Pat::Missing,
ast::Pat::BoxPat(_) => Pat::Missing,
ast::Pat::LiteralPat(_) => Pat::Missing,
ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing,
ast::Pat::RangePat(_) => Pat::Missing,
};
let ptr = AstPtr::new(&pat);
self.alloc_pat(pattern, Either::Left(ptr))
Expand Down
6 changes: 3 additions & 3 deletions crates/ra_hir_def/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ pub enum Pat {
},
Slice {
prefix: Vec<PatId>,
rest: Option<PatId>,
slice: Option<PatId>,
suffix: Vec<PatId>,
},
Path(Path),
Expand Down Expand Up @@ -425,8 +425,8 @@ impl Pat {
args.iter().copied().for_each(f);
}
Pat::Ref { pat, .. } => f(*pat),
Pat::Slice { prefix, rest, suffix } => {
let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter());
Pat::Slice { prefix, slice, suffix } => {
let total_iter = prefix.iter().chain(slice.iter()).chain(suffix.iter());
total_iter.copied().for_each(f);
}
Pat::Record { args, .. } => {
Expand Down
3 changes: 2 additions & 1 deletion crates/ra_syntax/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ use crate::{
pub use self::{
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
extensions::{
FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind, VisibilityKind,
FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind,
VisibilityKind,
},
generated::*,
tokens::*,
Expand Down
36 changes: 36 additions & 0 deletions crates/ra_syntax/src/ast/extensions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Various extension methods to ast Nodes, which are hard to code-generate.
//! Extensions for various expressions live in a sibling `expr_extensions` module.

use itertools::Itertools;

use crate::{
ast::{self, child_opt, children, AstNode, AttrInput, SyntaxNode},
SmolStr, SyntaxElement,
Expand Down Expand Up @@ -293,6 +295,40 @@ impl ast::BindPat {
}
}

pub struct SlicePatComponents {
pub prefix: Vec<ast::Pat>,
pub slice: Option<ast::Pat>,
pub suffix: Vec<ast::Pat>,
}

impl ast::SlicePat {
pub fn components(&self) -> SlicePatComponents {
let mut args = self.args().peekable();
let prefix = args
.peeking_take_while(|p| match p {
ast::Pat::DotDotPat(_) => false,
ast::Pat::BindPat(bp) => match bp.pat() {
Some(ast::Pat::DotDotPat(_)) => false,
_ => true,
},
ast::Pat::RefPat(rp) => match rp.pat() {
Some(ast::Pat::DotDotPat(_)) => false,
Some(ast::Pat::BindPat(bp)) => match bp.pat() {
Some(ast::Pat::DotDotPat(_)) => false,
_ => true,
},
_ => true,
},
_ => true,
})
.collect();
let slice = args.next();
let suffix = args.collect();

SlicePatComponents { prefix, slice, suffix }
}
}

impl ast::PointerType {
pub fn is_mut(&self) -> bool {
self.syntax().children_with_tokens().any(|n| n.kind() == T![mut])
Expand Down
6 changes: 5 additions & 1 deletion crates/ra_syntax/src/ast/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2117,7 +2117,11 @@ impl AstNode for SlicePat {
&self.syntax
}
}
impl SlicePat {}
impl SlicePat {
pub fn args(&self) -> AstChildren<Pat> {
AstChildren::new(&self.syntax)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RangePat {
pub(crate) syntax: SyntaxNode,
Expand Down
8 changes: 4 additions & 4 deletions xtask/src/ast_src.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,14 +417,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
pat: Pat,
guard: MatchGuard,
Expr,
}
}
struct MatchGuard { Expr }

struct RecordLit { Path, RecordFieldList }
struct RecordFieldList {
fields: [RecordField],
spread: Expr,
}
}
struct RecordField { NameRef, Expr }

struct OrPat { pats: [Pat] }
Expand All @@ -434,8 +434,8 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
struct BindPat: NameOwner { Pat }
struct PlaceholderPat { }
struct DotDotPat { }
struct PathPat { Path }
struct SlicePat {}
struct PathPat { Path }
struct SlicePat { args: [Pat] }
struct RangePat {}
struct LiteralPat { Literal }

Expand Down

0 comments on commit 759100f

Please sign in to comment.