Skip to content

Commit

Permalink
Split ast::PatKind::Enum into tuple struct and path patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Feb 13, 2016
1 parent 14adc9b commit 9f414a4
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 26 deletions.
5 changes: 4 additions & 1 deletion src/librustc_front/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/save/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
26 changes: 16 additions & 10 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,28 +555,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, 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
/// 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.
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
Expand Down
6 changes: 5 additions & 1 deletion src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3534,22 +3534,22 @@ 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));
}
}
_ => {
pat = match qself {
// Parse qualified path
Some(qself) => PatKind::QPath(qself, path),
// Parse nullary enum
None => PatKind::Enum(path, Some(vec![]))
None => PatKind::Path(path)
};
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 9f414a4

Please sign in to comment.