Split ast::PatKind::Enum into tuple struct and path patterns

This commit is contained in:
Vadim Petrochenkov 2016-02-13 15:51:27 +03:00
parent 14adc9bb63
commit 9f414a44a7
8 changed files with 47 additions and 26 deletions

View File

@ -920,11 +920,14 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
sub.as_ref().map(|x| lower_pat(lctx, x)))
}
PatKind::Lit(ref e) => hir::PatLit(lower_expr(lctx, e)),
PatKind::Enum(ref pth, ref pats) => {
PatKind::TupleStruct(ref pth, ref pats) => {
hir::PatEnum(lower_path(lctx, pth),
pats.as_ref()
.map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect()))
}
PatKind::Path(ref pth) => {
hir::PatEnum(lower_path(lctx, pth), Some(hir::HirVec::new()))
}
PatKind::QPath(ref qself, ref pth) => {
let qself = hir::QSelf {
ty: lower_ty(lctx, &qself.ty),

View File

@ -762,7 +762,8 @@ impl<'v> Visitor<'v> for PathCollector {
self.collected_paths.push((p.id, path.clone(),
ast::Mutability::Mutable, recorder::TypeRef));
}
PatKind::Enum(ref path, _) |
PatKind::TupleStruct(ref path, _) |
PatKind::Path(ref path) |
PatKind::QPath(_, ref path) => {
self.collected_paths.push((p.id, path.clone(),
ast::Mutability::Mutable, recorder::VarRef));

View File

@ -555,18 +555,27 @@ pub enum PatKind {
/// Represents a wildcard pattern (`_`)
Wild,
/// A PatKind::Ident may either be a new bound variable,
/// or a nullary enum (in which case the third field
/// is None).
/// A `PatKind::Ident` may either be a new bound variable,
/// or a unit struct/variant pattern, or a const pattern (in the last two cases
/// the third field must be `None`).
///
/// In the nullary enum case, the parser can't determine
/// In the unit or const pattern case, the parser can't determine
/// which it is. The resolver determines this, and
/// records this pattern's NodeId in an auxiliary
/// set (of "PatIdents that refer to nullary enums")
/// records this pattern's `NodeId` in an auxiliary
/// set (of "PatIdents that refer to unit patterns or constants").
Ident(BindingMode, SpannedIdent, Option<P<Pat>>),
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
/// The `bool` is `true` in the presence of a `..`.
Struct(Path, Vec<Spanned<FieldPat>>, bool),
/// A tuple struct/variant pattern `Variant(x, y, z)`.
/// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
Enum(Path, Option<Vec<P<Pat>>>),
TupleStruct(Path, Option<Vec<P<Pat>>>),
/// A path pattern.
/// Such pattern can be resolved to a unit struct/variant or a constant.
Path(Path),
/// An associated const named using the qualified path `<T>::CONST` or
/// `<T as Trait>::CONST`. Associated consts from inherent impls can be
@ -574,9 +583,6 @@ pub enum PatKind {
/// PatKind::Enum, and the resolver will have to sort that out.
QPath(QSelf, Path),
/// Destructuring of a struct, e.g. `Foo {x, y, ..}`
/// The `bool` is `true` in the presence of a `..`
Struct(Path, Vec<Spanned<FieldPat>>, bool),
/// A tuple pattern `(a, b)`
Tup(Vec<P<Pat>>),
/// A `box` pattern

View File

@ -827,7 +827,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.pat(span, pat)
}
fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
let pat = PatKind::Enum(path, Some(subpats));
let pat = if subpats.is_empty() {
PatKind::Path(path)
} else {
PatKind::TupleStruct(path, Some(subpats))
};
self.pat(span, pat)
}
fn pat_struct(&self, span: Span,

View File

@ -1127,10 +1127,13 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
sub.map(|x| folder.fold_pat(x)))
}
PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
PatKind::Enum(pth, pats) => {
PatKind::Enum(folder.fold_path(pth),
PatKind::TupleStruct(pth, pats) => {
PatKind::TupleStruct(folder.fold_path(pth),
pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
}
PatKind::Path(pth) => {
PatKind::Path(folder.fold_path(pth))
}
PatKind::QPath(qself, pth) => {
let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself};
PatKind::QPath(qself, folder.fold_path(pth))

View File

@ -3534,14 +3534,14 @@ impl<'a> Parser<'a> {
self.bump();
self.bump();
try!(self.expect(&token::CloseDelim(token::Paren)));
pat = PatKind::Enum(path, None);
pat = PatKind::TupleStruct(path, None);
} else {
let args = try!(self.parse_enum_variant_seq(
&token::OpenDelim(token::Paren),
&token::CloseDelim(token::Paren),
seq_sep_trailing_allowed(token::Comma),
|p| p.parse_pat()));
pat = PatKind::Enum(path, Some(args));
pat = PatKind::TupleStruct(path, Some(args));
}
}
_ => {
@ -3549,7 +3549,7 @@ impl<'a> Parser<'a> {
// Parse qualified path
Some(qself) => PatKind::QPath(qself, path),
// Parse nullary enum
None => PatKind::Enum(path, Some(vec![]))
None => PatKind::Path(path)
};
}
}

View File

@ -2478,20 +2478,21 @@ impl<'a> State<'a> {
None => ()
}
}
PatKind::Enum(ref path, ref args_) => {
PatKind::TupleStruct(ref path, ref args_) => {
try!(self.print_path(path, true, 0));
match *args_ {
None => try!(word(&mut self.s, "(..)")),
Some(ref args) => {
if !args.is_empty() {
try!(self.popen());
try!(self.commasep(Inconsistent, &args[..],
|s, p| s.print_pat(&p)));
try!(self.pclose());
}
try!(self.popen());
try!(self.commasep(Inconsistent, &args[..],
|s, p| s.print_pat(&p)));
try!(self.pclose());
}
}
}
PatKind::Path(ref path) => {
try!(self.print_path(path, true, 0));
}
PatKind::QPath(ref qself, ref path) => {
try!(self.print_qpath(path, qself, false));
}

View File

@ -419,12 +419,15 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
match pattern.node {
PatKind::Enum(ref path, ref opt_children) => {
PatKind::TupleStruct(ref path, ref opt_children) => {
visitor.visit_path(path, pattern.id);
if let Some(ref children) = *opt_children {
walk_list!(visitor, visit_pat, children);
}
}
PatKind::Path(ref path) => {
visitor.visit_path(path, pattern.id);
}
PatKind::QPath(ref qself, ref path) => {
visitor.visit_ty(&qself.ty);
visitor.visit_path(path, pattern.id)