Skip to content

Commit ba419a7

Browse files
committed
Cleanup of some pattern related code
1 parent d3c94b2 commit ba419a7

File tree

5 files changed

+94
-213
lines changed

5 files changed

+94
-213
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 39 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -945,52 +945,41 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
945945
/// The core driver for walking a pattern; `match_mode` must be
946946
/// established up front, e.g. via `determine_pat_move_mode` (see
947947
/// also `walk_irrefutable_pat` for patterns that stand alone).
948-
fn walk_pat(&mut self,
949-
cmt_discr: mc::cmt<'tcx>,
950-
pat: &hir::Pat,
951-
match_mode: MatchMode) {
952-
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr,
953-
pat);
948+
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
949+
debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
954950

955951
let tcx = &self.tcx();
956952
let mc = &self.mc;
957953
let infcx = self.mc.infcx;
958954
let delegate = &mut self.delegate;
959955
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
960-
match pat.node {
961-
PatKind::Binding(bmode, _, _) => {
962-
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}",
963-
cmt_pat,
964-
pat,
965-
match_mode);
966-
967-
// pat_ty: the type of the binding being produced.
968-
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
969-
970-
// Each match binding is effectively an assignment to the
971-
// binding being produced.
972-
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty,
973-
tcx.expect_def(pat.id)) {
974-
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
975-
}
956+
if let PatKind::Binding(bmode, _, _) = pat.node {
957+
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
976958

977-
// It is also a borrow or copy/move of the value being matched.
978-
match bmode {
979-
hir::BindByRef(m) => {
980-
if let ty::TyRef(&r, _) = pat_ty.sty {
981-
let bk = ty::BorrowKind::from_mutbl(m);
982-
delegate.borrow(pat.id, pat.span, cmt_pat,
983-
r, bk, RefBinding);
984-
}
985-
}
986-
hir::BindByValue(..) => {
987-
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
988-
debug!("walk_pat binding consuming pat");
989-
delegate.consume_pat(pat, cmt_pat, mode);
959+
// pat_ty: the type of the binding being produced.
960+
let pat_ty = return_if_err!(infcx.node_ty(pat.id));
961+
962+
// Each match binding is effectively an assignment to the
963+
// binding being produced.
964+
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty,
965+
tcx.expect_def(pat.id)) {
966+
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
967+
}
968+
969+
// It is also a borrow or copy/move of the value being matched.
970+
match bmode {
971+
hir::BindByRef(m) => {
972+
if let ty::TyRef(&r, _) = pat_ty.sty {
973+
let bk = ty::BorrowKind::from_mutbl(m);
974+
delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding);
990975
}
991976
}
977+
hir::BindByValue(..) => {
978+
let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
979+
debug!("walk_pat binding consuming pat");
980+
delegate.consume_pat(pat, cmt_pat, mode);
981+
}
992982
}
993-
_ => {}
994983
}
995984
}));
996985

@@ -999,72 +988,23 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
999988
// to the above loop's visit of than the bindings that form
1000989
// the leaves of the pattern tree structure.
1001990
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
1002-
match pat.node {
1003-
PatKind::Struct(..) | PatKind::TupleStruct(..) |
1004-
PatKind::Path(..) | PatKind::QPath(..) => {
1005-
match tcx.expect_def(pat.id) {
1006-
Def::Variant(enum_did, variant_did) => {
1007-
let downcast_cmt =
1008-
if tcx.lookup_adt_def(enum_did).is_univariant() {
1009-
cmt_pat
1010-
} else {
1011-
let cmt_pat_ty = cmt_pat.ty;
1012-
mc.cat_downcast(pat, cmt_pat, cmt_pat_ty, variant_did)
1013-
};
1014-
1015-
debug!("variant downcast_cmt={:?} pat={:?}",
1016-
downcast_cmt,
1017-
pat);
1018-
1019-
delegate.matched_pat(pat, downcast_cmt, match_mode);
1020-
}
1021-
1022-
Def::Struct(..) | Def::TyAlias(..) => {
1023-
// A struct (in either the value or type
1024-
// namespace; we encounter the former on
1025-
// e.g. patterns for unit structs).
1026-
1027-
debug!("struct cmt_pat={:?} pat={:?}",
1028-
cmt_pat,
1029-
pat);
1030-
1031-
delegate.matched_pat(pat, cmt_pat, match_mode);
1032-
}
1033-
1034-
Def::Const(..) | Def::AssociatedConst(..) => {
1035-
// This is a leaf (i.e. identifier binding
1036-
// or constant value to match); thus no
1037-
// `matched_pat` call.
1038-
}
991+
match tcx.expect_def_or_none(pat.id) {
992+
Some(Def::Variant(enum_did, variant_did)) => {
993+
let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() {
994+
cmt_pat
995+
} else {
996+
let cmt_pat_ty = cmt_pat.ty;
997+
mc.cat_downcast(pat, cmt_pat, cmt_pat_ty, variant_did)
998+
};
1039999

1040-
def => {
1041-
// An enum type should never be in a pattern.
1042-
// Remaining cases are e.g. Def::Fn, to
1043-
// which identifiers within patterns
1044-
// should not resolve. However, we do
1045-
// encouter this when using the
1046-
// expr-use-visitor during typeck. So just
1047-
// ignore it, an error should have been
1048-
// reported.
1049-
1050-
if !tcx.sess.has_errors() {
1051-
span_bug!(pat.span,
1052-
"Pattern has unexpected def: {:?} and type {:?}",
1053-
def,
1054-
cmt_pat.ty);
1055-
}
1056-
}
1057-
}
1000+
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
1001+
delegate.matched_pat(pat, downcast_cmt, match_mode);
10581002
}
1059-
1060-
PatKind::Wild | PatKind::Tuple(..) | PatKind::Box(..) |
1061-
PatKind::Ref(..) | PatKind::Lit(..) | PatKind::Range(..) |
1062-
PatKind::Vec(..) | PatKind::Binding(..) => {
1063-
// Each of these cases does not
1064-
// correspond to an enum variant or struct, so we
1065-
// do not do any `matched_pat` calls for these
1066-
// cases either.
1003+
Some(Def::Struct(..)) | Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => {
1004+
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
1005+
delegate.matched_pat(pat, cmt_pat, match_mode);
10671006
}
1007+
_ => {}
10681008
}
10691009
}));
10701010
}

src/librustc/middle/mem_categorization.rs

Lines changed: 43 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,9 +1050,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10501050
}
10511051

10521052
// FIXME(#19596) This is a workaround, but there should be a better way to do this
1053-
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F)
1054-
-> McResult<()>
1055-
where F : FnMut(&MemCategorizationContext<'a, 'gcx, 'tcx>, cmt<'tcx>, &hir::Pat),
1053+
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResult<()>
1054+
where F : FnMut(&MemCategorizationContext<'a, 'gcx, 'tcx>, cmt<'tcx>, &hir::Pat)
10561055
{
10571056
// Here, `cmt` is the categorization for the value being
10581057
// matched and pat is the pattern it is being matched against.
@@ -1099,21 +1098,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10991098
// step out of sync again. So you'll see below that we always
11001099
// get the type of the *subpattern* and use that.
11011100

1102-
debug!("cat_pattern: {:?} cmt={:?}",
1103-
pat,
1104-
cmt);
1105-
1106-
(*op)(self, cmt.clone(), pat);
1101+
debug!("cat_pattern: {:?} cmt={:?}", pat, cmt);
11071102

1108-
let opt_def = self.tcx().expect_def_or_none(pat.id);
1109-
if opt_def == Some(Def::Err) {
1110-
return Err(());
1111-
}
1103+
op(self, cmt.clone(), pat);
11121104

11131105
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
1114-
// alone) because struct patterns can refer to struct types or
1115-
// to struct variants within enums.
1116-
let cmt = match opt_def {
1106+
// alone) because PatKind::Struct can also refer to variants.
1107+
let cmt = match self.tcx().expect_def_or_none(pat.id) {
1108+
Some(Def::Err) => return Err(()),
11171109
Some(Def::Variant(enum_did, variant_did))
11181110
// univariant enums do not need downcasts
11191111
if !self.tcx().lookup_adt_def(enum_did).is_univariant() => {
@@ -1123,66 +1115,33 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11231115
};
11241116

11251117
match pat.node {
1126-
PatKind::Wild => {
1127-
// _
1128-
}
1129-
11301118
PatKind::TupleStruct(_, ref subpats, ddpos) => {
1131-
match opt_def {
1132-
Some(Def::Variant(enum_def, def_id)) => {
1133-
// variant(x, y, z)
1134-
let expected_len = self.tcx().lookup_adt_def(enum_def)
1135-
.variant_with_id(def_id).fields.len();
1136-
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
1137-
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
1138-
1139-
let subcmt =
1140-
self.cat_imm_interior(
1141-
pat, cmt.clone(), subpat_ty,
1142-
InteriorField(PositionalField(i)));
1143-
1144-
self.cat_pattern_(subcmt, &subpat, op)?;
1145-
}
1119+
let expected_len = match self.tcx().expect_def(pat.id) {
1120+
Def::Variant(enum_def, def_id) => {
1121+
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
11461122
}
1147-
Some(Def::Struct(..)) => {
1148-
let expected_len = match self.pat_ty(&pat)?.sty {
1123+
Def::Struct(..) => {
1124+
match self.pat_ty(&pat)?.sty {
11491125
ty::TyStruct(adt_def, _) => {
11501126
adt_def.struct_variant().fields.len()
11511127
}
11521128
ref ty => {
11531129
span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
11541130
}
1155-
};
1156-
1157-
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
1158-
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
1159-
let cmt_field =
1160-
self.cat_imm_interior(
1161-
pat, cmt.clone(), subpat_ty,
1162-
InteriorField(PositionalField(i)));
1163-
self.cat_pattern_(cmt_field, &subpat, op)?;
11641131
}
11651132
}
1166-
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {
1167-
for subpat in subpats {
1168-
self.cat_pattern_(cmt.clone(), &subpat, op)?;
1169-
}
1170-
}
1171-
_ => {
1172-
span_bug!(
1173-
pat.span,
1174-
"enum pattern didn't resolve to enum or struct {:?}",
1175-
opt_def);
1133+
def => {
1134+
span_bug!(pat.span, "tuple struct pattern didn't resolve \
1135+
to variant or struct {:?}", def);
11761136
}
1177-
}
1178-
}
1179-
1180-
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) => {
1181-
// Lone constant, or unit variant or identifier: ignore
1182-
}
1137+
};
11831138

1184-
PatKind::Binding(_, _, Some(ref subpat)) => {
1185-
self.cat_pattern_(cmt, &subpat, op)?;
1139+
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
1140+
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
1141+
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
1142+
InteriorField(PositionalField(i)));
1143+
self.cat_pattern_(subcmt, &subpat, op)?;
1144+
}
11861145
}
11871146

11881147
PatKind::Struct(_, ref field_pats, _) => {
@@ -1194,6 +1153,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11941153
}
11951154
}
11961155

1156+
PatKind::Binding(_, _, Some(ref subpat)) => {
1157+
self.cat_pattern_(cmt, &subpat, op)?;
1158+
}
1159+
11971160
PatKind::Tuple(ref subpats, ddpos) => {
11981161
// (p1, ..., pN)
11991162
let expected_len = match self.pat_ty(&pat)?.sty {
@@ -1202,10 +1165,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12021165
};
12031166
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
12041167
let subpat_ty = self.pat_ty(&subpat)?; // see (*2)
1205-
let subcmt =
1206-
self.cat_imm_interior(
1207-
pat, cmt.clone(), subpat_ty,
1208-
InteriorField(PositionalField(i)));
1168+
let subcmt = self.cat_imm_interior(pat, cmt.clone(), subpat_ty,
1169+
InteriorField(PositionalField(i)));
12091170
self.cat_pattern_(subcmt, &subpat, op)?;
12101171
}
12111172
}
@@ -1215,25 +1176,26 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12151176
// PatKind::Ref since that information is already contained
12161177
// in the type.
12171178
let subcmt = self.cat_deref(pat, cmt, 0, None)?;
1218-
self.cat_pattern_(subcmt, &subpat, op)?;
1179+
self.cat_pattern_(subcmt, &subpat, op)?;
12191180
}
12201181

12211182
PatKind::Vec(ref before, ref slice, ref after) => {
1222-
let context = InteriorOffsetKind::Pattern;
1223-
let elt_cmt = self.cat_index(pat, cmt, context)?;
1224-
for before_pat in before {
1225-
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
1226-
}
1227-
if let Some(ref slice_pat) = *slice {
1228-
self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
1229-
}
1230-
for after_pat in after {
1231-
self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
1232-
}
1183+
let context = InteriorOffsetKind::Pattern;
1184+
let elt_cmt = self.cat_index(pat, cmt, context)?;
1185+
for before_pat in before {
1186+
self.cat_pattern_(elt_cmt.clone(), &before_pat, op)?;
1187+
}
1188+
if let Some(ref slice_pat) = *slice {
1189+
self.cat_pattern_(elt_cmt.clone(), &slice_pat, op)?;
1190+
}
1191+
for after_pat in after {
1192+
self.cat_pattern_(elt_cmt.clone(), &after_pat, op)?;
1193+
}
12331194
}
12341195

1235-
PatKind::Lit(_) | PatKind::Range(_, _) => {
1236-
/*always ok*/
1196+
PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) |
1197+
PatKind::Lit(..) | PatKind::Range(..) | PatKind::Wild => {
1198+
// always ok
12371199
}
12381200
}
12391201

src/librustc_const_eval/check_match.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -784,18 +784,14 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
784784
left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
785785
let pat = raw_pat(p);
786786
match pat.node {
787-
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
787+
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) =>
788788
match cx.tcx.expect_def(pat.id) {
789-
Def::Const(..) | Def::AssociatedConst(..) =>
790-
span_bug!(pat.span, "const pattern should've \
791-
been rewritten"),
792-
Def::Struct(..) | Def::TyAlias(..) => vec![Single],
793789
Def::Variant(_, id) => vec![Variant(id)],
794-
def => span_bug!(pat.span, "pat_constructors: unexpected \
795-
definition {:?}", def),
790+
Def::Struct(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => vec![Single],
791+
Def::Const(..) | Def::AssociatedConst(..) =>
792+
span_bug!(pat.span, "const pattern should've been rewritten"),
793+
def => span_bug!(pat.span, "pat_constructors: unexpected definition {:?}", def),
796794
},
797-
PatKind::QPath(..) =>
798-
span_bug!(pat.span, "const pattern should've been rewritten"),
799795
PatKind::Lit(ref expr) =>
800796
vec![ConstantValue(eval_const_expr(cx.tcx, &expr))],
801797
PatKind::Range(ref lo, ref hi) =>
@@ -899,7 +895,7 @@ pub fn specialize<'a, 'b, 'tcx>(
899895
PatKind::Binding(..) | PatKind::Wild =>
900896
Some(vec![dummy_pat; arity]),
901897

902-
PatKind::Path(..) => {
898+
PatKind::Path(..) | PatKind::QPath(..) => {
903899
match cx.tcx.expect_def(pat_id) {
904900
Def::Const(..) | Def::AssociatedConst(..) =>
905901
span_bug!(pat_span, "const pattern should've \
@@ -934,10 +930,6 @@ pub fn specialize<'a, 'b, 'tcx>(
934930
}
935931
}
936932

937-
PatKind::QPath(_, _) => {
938-
span_bug!(pat_span, "const pattern should've been rewritten")
939-
}
940-
941933
PatKind::Struct(_, ref pattern_fields, _) => {
942934
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
943935
let variant = constructor.variant_for_adt(adt);

0 commit comments

Comments
 (0)