Skip to content

Commit b597921

Browse files
committed
Move Constructor::apply to Fields
1 parent c922857 commit b597921

File tree

1 file changed

+89
-93
lines changed
  • compiler/rustc_mir_build/src/thir/pattern

1 file changed

+89
-93
lines changed

compiler/rustc_mir_build/src/thir/pattern/_match.rs

Lines changed: 89 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -993,93 +993,6 @@ impl<'tcx> Constructor<'tcx> {
993993
}
994994
}
995995
}
996-
997-
/// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
998-
/// must have as many elements as this constructor's arity.
999-
///
1000-
/// This is roughly the inverse of `specialize_constructor`.
1001-
///
1002-
/// Examples:
1003-
/// `self`: `Constructor::Single`
1004-
/// `ty`: `(u32, u32, u32)`
1005-
/// `pats`: `[10, 20, _]`
1006-
/// returns `(10, 20, _)`
1007-
///
1008-
/// `self`: `Constructor::Variant(Option::Some)`
1009-
/// `ty`: `Option<bool>`
1010-
/// `pats`: `[false]`
1011-
/// returns `Some(false)`
1012-
fn apply<'p>(&self, pcx: PatCtxt<'_, 'p, 'tcx>, fields: Fields<'p, 'tcx>) -> Pat<'tcx> {
1013-
let mut subpatterns = fields.all_patterns();
1014-
1015-
let pat = match self {
1016-
Single | Variant(_) => match pcx.ty.kind() {
1017-
ty::Adt(..) | ty::Tuple(..) => {
1018-
let subpatterns = subpatterns
1019-
.enumerate()
1020-
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
1021-
.collect();
1022-
1023-
if let ty::Adt(adt, substs) = pcx.ty.kind() {
1024-
if adt.is_enum() {
1025-
PatKind::Variant {
1026-
adt_def: adt,
1027-
substs,
1028-
variant_index: self.variant_index_for_adt(adt),
1029-
subpatterns,
1030-
}
1031-
} else {
1032-
PatKind::Leaf { subpatterns }
1033-
}
1034-
} else {
1035-
PatKind::Leaf { subpatterns }
1036-
}
1037-
}
1038-
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
1039-
// be careful to reconstruct the correct constant pattern here. However a string
1040-
// literal pattern will never be reported as a non-exhaustiveness witness, so we
1041-
// can ignore this issue.
1042-
ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
1043-
ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, pcx.ty),
1044-
_ => PatKind::Wild,
1045-
},
1046-
Slice(slice) => match slice.kind {
1047-
FixedLen(_) => {
1048-
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
1049-
}
1050-
VarLen(prefix, _) => {
1051-
let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
1052-
if slice.array_len.is_some() {
1053-
// Improves diagnostics a bit: if the type is a known-size array, instead
1054-
// of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
1055-
// This is incorrect if the size is not known, since `[_, ..]` captures
1056-
// arrays of lengths `>= 1` whereas `[..]` captures any length.
1057-
while !prefix.is_empty() && prefix.last().unwrap().is_wildcard() {
1058-
prefix.pop();
1059-
}
1060-
}
1061-
let suffix: Vec<_> = if slice.array_len.is_some() {
1062-
// Same as above.
1063-
subpatterns.skip_while(Pat::is_wildcard).collect()
1064-
} else {
1065-
subpatterns.collect()
1066-
};
1067-
let wild = Pat::wildcard_from_ty(pcx.ty);
1068-
PatKind::Slice { prefix, slice: Some(wild), suffix }
1069-
}
1070-
},
1071-
&Str(value) => PatKind::Constant { value },
1072-
&FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
1073-
IntRange(range) => return range.to_pat(pcx.cx.tcx),
1074-
NonExhaustive => PatKind::Wild,
1075-
Opaque => bug!("we should not try to apply an opaque constructor"),
1076-
Wildcard => bug!(
1077-
"trying to apply a wildcard constructor; this should have been done in `apply_constructors`"
1078-
),
1079-
};
1080-
1081-
Pat { ty: pcx.ty, span: DUMMY_SP, kind: Box::new(pat) }
1082-
}
1083996
}
1084997

1085998
/// Some fields need to be explicitly hidden away in certain cases; see the comment above the
@@ -1228,6 +1141,93 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12281141
ret
12291142
}
12301143

1144+
/// Apply a constructor to a list of patterns, yielding a new pattern. `self`
1145+
/// must have as many elements as this constructor's arity.
1146+
///
1147+
/// This is roughly the inverse of `specialize_constructor`.
1148+
///
1149+
/// Examples:
1150+
/// `ctor`: `Constructor::Single`
1151+
/// `ty`: `Foo(u32, u32, u32)`
1152+
/// `self`: `[10, 20, _]`
1153+
/// returns `Foo(10, 20, _)`
1154+
///
1155+
/// `ctor`: `Constructor::Variant(Option::Some)`
1156+
/// `ty`: `Option<bool>`
1157+
/// `self`: `[false]`
1158+
/// returns `Some(false)`
1159+
fn apply(self, pcx: PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'tcx>) -> Pat<'tcx> {
1160+
let mut subpatterns = self.all_patterns();
1161+
1162+
let pat = match ctor {
1163+
Single | Variant(_) => match pcx.ty.kind() {
1164+
ty::Adt(..) | ty::Tuple(..) => {
1165+
let subpatterns = subpatterns
1166+
.enumerate()
1167+
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
1168+
.collect();
1169+
1170+
if let ty::Adt(adt, substs) = pcx.ty.kind() {
1171+
if adt.is_enum() {
1172+
PatKind::Variant {
1173+
adt_def: adt,
1174+
substs,
1175+
variant_index: ctor.variant_index_for_adt(adt),
1176+
subpatterns,
1177+
}
1178+
} else {
1179+
PatKind::Leaf { subpatterns }
1180+
}
1181+
} else {
1182+
PatKind::Leaf { subpatterns }
1183+
}
1184+
}
1185+
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
1186+
// be careful to reconstruct the correct constant pattern here. However a string
1187+
// literal pattern will never be reported as a non-exhaustiveness witness, so we
1188+
// can ignore this issue.
1189+
ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
1190+
ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", ctor, pcx.ty),
1191+
_ => PatKind::Wild,
1192+
},
1193+
Slice(slice) => match slice.kind {
1194+
FixedLen(_) => {
1195+
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
1196+
}
1197+
VarLen(prefix, _) => {
1198+
let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
1199+
if slice.array_len.is_some() {
1200+
// Improves diagnostics a bit: if the type is a known-size array, instead
1201+
// of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
1202+
// This is incorrect if the size is not known, since `[_, ..]` captures
1203+
// arrays of lengths `>= 1` whereas `[..]` captures any length.
1204+
while !prefix.is_empty() && prefix.last().unwrap().is_wildcard() {
1205+
prefix.pop();
1206+
}
1207+
}
1208+
let suffix: Vec<_> = if slice.array_len.is_some() {
1209+
// Same as above.
1210+
subpatterns.skip_while(Pat::is_wildcard).collect()
1211+
} else {
1212+
subpatterns.collect()
1213+
};
1214+
let wild = Pat::wildcard_from_ty(pcx.ty);
1215+
PatKind::Slice { prefix, slice: Some(wild), suffix }
1216+
}
1217+
},
1218+
&Str(value) => PatKind::Constant { value },
1219+
&FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
1220+
IntRange(range) => return range.to_pat(pcx.cx.tcx),
1221+
NonExhaustive => PatKind::Wild,
1222+
Opaque => bug!("we should not try to apply an opaque constructor"),
1223+
Wildcard => bug!(
1224+
"trying to apply a wildcard constructor; this should have been done in `apply_constructors`"
1225+
),
1226+
};
1227+
1228+
Pat { ty: pcx.ty, span: DUMMY_SP, kind: Box::new(pat) }
1229+
}
1230+
12311231
/// Returns the number of patterns from the viewpoint of match-checking, i.e. excluding hidden
12321232
/// fields. This is what we want in most cases in this file, the only exception being
12331233
/// conversion to/from `Pat`.
@@ -1534,8 +1534,7 @@ impl<'tcx> Witness<'tcx> {
15341534
let len = self.0.len();
15351535
let arity = ctor_wild_subpatterns.len();
15361536
let pats = self.0.drain((len - arity)..).rev();
1537-
let fields = ctor_wild_subpatterns.replace_fields(pcx.cx, pats);
1538-
ctor.apply(pcx, fields)
1537+
ctor_wild_subpatterns.replace_fields(pcx.cx, pats).apply(pcx, ctor)
15391538
};
15401539

15411540
self.0.push(pat);
@@ -2072,10 +2071,7 @@ impl<'tcx> MissingConstructors<'tcx> {
20722071
// it. For example, if `ctor` is a `Constructor::Variant` for
20732072
// `Option::Some`, we get the pattern `Some(_)`.
20742073
self.iter(pcx)
2075-
.map(|missing_ctor| {
2076-
let fields = Fields::wildcards(pcx, &missing_ctor);
2077-
missing_ctor.apply(pcx, fields)
2078-
})
2074+
.map(|missing_ctor| Fields::wildcards(pcx, &missing_ctor).apply(pcx, missing_ctor))
20792075
.collect()
20802076
}
20812077
}

0 commit comments

Comments
 (0)