Split PatKind::Enum into PatKind::TupleStruct and PatKind::Path

This commit is contained in:
Vadim Petrochenkov 2016-02-16 00:40:38 +03:00
parent 9b40e1e5b3
commit 06755d90ce
22 changed files with 137 additions and 142 deletions

View file

@ -972,10 +972,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

@ -509,28 +509,34 @@ 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, Spanned<Ident>, 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, HirVec<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<HirVec<P<Pat>>>),
TupleStruct(Path, Option<HirVec<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
/// referred to as simply `T::CONST`, in which case they will end up as
/// PatKind::Enum, and the resolver will have to sort that out.
/// PatKind::Path, 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, HirVec<Spanned<FieldPat>>, bool),
/// A tuple pattern `(a, b)`
Tup(HirVec<P<Pat>>),
/// A `box` pattern

View file

@ -468,12 +468,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)

View file

@ -921,12 +921,12 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
}
PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)),
PatKind::TupleStruct(ref pth, ref pats) => {
hir::PatKind::Enum(lower_path(lctx, pth),
hir::PatKind::TupleStruct(lower_path(lctx, pth),
pats.as_ref()
.map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect()))
}
PatKind::Path(ref pth) => {
hir::PatKind::Enum(lower_path(lctx, pth), Some(hir::HirVec::new()))
hir::PatKind::Path(lower_path(lctx, pth))
}
PatKind::QPath(ref qself, ref pth) => {
let qself = hir::QSelf {
@ -1750,7 +1750,11 @@ fn pat_enum(lctx: &LoweringContext,
path: hir::Path,
subpats: hir::HirVec<P<hir::Pat>>)
-> P<hir::Pat> {
let pt = hir::PatKind::Enum(path, Some(subpats));
let pt = if subpats.is_empty() {
hir::PatKind::Path(path)
} else {
hir::PatKind::TupleStruct(path, Some(subpats))
};
pat(lctx, span, pt)
}

View file

@ -1748,19 +1748,20 @@ 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

@ -32,7 +32,7 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
PatKind::Struct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat_(&field.node.pat, it))
}
PatKind::Enum(_, Some(ref s)) | PatKind::Tup(ref s) => {
PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => {
s.iter().all(|p| walk_pat_(&p, it))
}
PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
@ -47,7 +47,8 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
PatKind::Lit(_) |
PatKind::Range(_, _) |
PatKind::Ident(_, _, _) |
PatKind::Enum(_, _) |
PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::QPath(_, _) => {
true
}