Skip to content

Commit 06755d9

Browse files
committed
Split PatKind::Enum into PatKind::TupleStruct and PatKind::Path
1 parent 9b40e1e commit 06755d9

File tree

22 files changed

+137
-142
lines changed

22 files changed

+137
-142
lines changed

src/librustc/middle/cfg/construct.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
100100
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
101101
match pat.node {
102102
PatKind::Ident(_, _, None) |
103-
PatKind::Enum(_, None) |
103+
PatKind::TupleStruct(_, None) |
104+
PatKind::Path(..) |
104105
PatKind::QPath(..) |
105106
PatKind::Lit(..) |
106107
PatKind::Range(..) |
@@ -115,7 +116,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
115116
self.add_ast_node(pat.id, &[subpat_exit])
116117
}
117118

118-
PatKind::Enum(_, Some(ref subpats)) |
119+
PatKind::TupleStruct(_, Some(ref subpats)) |
119120
PatKind::Tup(ref subpats) => {
120121
let pats_exit = self.pats_all(subpats.iter(), pred);
121122
self.add_ast_node(pat.id, &[pats_exit])

src/librustc/middle/check_match.rs

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir:
377377
hir::MatchSource::ForLoopDesugar => {
378378
// `witnesses[0]` has the form `Some(<head>)`, peel off the `Some`
379379
let witness = match witnesses[0].node {
380-
PatKind::Enum(_, Some(ref pats)) => match &pats[..] {
380+
PatKind::TupleStruct(_, Some(ref pats)) => match &pats[..] {
381381
[ref pat] => &**pat,
382382
_ => unreachable!(),
383383
},
@@ -466,7 +466,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
466466
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
467467
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
468468
return match pat.node {
469-
PatKind::Ident(..) | PatKind::Enum(..) | PatKind::QPath(..) => {
469+
PatKind::Ident(..) | PatKind::Path(..) | PatKind::QPath(..) => {
470470
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
471471
match def {
472472
Some(Def::AssociatedConst(did)) |
@@ -534,22 +534,28 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
534534

535535
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
536536
let v = adt.variant_of_ctor(ctor);
537-
if let VariantKind::Struct = v.kind() {
538-
let field_pats: hir::HirVec<_> = v.fields.iter()
539-
.zip(pats)
540-
.filter(|&(_, ref pat)| pat.node != PatKind::Wild)
541-
.map(|(field, pat)| Spanned {
542-
span: DUMMY_SP,
543-
node: hir::FieldPat {
544-
name: field.name,
545-
pat: pat,
546-
is_shorthand: false,
547-
}
548-
}).collect();
549-
let has_more_fields = field_pats.len() < pats_len;
550-
PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
551-
} else {
552-
PatKind::Enum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
537+
match v.kind() {
538+
VariantKind::Struct => {
539+
let field_pats: hir::HirVec<_> = v.fields.iter()
540+
.zip(pats)
541+
.filter(|&(_, ref pat)| pat.node != PatKind::Wild)
542+
.map(|(field, pat)| Spanned {
543+
span: DUMMY_SP,
544+
node: hir::FieldPat {
545+
name: field.name,
546+
pat: pat,
547+
is_shorthand: false,
548+
}
549+
}).collect();
550+
let has_more_fields = field_pats.len() < pats_len;
551+
PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
552+
}
553+
VariantKind::Tuple => {
554+
PatKind::TupleStruct(def_to_path(cx.tcx, v.did), Some(pats.collect()))
555+
}
556+
VariantKind::Unit => {
557+
PatKind::Path(def_to_path(cx.tcx, v.did))
558+
}
553559
}
554560
}
555561

@@ -769,34 +775,20 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
769775
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
770776
let pat = raw_pat(p);
771777
match pat.node {
772-
PatKind::Ident(..) =>
773-
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
774-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
775-
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
776-
been rewritten"),
777-
Some(Def::Struct(..)) => vec!(Single),
778-
Some(Def::Variant(_, id)) => vec!(Variant(id)),
779-
_ => vec!()
780-
},
781-
PatKind::Enum(..) =>
782-
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
783-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
778+
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) =>
779+
match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
780+
Def::Const(..) | Def::AssociatedConst(..) =>
784781
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
785782
been rewritten"),
786-
Some(Def::Variant(_, id)) => vec!(Variant(id)),
787-
_ => vec!(Single)
783+
Def::Struct(..) | Def::TyAlias(..) => vec![Single],
784+
Def::Variant(_, id) => vec![Variant(id)],
785+
Def::Local(..) => vec![],
786+
def => cx.tcx.sess.span_bug(pat.span, &format!("pat_constructors: unexpected \
787+
definition {:?}", def)),
788788
},
789789
PatKind::QPath(..) =>
790790
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
791791
been rewritten"),
792-
PatKind::Struct(..) =>
793-
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
794-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
795-
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
796-
been rewritten"),
797-
Some(Def::Variant(_, id)) => vec!(Variant(id)),
798-
_ => vec!(Single)
799-
},
800792
PatKind::Lit(ref expr) =>
801793
vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))),
802794
PatKind::Range(ref lo, ref hi) =>
@@ -880,22 +872,21 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
880872
PatKind::Wild =>
881873
Some(vec![DUMMY_WILD_PAT; arity]),
882874

883-
PatKind::Ident(_, _, _) => {
884-
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
885-
match opt_def {
886-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
875+
PatKind::Path(..) | PatKind::Ident(..) => {
876+
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
877+
match def {
878+
Def::Const(..) | Def::AssociatedConst(..) =>
887879
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
888880
been rewritten"),
889-
Some(Def::Variant(_, id)) => if *constructor == Variant(id) {
890-
Some(vec!())
891-
} else {
892-
None
893-
},
894-
_ => Some(vec![DUMMY_WILD_PAT; arity])
881+
Def::Variant(_, id) if *constructor != Variant(id) => None,
882+
Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
883+
Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]),
884+
_ => cx.tcx.sess.span_bug(pat_span, &format!("specialize: unexpected \
885+
definition {:?}", def)),
895886
}
896887
}
897888

898-
PatKind::Enum(_, ref args) => {
889+
PatKind::TupleStruct(_, ref args) => {
899890
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
900891
match def {
901892
Def::Const(..) | Def::AssociatedConst(..) =>

src/librustc/middle/const_eval.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
343343
_ => unreachable!()
344344
};
345345
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
346-
PatKind::Enum(path, Some(pats))
346+
PatKind::TupleStruct(path, Some(pats))
347347
}
348348

349349
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>
366366
hir::ExprPath(_, ref path) => {
367367
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
368368
match opt_def {
369-
Some(Def::Struct(..)) =>
370-
PatKind::Struct(path.clone(), hir::HirVec::new(), false),
371-
Some(Def::Variant(..)) =>
372-
PatKind::Enum(path.clone(), None),
369+
Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
370+
PatKind::Path(path.clone()),
373371
Some(Def::Const(def_id)) |
374372
Some(Def::AssociatedConst(def_id)) => {
375373
let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();

src/librustc/middle/expr_use_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
10701070
let tcx = typer.tcx;
10711071

10721072
match pat.node {
1073-
PatKind::Enum(_, _) | PatKind::QPath(..) |
1073+
PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
10741074
PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
10751075
match def_map.get(&pat.id).map(|d| d.full_def()) {
10761076
None => {

src/librustc/middle/mem_categorization.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
12091209
None
12101210
};
12111211

1212-
// Note: This goes up here (rather than within the PatKind::Enum arm
1212+
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
12131213
// alone) because struct patterns can refer to struct types or
12141214
// to struct variants within enums.
12151215
let cmt = match opt_def {
@@ -1226,10 +1226,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
12261226
// _
12271227
}
12281228

1229-
PatKind::Enum(_, None) => {
1229+
PatKind::TupleStruct(_, None) => {
12301230
// variant(..)
12311231
}
1232-
PatKind::Enum(_, Some(ref subpats)) => {
1232+
PatKind::TupleStruct(_, Some(ref subpats)) => {
12331233
match opt_def {
12341234
Some(Def::Variant(..)) => {
12351235
// variant(x, y, z)
@@ -1267,18 +1267,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
12671267
}
12681268
}
12691269

1270-
PatKind::QPath(..) => {
1271-
// Lone constant: ignore
1270+
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
1271+
// Lone constant, or unit variant or identifier: ignore
12721272
}
12731273

12741274
PatKind::Ident(_, _, Some(ref subpat)) => {
12751275
try!(self.cat_pattern_(cmt, &subpat, op));
12761276
}
12771277

1278-
PatKind::Ident(_, _, None) => {
1279-
// nullary variant or identifier: ignore
1280-
}
1281-
12821278
PatKind::Struct(_, ref field_pats, _) => {
12831279
// {f1: p1, ..., fN: pN}
12841280
for fp in field_pats {

src/librustc/middle/pat_util.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ pub fn pat_id_map(dm: &RefCell<DefMap>, pat: &hir::Pat) -> PatIdMap {
3535
pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
3636
match pat.node {
3737
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
38-
PatKind::Enum(_, _) |
38+
PatKind::TupleStruct(..) |
39+
PatKind::Path(..) |
3940
PatKind::Ident(_, _, None) |
4041
PatKind::Struct(..) => {
4142
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 {
5051

5152
pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
5253
match pat.node {
53-
PatKind::Enum(_, _) |
54+
PatKind::TupleStruct(..) |
55+
PatKind::Path(..) |
5456
PatKind::Ident(_, _, None) |
5557
PatKind::Struct(..) => {
5658
match dm.get(&pat.id).map(|d| d.full_def()) {
57-
Some(Def::Variant(..)) | Some(Def::Struct(..)) => true,
59+
Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true,
5860
_ => false
5961
}
6062
}
@@ -64,7 +66,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
6466

6567
pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
6668
match pat.node {
67-
PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => {
69+
PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
6870
match dm.get(&pat.id).map(|d| d.full_def()) {
6971
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
7072
_ => false
@@ -78,7 +80,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
7880
// returned instead of a panic.
7981
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
8082
match pat.node {
81-
PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => {
83+
PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
8284
match dm.get(&pat.id)
8385
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
8486
else { None } ) {
@@ -224,7 +226,8 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
224226
let mut variants = vec![];
225227
walk_pat(pat, |p| {
226228
match p.node {
227-
PatKind::Enum(_, _) |
229+
PatKind::TupleStruct(..) |
230+
PatKind::Path(..) |
228231
PatKind::Ident(_, _, None) |
229232
PatKind::Struct(..) => {
230233
match dm.get(&p.id) {

src/librustc/middle/region.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
970970
pats3.iter().any(|p| is_binding_pat(&p))
971971
}
972972

973-
PatKind::Enum(_, Some(ref subpats)) |
973+
PatKind::TupleStruct(_, Some(ref subpats)) |
974974
PatKind::Tup(ref subpats) => {
975975
subpats.iter().any(|p| is_binding_pat(&p))
976976
}

src/librustc/middle/stability.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,8 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
598598
};
599599
match pat.node {
600600
// Foo(a, b, c)
601-
// A Variant(..) pattern `PatKind::Enum(_, None)` doesn't have to be recursed into.
602-
PatKind::Enum(_, Some(ref pat_fields)) => {
601+
// A Variant(..) pattern `PatKind::TupleStruct(_, None)` doesn't have to be recursed into.
602+
PatKind::TupleStruct(_, Some(ref pat_fields)) => {
603603
for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
604604
maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
605605
}

src/librustc_front/fold.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,13 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
972972
sub.map(|x| folder.fold_pat(x)))
973973
}
974974
PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
975-
PatKind::Enum(pth, pats) => {
976-
PatKind::Enum(folder.fold_path(pth),
975+
PatKind::TupleStruct(pth, pats) => {
976+
PatKind::TupleStruct(folder.fold_path(pth),
977977
pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
978978
}
979+
PatKind::Path(pth) => {
980+
PatKind::Path(folder.fold_path(pth))
981+
}
979982
PatKind::QPath(qself, pth) => {
980983
let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself };
981984
PatKind::QPath(qself, folder.fold_path(pth))

src/librustc_front/hir.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -509,28 +509,34 @@ pub enum PatKind {
509509
/// Represents a wildcard pattern (`_`)
510510
Wild,
511511

512-
/// A PatKind::Ident may either be a new bound variable,
513-
/// or a nullary enum (in which case the third field
514-
/// is None).
512+
/// A `PatKind::Ident` may either be a new bound variable,
513+
/// or a unit struct/variant pattern, or a const pattern (in the last two cases
514+
/// the third field must be `None`).
515515
///
516-
/// In the nullary enum case, the parser can't determine
516+
/// In the unit or const pattern case, the parser can't determine
517517
/// which it is. The resolver determines this, and
518-
/// records this pattern's NodeId in an auxiliary
519-
/// set (of "PatIdents that refer to nullary enums")
518+
/// records this pattern's `NodeId` in an auxiliary
519+
/// set (of "PatIdents that refer to unit patterns or constants").
520520
Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>),
521521

522+
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
523+
/// The `bool` is `true` in the presence of a `..`.
524+
Struct(Path, HirVec<Spanned<FieldPat>>, bool),
525+
526+
/// A tuple struct/variant pattern `Variant(x, y, z)`.
522527
/// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
523-
Enum(Path, Option<HirVec<P<Pat>>>),
528+
TupleStruct(Path, Option<HirVec<P<Pat>>>),
529+
530+
/// A path pattern.
531+
/// Such pattern can be resolved to a unit struct/variant or a constant.
532+
Path(Path),
524533

525534
/// An associated const named using the qualified path `<T>::CONST` or
526535
/// `<T as Trait>::CONST`. Associated consts from inherent impls can be
527536
/// referred to as simply `T::CONST`, in which case they will end up as
528-
/// PatKind::Enum, and the resolver will have to sort that out.
537+
/// PatKind::Path, and the resolver will have to sort that out.
529538
QPath(QSelf, Path),
530539

531-
/// Destructuring of a struct, e.g. `Foo {x, y, ..}`
532-
/// The `bool` is `true` in the presence of a `..`
533-
Struct(Path, HirVec<Spanned<FieldPat>>, bool),
534540
/// A tuple pattern `(a, b)`
535541
Tup(HirVec<P<Pat>>),
536542
/// A `box` pattern

src/librustc_front/intravisit.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,15 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
468468

469469
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
470470
match pattern.node {
471-
PatKind::Enum(ref path, ref opt_children) => {
471+
PatKind::TupleStruct(ref path, ref opt_children) => {
472472
visitor.visit_path(path, pattern.id);
473473
if let Some(ref children) = *opt_children {
474474
walk_list!(visitor, visit_pat, children);
475475
}
476476
}
477+
PatKind::Path(ref path) => {
478+
visitor.visit_path(path, pattern.id);
479+
}
477480
PatKind::QPath(ref qself, ref path) => {
478481
visitor.visit_ty(&qself.ty);
479482
visitor.visit_path(path, pattern.id)

0 commit comments

Comments
 (0)