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

@@ -100,7 +100,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex { fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
match pat.node { match pat.node {
PatKind::Ident(_, _, None) | PatKind::Ident(_, _, None) |
PatKind::Enum(_, None) | PatKind::TupleStruct(_, None) |
PatKind::Path(..) |
PatKind::QPath(..) | PatKind::QPath(..) |
PatKind::Lit(..) | PatKind::Lit(..) |
PatKind::Range(..) | PatKind::Range(..) |
@@ -115,7 +116,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.add_ast_node(pat.id, &[subpat_exit]) self.add_ast_node(pat.id, &[subpat_exit])
} }
PatKind::Enum(_, Some(ref subpats)) | PatKind::TupleStruct(_, Some(ref subpats)) |
PatKind::Tup(ref subpats) => { PatKind::Tup(ref subpats) => {
let pats_exit = self.pats_all(subpats.iter(), pred); let pats_exit = self.pats_all(subpats.iter(), pred);
self.add_ast_node(pat.id, &[pats_exit]) self.add_ast_node(pat.id, &[pats_exit])

View File

@@ -377,7 +377,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir:
hir::MatchSource::ForLoopDesugar => { hir::MatchSource::ForLoopDesugar => {
// `witnesses[0]` has the form `Some(<head>)`, peel off the `Some` // `witnesses[0]` has the form `Some(<head>)`, peel off the `Some`
let witness = match witnesses[0].node { let witness = match witnesses[0].node {
PatKind::Enum(_, Some(ref pats)) => match &pats[..] { PatKind::TupleStruct(_, Some(ref pats)) => match &pats[..] {
[ref pat] => &**pat, [ref pat] => &**pat,
_ => unreachable!(), _ => unreachable!(),
}, },
@@ -466,7 +466,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> { fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
return match pat.node { return match pat.node {
PatKind::Ident(..) | PatKind::Enum(..) | PatKind::QPath(..) => { PatKind::Ident(..) | PatKind::Path(..) | PatKind::QPath(..) => {
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()); let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
match def { match def {
Some(Def::AssociatedConst(did)) | Some(Def::AssociatedConst(did)) |
@@ -534,7 +534,8 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => { ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
let v = adt.variant_of_ctor(ctor); let v = adt.variant_of_ctor(ctor);
if let VariantKind::Struct = v.kind() { match v.kind() {
VariantKind::Struct => {
let field_pats: hir::HirVec<_> = v.fields.iter() let field_pats: hir::HirVec<_> = v.fields.iter()
.zip(pats) .zip(pats)
.filter(|&(_, ref pat)| pat.node != PatKind::Wild) .filter(|&(_, ref pat)| pat.node != PatKind::Wild)
@@ -548,8 +549,13 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
}).collect(); }).collect();
let has_more_fields = field_pats.len() < pats_len; let has_more_fields = field_pats.len() < pats_len;
PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields) PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
} else { }
PatKind::Enum(def_to_path(cx.tcx, v.did), Some(pats.collect())) VariantKind::Tuple => {
PatKind::TupleStruct(def_to_path(cx.tcx, v.did), Some(pats.collect()))
}
VariantKind::Unit => {
PatKind::Path(def_to_path(cx.tcx, v.did))
}
} }
} }
@@ -769,34 +775,20 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> { left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
let pat = raw_pat(p); let pat = raw_pat(p);
match pat.node { match pat.node {
PatKind::Ident(..) => PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) { match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => Def::Const(..) | Def::AssociatedConst(..) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \ cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"), been rewritten"),
Some(Def::Struct(..)) => vec!(Single), Def::Struct(..) | Def::TyAlias(..) => vec![Single],
Some(Def::Variant(_, id)) => vec!(Variant(id)), Def::Variant(_, id) => vec![Variant(id)],
_ => vec!() Def::Local(..) => vec![],
}, def => cx.tcx.sess.span_bug(pat.span, &format!("pat_constructors: unexpected \
PatKind::Enum(..) => definition {:?}", def)),
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"),
Some(Def::Variant(_, id)) => vec!(Variant(id)),
_ => vec!(Single)
}, },
PatKind::QPath(..) => PatKind::QPath(..) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \ cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"), been rewritten"),
PatKind::Struct(..) =>
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
been rewritten"),
Some(Def::Variant(_, id)) => vec!(Variant(id)),
_ => vec!(Single)
},
PatKind::Lit(ref expr) => PatKind::Lit(ref expr) =>
vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))), vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))),
PatKind::Range(ref lo, ref hi) => PatKind::Range(ref lo, ref hi) =>
@@ -880,22 +872,21 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
PatKind::Wild => PatKind::Wild =>
Some(vec![DUMMY_WILD_PAT; arity]), Some(vec![DUMMY_WILD_PAT; arity]),
PatKind::Ident(_, _, _) => { PatKind::Path(..) | PatKind::Ident(..) => {
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def()); let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match opt_def { match def {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => Def::Const(..) | Def::AssociatedConst(..) =>
cx.tcx.sess.span_bug(pat_span, "const pattern should've \ cx.tcx.sess.span_bug(pat_span, "const pattern should've \
been rewritten"), been rewritten"),
Some(Def::Variant(_, id)) => if *constructor == Variant(id) { Def::Variant(_, id) if *constructor != Variant(id) => None,
Some(vec!()) Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
} else { Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]),
None _ => cx.tcx.sess.span_bug(pat_span, &format!("specialize: unexpected \
}, definition {:?}", def)),
_ => Some(vec![DUMMY_WILD_PAT; arity])
} }
} }
PatKind::Enum(_, ref args) => { PatKind::TupleStruct(_, ref args) => {
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match def { match def {
Def::Const(..) | Def::AssociatedConst(..) => Def::Const(..) | Def::AssociatedConst(..) =>

View File

@@ -343,7 +343,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
_ => unreachable!() _ => unreachable!()
}; };
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect(); let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
PatKind::Enum(path, Some(pats)) PatKind::TupleStruct(path, Some(pats))
} }
hir::ExprStruct(ref path, ref fields, None) => { hir::ExprStruct(ref path, ref fields, None) => {
@@ -366,10 +366,8 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
hir::ExprPath(_, ref path) => { hir::ExprPath(_, ref path) => {
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()); let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
match opt_def { match opt_def {
Some(Def::Struct(..)) => Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
PatKind::Struct(path.clone(), hir::HirVec::new(), false), PatKind::Path(path.clone()),
Some(Def::Variant(..)) =>
PatKind::Enum(path.clone(), None),
Some(Def::Const(def_id)) | Some(Def::Const(def_id)) |
Some(Def::AssociatedConst(def_id)) => { Some(Def::AssociatedConst(def_id)) => {
let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap(); let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();

View File

@@ -1070,7 +1070,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
let tcx = typer.tcx; let tcx = typer.tcx;
match pat.node { match pat.node {
PatKind::Enum(_, _) | PatKind::QPath(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
PatKind::Ident(_, _, None) | PatKind::Struct(..) => { PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
match def_map.get(&pat.id).map(|d| d.full_def()) { match def_map.get(&pat.id).map(|d| d.full_def()) {
None => { None => {

View File

@@ -1209,7 +1209,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
None None
}; };
// Note: This goes up here (rather than within the PatKind::Enum arm // Note: This goes up here (rather than within the PatKind::TupleStruct arm
// alone) because struct patterns can refer to struct types or // alone) because struct patterns can refer to struct types or
// to struct variants within enums. // to struct variants within enums.
let cmt = match opt_def { let cmt = match opt_def {
@@ -1226,10 +1226,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
// _ // _
} }
PatKind::Enum(_, None) => { PatKind::TupleStruct(_, None) => {
// variant(..) // variant(..)
} }
PatKind::Enum(_, Some(ref subpats)) => { PatKind::TupleStruct(_, Some(ref subpats)) => {
match opt_def { match opt_def {
Some(Def::Variant(..)) => { Some(Def::Variant(..)) => {
// variant(x, y, z) // variant(x, y, z)
@@ -1267,18 +1267,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
} }
} }
PatKind::QPath(..) => { PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
// Lone constant: ignore // Lone constant, or unit variant or identifier: ignore
} }
PatKind::Ident(_, _, Some(ref subpat)) => { PatKind::Ident(_, _, Some(ref subpat)) => {
try!(self.cat_pattern_(cmt, &subpat, op)); try!(self.cat_pattern_(cmt, &subpat, op));
} }
PatKind::Ident(_, _, None) => {
// nullary variant or identifier: ignore
}
PatKind::Struct(_, ref field_pats, _) => { PatKind::Struct(_, ref field_pats, _) => {
// {f1: p1, ..., fN: pN} // {f1: p1, ..., fN: pN}
for fp in field_pats { for fp in field_pats {

View File

@@ -35,7 +35,8 @@ pub fn pat_id_map(dm: &RefCell<DefMap>, pat: &hir::Pat) -> PatIdMap {
pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node { match pat.node {
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true, PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
PatKind::Enum(_, _) | PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) | PatKind::Ident(_, _, None) |
PatKind::Struct(..) => { PatKind::Struct(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) { match dm.get(&pat.id).map(|d| d.full_def()) {
@@ -50,11 +51,12 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node { match pat.node {
PatKind::Enum(_, _) | PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) | PatKind::Ident(_, _, None) |
PatKind::Struct(..) => { PatKind::Struct(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) { match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Variant(..)) | Some(Def::Struct(..)) => true, Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true,
_ => false _ => false
} }
} }
@@ -64,7 +66,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node { match pat.node {
PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => { PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) { match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
_ => false _ => false
@@ -78,7 +80,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
// returned instead of a panic. // returned instead of a panic.
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
match pat.node { match pat.node {
PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => { PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
match dm.get(&pat.id) match dm.get(&pat.id)
.and_then(|d| if d.depth == 0 { Some(d.base_def) } .and_then(|d| if d.depth == 0 { Some(d.base_def) }
else { None } ) { else { None } ) {
@@ -224,7 +226,8 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
let mut variants = vec![]; let mut variants = vec![];
walk_pat(pat, |p| { walk_pat(pat, |p| {
match p.node { match p.node {
PatKind::Enum(_, _) | PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Ident(_, _, None) | PatKind::Ident(_, _, None) |
PatKind::Struct(..) => { PatKind::Struct(..) => {
match dm.get(&p.id) { match dm.get(&p.id) {

View File

@@ -970,7 +970,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
pats3.iter().any(|p| is_binding_pat(&p)) pats3.iter().any(|p| is_binding_pat(&p))
} }
PatKind::Enum(_, Some(ref subpats)) | PatKind::TupleStruct(_, Some(ref subpats)) |
PatKind::Tup(ref subpats) => { PatKind::Tup(ref subpats) => {
subpats.iter().any(|p| is_binding_pat(&p)) subpats.iter().any(|p| is_binding_pat(&p))
} }

View File

@@ -598,8 +598,8 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
}; };
match pat.node { match pat.node {
// Foo(a, b, c) // Foo(a, b, c)
// A Variant(..) pattern `PatKind::Enum(_, None)` doesn't have to be recursed into. // A Variant(..) pattern `PatKind::TupleStruct(_, None)` doesn't have to be recursed into.
PatKind::Enum(_, Some(ref pat_fields)) => { PatKind::TupleStruct(_, Some(ref pat_fields)) => {
for (field, struct_field) in pat_fields.iter().zip(&v.fields) { for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
maybe_do_stability_check(tcx, struct_field.did, field.span, cb) maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
} }

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))) sub.map(|x| folder.fold_pat(x)))
} }
PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
PatKind::Enum(pth, pats) => { PatKind::TupleStruct(pth, pats) => {
PatKind::Enum(folder.fold_path(pth), PatKind::TupleStruct(folder.fold_path(pth),
pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
} }
PatKind::Path(pth) => {
PatKind::Path(folder.fold_path(pth))
}
PatKind::QPath(qself, pth) => { PatKind::QPath(qself, pth) => {
let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself }; let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself };
PatKind::QPath(qself, folder.fold_path(pth)) PatKind::QPath(qself, folder.fold_path(pth))

View File

@@ -509,28 +509,34 @@ pub enum PatKind {
/// Represents a wildcard pattern (`_`) /// Represents a wildcard pattern (`_`)
Wild, Wild,
/// A PatKind::Ident may either be a new bound variable, /// A `PatKind::Ident` may either be a new bound variable,
/// or a nullary enum (in which case the third field /// or a unit struct/variant pattern, or a const pattern (in the last two cases
/// is None). /// 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 /// which it is. The resolver determines this, and
/// records this pattern's NodeId in an auxiliary /// records this pattern's `NodeId` in an auxiliary
/// set (of "PatIdents that refer to nullary enums") /// set (of "PatIdents that refer to unit patterns or constants").
Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>), 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. /// "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 /// An associated const named using the qualified path `<T>::CONST` or
/// `<T as Trait>::CONST`. Associated consts from inherent impls can be /// `<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 /// 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), 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)` /// A tuple pattern `(a, b)`
Tup(HirVec<P<Pat>>), Tup(HirVec<P<Pat>>),
/// A `box` pattern /// 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) { pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
match pattern.node { match pattern.node {
PatKind::Enum(ref path, ref opt_children) => { PatKind::TupleStruct(ref path, ref opt_children) => {
visitor.visit_path(path, pattern.id); visitor.visit_path(path, pattern.id);
if let Some(ref children) = *opt_children { if let Some(ref children) = *opt_children {
walk_list!(visitor, visit_pat, children); walk_list!(visitor, visit_pat, children);
} }
} }
PatKind::Path(ref path) => {
visitor.visit_path(path, pattern.id);
}
PatKind::QPath(ref qself, ref path) => { PatKind::QPath(ref qself, ref path) => {
visitor.visit_ty(&qself.ty); visitor.visit_ty(&qself.ty);
visitor.visit_path(path, pattern.id) 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::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)),
PatKind::TupleStruct(ref pth, ref pats) => { PatKind::TupleStruct(ref pth, ref pats) => {
hir::PatKind::Enum(lower_path(lctx, pth), hir::PatKind::TupleStruct(lower_path(lctx, pth),
pats.as_ref() pats.as_ref()
.map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect()))
} }
PatKind::Path(ref pth) => { 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) => { PatKind::QPath(ref qself, ref pth) => {
let qself = hir::QSelf { let qself = hir::QSelf {
@@ -1750,7 +1750,11 @@ fn pat_enum(lctx: &LoweringContext,
path: hir::Path, path: hir::Path,
subpats: hir::HirVec<P<hir::Pat>>) subpats: hir::HirVec<P<hir::Pat>>)
-> 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) pat(lctx, span, pt)
} }

View File

@@ -1748,18 +1748,19 @@ impl<'a> State<'a> {
None => (), None => (),
} }
} }
PatKind::Enum(ref path, ref args_) => { PatKind::TupleStruct(ref path, ref args_) => {
try!(self.print_path(path, true, 0)); try!(self.print_path(path, true, 0));
match *args_ { match *args_ {
None => try!(word(&mut self.s, "(..)")), None => try!(word(&mut self.s, "(..)")),
Some(ref args) => { Some(ref args) => {
if !args.is_empty() {
try!(self.popen()); try!(self.popen());
try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p))); try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p)));
try!(self.pclose()); try!(self.pclose());
} }
} }
} }
PatKind::Path(ref path) => {
try!(self.print_path(path, true, 0));
} }
PatKind::QPath(ref qself, ref path) => { PatKind::QPath(ref qself, ref path) => {
try!(self.print_qpath(path, qself, false)); 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, _) => { PatKind::Struct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat_(&field.node.pat, it)) 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)) s.iter().all(|p| walk_pat_(&p, it))
} }
PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { 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::Lit(_) |
PatKind::Range(_, _) | PatKind::Range(_, _) |
PatKind::Ident(_, _, _) | PatKind::Ident(_, _, _) |
PatKind::Enum(_, _) | PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::QPath(_, _) => { PatKind::QPath(_, _) => {
true true
} }

View File

@@ -79,7 +79,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
PatternKind::Range { lo: lo, hi: hi } PatternKind::Range { lo: lo, hi: hi }
}, },
PatKind::Enum(..) | PatKind::Ident(..) | PatKind::QPath(..) PatKind::Path(..) | PatKind::Ident(..) | PatKind::QPath(..)
if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) => if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) =>
{ {
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
@@ -179,11 +179,11 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
} }
} }
PatKind::Ident(..) => { PatKind::Ident(..) | PatKind::Path(..) => {
self.variant_or_leaf(pat, vec![]) self.variant_or_leaf(pat, vec![])
} }
PatKind::Enum(_, ref opt_subpatterns) => { PatKind::TupleStruct(_, ref opt_subpatterns) => {
let subpatterns = let subpatterns =
opt_subpatterns.iter() opt_subpatterns.iter()
.flat_map(|v| v.iter()) .flat_map(|v| v.iter())

View File

@@ -932,7 +932,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
// Patterns which bind no fields are allowable (the path is check // Patterns which bind no fields are allowable (the path is check
// elsewhere). // elsewhere).
PatKind::Enum(_, Some(ref fields)) => { PatKind::TupleStruct(_, Some(ref fields)) => {
match self.tcx.pat_ty(pattern).sty { match self.tcx.pat_ty(pattern).sty {
ty::TyStruct(def, _) => { ty::TyStruct(def, _) => {
for (i, field) in fields.iter().enumerate() { for (i, field) in fields.iter().enumerate() {

View File

@@ -2473,7 +2473,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
PatKind::Enum(ref path, _) => { PatKind::TupleStruct(ref path, _) | PatKind::Path(ref path) => {
// This must be an enum variant, struct or const. // This must be an enum variant, struct or const.
let resolution = match self.resolve_possibly_assoc_item(pat_id, let resolution = match self.resolve_possibly_assoc_item(pat_id,
None, None,
@@ -2484,13 +2484,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// qualified paths should be in PatKind::QPath. // qualified paths should be in PatKind::QPath.
TypecheckRequired => TypecheckRequired =>
self.session.span_bug(path.span, self.session.span_bug(path.span,
"resolve_possibly_assoc_item claimed "resolve_possibly_assoc_item claimed that a path \
\ in PatKind::Path or PatKind::TupleStruct \
that a path in PatKind::Enum requires typecheck requires typecheck to resolve, but qualified \
\ paths should be PatKind::QPath"),
to resolve, but qualified paths should be
\
PatKind::QPath"),
ResolveAttempt(resolution) => resolution, ResolveAttempt(resolution) => resolution,
}; };
if let Some(path_res) = resolution { if let Some(path_res) = resolution {

View File

@@ -665,7 +665,8 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
PatKind::Lit(ref l) => { PatKind::Lit(ref l) => {
ConstantValue(ConstantExpr(&l), debug_loc) ConstantValue(ConstantExpr(&l), debug_loc)
} }
PatKind::Ident(..) | PatKind::Enum(..) | PatKind::Struct(..) => { PatKind::Ident(..) | PatKind::Path(..) |
PatKind::TupleStruct(..) | PatKind::Struct(..) => {
// This is either an enum variant or a variable binding. // This is either an enum variant or a variable binding.
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def()); let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
match opt_def { match opt_def {
@@ -798,16 +799,11 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: usize) -> bool {
let pat = br.pats[col]; let pat = br.pats[col];
match pat.node { match pat.node {
PatKind::Tup(_) => true, PatKind::Tup(_) => true,
PatKind::Struct(..) => { PatKind::Struct(..) | PatKind::TupleStruct(..) |
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) { PatKind::Path(..) | PatKind::Ident(_, _, None) => {
Some(Def::Variant(..)) => false, match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
_ => true, Def::Struct(..) | Def::TyAlias(..) => true,
} _ => false,
}
PatKind::Enum(..) | PatKind::Ident(_, _, None) => {
match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
Some(Def::Struct(..)) => true,
_ => false
} }
} }
_ => false _ => false
@@ -1849,7 +1845,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bcx = bind_irrefutable_pat(bcx, &inner_pat, val, cleanup_scope); bcx = bind_irrefutable_pat(bcx, &inner_pat, val, cleanup_scope);
} }
} }
PatKind::Enum(_, ref sub_pats) => { PatKind::TupleStruct(_, ref sub_pats) => {
let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def()); let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
match opt_def { match opt_def {
Some(Def::Variant(enum_id, var_id)) => { Some(Def::Variant(enum_id, var_id)) => {
@@ -2013,7 +2009,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
cleanup_scope) cleanup_scope)
}); });
} }
PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) | PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) |
PatKind::Range(_, _) => () PatKind::Range(_, _) => ()
} }
return bcx; return bcx;

View File

@@ -239,7 +239,7 @@ fn walk_pattern(cx: &CrateContext,
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
} }
PatKind::Enum(_, ref sub_pats_opt) => { PatKind::TupleStruct(_, ref sub_pats_opt) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
if let Some(ref sub_pats) = *sub_pats_opt { if let Some(ref sub_pats) = *sub_pats_opt {
@@ -249,7 +249,7 @@ fn walk_pattern(cx: &CrateContext,
} }
} }
PatKind::QPath(..) => { PatKind::Path(..) | PatKind::QPath(..) => {
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata); scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
} }

View File

@@ -135,14 +135,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
// subtyping doesn't matter here, as the value is some kind of scalar // subtyping doesn't matter here, as the value is some kind of scalar
demand::eqtype(fcx, pat.span, expected, lhs_ty); demand::eqtype(fcx, pat.span, expected, lhs_ty);
} }
PatKind::Enum(..) | PatKind::Ident(..) PatKind::Path(..) | PatKind::Ident(..)
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => { if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
if let PatKind::Enum(ref path, ref subpats) = pat.node {
if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
bad_struct_kind_err(tcx.sess, pat, path, false);
return;
}
}
if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) { if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
let const_did = pat_def.def_id(); let const_did = pat_def.def_id();
let const_scheme = tcx.lookup_item_type(const_did); let const_scheme = tcx.lookup_item_type(const_did);
@@ -206,10 +200,11 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let path = hir_util::ident_to_path(path.span, path.node); let path = hir_util::ident_to_path(path.span, path.node);
check_pat_enum(pcx, pat, &path, Some(&[]), expected, false); check_pat_enum(pcx, pat, &path, Some(&[]), expected, false);
} }
PatKind::Enum(ref path, ref subpats) => { PatKind::TupleStruct(ref path, ref subpats) => {
let subpats = subpats.as_ref().map(|v| &v[..]); check_pat_enum(pcx, pat, path, subpats.as_ref().map(|v| &v[..]), expected, true);
let is_tuple_struct_pat = !(subpats.is_some() && subpats.unwrap().is_empty()); }
check_pat_enum(pcx, pat, path, subpats, expected, is_tuple_struct_pat); PatKind::Path(ref path) => {
check_pat_enum(pcx, pat, path, None, expected, false);
} }
PatKind::QPath(ref qself, ref path) => { PatKind::QPath(ref qself, ref path) => {
let self_ty = fcx.to_ty(&qself.ty); let self_ty = fcx.to_ty(&qself.ty);

View File

@@ -2554,7 +2554,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
match p.node { match p.node {
PatKind::Wild => "_".to_string(), PatKind::Wild => "_".to_string(),
PatKind::Ident(_, ref p, _) => p.node.to_string(), PatKind::Ident(_, ref p, _) => p.node.to_string(),
PatKind::Enum(ref p, _) => path_to_string(p), PatKind::TupleStruct(ref p, _) | PatKind::Path(ref p) => path_to_string(p),
PatKind::QPath(..) => panic!("tried to get argument name from PatKind::QPath, \ PatKind::QPath(..) => panic!("tried to get argument name from PatKind::QPath, \
which is not allowed in function arguments"), which is not allowed in function arguments"),
PatKind::Struct(ref name, ref fields, etc) => { PatKind::Struct(ref name, ref fields, etc) => {

View File

@@ -580,7 +580,7 @@ pub enum PatKind {
/// An associated const named using the qualified path `<T>::CONST` or /// An associated const named using the qualified path `<T>::CONST` or
/// `<T as Trait>::CONST`. Associated consts from inherent impls can be /// `<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 /// 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), QPath(QSelf, Path),
/// A tuple pattern `(a, b)` /// A tuple pattern `(a, b)`