Split PatKind::Enum into PatKind::TupleStruct and PatKind::Path
This commit is contained in:
parent
9b40e1e5b3
commit
06755d90ce
22 changed files with 137 additions and 142 deletions
|
|
@ -100,7 +100,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
|
||||
match pat.node {
|
||||
PatKind::Ident(_, _, None) |
|
||||
PatKind::Enum(_, None) |
|
||||
PatKind::TupleStruct(_, None) |
|
||||
PatKind::Path(..) |
|
||||
PatKind::QPath(..) |
|
||||
PatKind::Lit(..) |
|
||||
PatKind::Range(..) |
|
||||
|
|
@ -115,7 +116,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
self.add_ast_node(pat.id, &[subpat_exit])
|
||||
}
|
||||
|
||||
PatKind::Enum(_, Some(ref subpats)) |
|
||||
PatKind::TupleStruct(_, Some(ref subpats)) |
|
||||
PatKind::Tup(ref subpats) => {
|
||||
let pats_exit = self.pats_all(subpats.iter(), pred);
|
||||
self.add_ast_node(pat.id, &[pats_exit])
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir:
|
|||
hir::MatchSource::ForLoopDesugar => {
|
||||
// `witnesses[0]` has the form `Some(<head>)`, peel off the `Some`
|
||||
let witness = match witnesses[0].node {
|
||||
PatKind::Enum(_, Some(ref pats)) => match &pats[..] {
|
||||
PatKind::TupleStruct(_, Some(ref pats)) => match &pats[..] {
|
||||
[ref pat] => &**pat,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|
|
@ -466,7 +466,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
|
|||
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
||||
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
||||
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());
|
||||
match def {
|
||||
Some(Def::AssociatedConst(did)) |
|
||||
|
|
@ -534,22 +534,28 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
|
|||
|
||||
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
|
||||
let v = adt.variant_of_ctor(ctor);
|
||||
if let VariantKind::Struct = v.kind() {
|
||||
let field_pats: hir::HirVec<_> = v.fields.iter()
|
||||
.zip(pats)
|
||||
.filter(|&(_, ref pat)| pat.node != PatKind::Wild)
|
||||
.map(|(field, pat)| Spanned {
|
||||
span: DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
name: field.name,
|
||||
pat: pat,
|
||||
is_shorthand: false,
|
||||
}
|
||||
}).collect();
|
||||
let has_more_fields = field_pats.len() < pats_len;
|
||||
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()))
|
||||
match v.kind() {
|
||||
VariantKind::Struct => {
|
||||
let field_pats: hir::HirVec<_> = v.fields.iter()
|
||||
.zip(pats)
|
||||
.filter(|&(_, ref pat)| pat.node != PatKind::Wild)
|
||||
.map(|(field, pat)| Spanned {
|
||||
span: DUMMY_SP,
|
||||
node: hir::FieldPat {
|
||||
name: field.name,
|
||||
pat: pat,
|
||||
is_shorthand: false,
|
||||
}
|
||||
}).collect();
|
||||
let has_more_fields = field_pats.len() < pats_len;
|
||||
PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
|
||||
}
|
||||
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> {
|
||||
let pat = raw_pat(p);
|
||||
match pat.node {
|
||||
PatKind::Ident(..) =>
|
||||
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
|
||||
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) =>
|
||||
match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||
been rewritten"),
|
||||
Some(Def::Struct(..)) => vec!(Single),
|
||||
Some(Def::Variant(_, id)) => vec!(Variant(id)),
|
||||
_ => vec!()
|
||||
},
|
||||
PatKind::Enum(..) =>
|
||||
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)
|
||||
Def::Struct(..) | Def::TyAlias(..) => vec![Single],
|
||||
Def::Variant(_, id) => vec![Variant(id)],
|
||||
Def::Local(..) => vec![],
|
||||
def => cx.tcx.sess.span_bug(pat.span, &format!("pat_constructors: unexpected \
|
||||
definition {:?}", def)),
|
||||
},
|
||||
PatKind::QPath(..) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||
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) =>
|
||||
vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))),
|
||||
PatKind::Range(ref lo, ref hi) =>
|
||||
|
|
@ -880,22 +872,21 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
|||
PatKind::Wild =>
|
||||
Some(vec![DUMMY_WILD_PAT; arity]),
|
||||
|
||||
PatKind::Ident(_, _, _) => {
|
||||
let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
|
||||
match opt_def {
|
||||
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
|
||||
PatKind::Path(..) | PatKind::Ident(..) => {
|
||||
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
|
||||
match def {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
Some(Def::Variant(_, id)) => if *constructor == Variant(id) {
|
||||
Some(vec!())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
_ => Some(vec![DUMMY_WILD_PAT; arity])
|
||||
Def::Variant(_, id) if *constructor != Variant(id) => None,
|
||||
Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
|
||||
Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]),
|
||||
_ => cx.tcx.sess.span_bug(pat_span, &format!("specialize: unexpected \
|
||||
definition {:?}", def)),
|
||||
}
|
||||
}
|
||||
|
||||
PatKind::Enum(_, ref args) => {
|
||||
PatKind::TupleStruct(_, ref args) => {
|
||||
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
|
||||
match def {
|
||||
Def::Const(..) | Def::AssociatedConst(..) =>
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
|
|||
_ => unreachable!()
|
||||
};
|
||||
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) => {
|
||||
|
|
@ -366,10 +366,8 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
|
|||
hir::ExprPath(_, ref path) => {
|
||||
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
|
||||
match opt_def {
|
||||
Some(Def::Struct(..)) =>
|
||||
PatKind::Struct(path.clone(), hir::HirVec::new(), false),
|
||||
Some(Def::Variant(..)) =>
|
||||
PatKind::Enum(path.clone(), None),
|
||||
Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
|
||||
PatKind::Path(path.clone()),
|
||||
Some(Def::Const(def_id)) |
|
||||
Some(Def::AssociatedConst(def_id)) => {
|
||||
let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
|
||||
|
|
|
|||
|
|
@ -1070,7 +1070,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
|
|||
let tcx = typer.tcx;
|
||||
|
||||
match pat.node {
|
||||
PatKind::Enum(_, _) | PatKind::QPath(..) |
|
||||
PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
|
||||
PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
|
||||
match def_map.get(&pat.id).map(|d| d.full_def()) {
|
||||
None => {
|
||||
|
|
|
|||
|
|
@ -1209,7 +1209,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
|
|||
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
|
||||
// to struct variants within enums.
|
||||
let cmt = match opt_def {
|
||||
|
|
@ -1226,10 +1226,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
|
|||
// _
|
||||
}
|
||||
|
||||
PatKind::Enum(_, None) => {
|
||||
PatKind::TupleStruct(_, None) => {
|
||||
// variant(..)
|
||||
}
|
||||
PatKind::Enum(_, Some(ref subpats)) => {
|
||||
PatKind::TupleStruct(_, Some(ref subpats)) => {
|
||||
match opt_def {
|
||||
Some(Def::Variant(..)) => {
|
||||
// variant(x, y, z)
|
||||
|
|
@ -1267,18 +1267,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
PatKind::QPath(..) => {
|
||||
// Lone constant: ignore
|
||||
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
|
||||
// Lone constant, or unit variant or identifier: ignore
|
||||
}
|
||||
|
||||
PatKind::Ident(_, _, Some(ref subpat)) => {
|
||||
try!(self.cat_pattern_(cmt, &subpat, op));
|
||||
}
|
||||
|
||||
PatKind::Ident(_, _, None) => {
|
||||
// nullary variant or identifier: ignore
|
||||
}
|
||||
|
||||
PatKind::Struct(_, ref field_pats, _) => {
|
||||
// {f1: p1, ..., fN: pN}
|
||||
for fp in field_pats {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
match pat.node {
|
||||
PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
|
||||
PatKind::Enum(_, _) |
|
||||
PatKind::TupleStruct(..) |
|
||||
PatKind::Path(..) |
|
||||
PatKind::Ident(_, _, None) |
|
||||
PatKind::Struct(..) => {
|
||||
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 {
|
||||
match pat.node {
|
||||
PatKind::Enum(_, _) |
|
||||
PatKind::TupleStruct(..) |
|
||||
PatKind::Path(..) |
|
||||
PatKind::Ident(_, _, None) |
|
||||
PatKind::Struct(..) => {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
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()) {
|
||||
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
|
||||
_ => false
|
||||
|
|
@ -78,7 +80,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
|
|||
// returned instead of a panic.
|
||||
pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
|
||||
match pat.node {
|
||||
PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => {
|
||||
PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
|
||||
match dm.get(&pat.id)
|
||||
.and_then(|d| if d.depth == 0 { Some(d.base_def) }
|
||||
else { None } ) {
|
||||
|
|
@ -224,7 +226,8 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
|
|||
let mut variants = vec![];
|
||||
walk_pat(pat, |p| {
|
||||
match p.node {
|
||||
PatKind::Enum(_, _) |
|
||||
PatKind::TupleStruct(..) |
|
||||
PatKind::Path(..) |
|
||||
PatKind::Ident(_, _, None) |
|
||||
PatKind::Struct(..) => {
|
||||
match dm.get(&p.id) {
|
||||
|
|
|
|||
|
|
@ -970,7 +970,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
|
|||
pats3.iter().any(|p| is_binding_pat(&p))
|
||||
}
|
||||
|
||||
PatKind::Enum(_, Some(ref subpats)) |
|
||||
PatKind::TupleStruct(_, Some(ref subpats)) |
|
||||
PatKind::Tup(ref subpats) => {
|
||||
subpats.iter().any(|p| is_binding_pat(&p))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -598,8 +598,8 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
|
|||
};
|
||||
match pat.node {
|
||||
// Foo(a, b, c)
|
||||
// A Variant(..) pattern `PatKind::Enum(_, None)` doesn't have to be recursed into.
|
||||
PatKind::Enum(_, Some(ref pat_fields)) => {
|
||||
// A Variant(..) pattern `PatKind::TupleStruct(_, None)` doesn't have to be recursed into.
|
||||
PatKind::TupleStruct(_, Some(ref pat_fields)) => {
|
||||
for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
|
||||
maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue