Skip to content

Commit eb99c73

Browse files
committed
Match constructor first in Constructor methods
This makes it easier to add new non-standard constructors, and this also ensures that we don't forget cases when adding a new constructor.
1 parent e3d9984 commit eb99c73

File tree

1 file changed

+105
-106
lines changed

1 file changed

+105
-106
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 105 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -781,65 +781,68 @@ impl<'tcx> Constructor<'tcx> {
781781
ty: Ty<'tcx>,
782782
) -> Vec<Pat<'tcx>> {
783783
debug!("wildcard_subpatterns({:#?}, {:?})", self, ty);
784-
match ty.kind {
785-
ty::Tuple(ref fs) => {
786-
fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect()
787-
}
788-
ty::Slice(ty) | ty::Array(ty, _) => match *self {
789-
FixedLenSlice(length) => (0..length).map(|_| Pat::wildcard_from_ty(ty)).collect(),
790-
VarLenSlice(prefix, suffix) => {
791-
(0..prefix + suffix).map(|_| Pat::wildcard_from_ty(ty)).collect()
784+
785+
match self {
786+
Single | Variant(_) => match ty.kind {
787+
ty::Tuple(ref fs) => {
788+
fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect()
792789
}
793-
ConstantValue(..) => vec![],
794-
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
795-
},
796-
ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)],
797-
ty::Adt(adt, substs) => {
798-
if adt.is_box() {
799-
// Use T as the sub pattern type of Box<T>.
800-
vec![Pat::wildcard_from_ty(substs.type_at(0))]
801-
} else {
802-
let variant = &adt.variants[self.variant_index_for_adt(cx, adt)];
803-
let is_non_exhaustive =
804-
variant.is_field_list_non_exhaustive() && !cx.is_local(ty);
805-
variant
806-
.fields
807-
.iter()
808-
.map(|field| {
809-
let is_visible =
810-
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
811-
let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs));
812-
match (is_visible, is_non_exhaustive, is_uninhabited) {
813-
// Treat all uninhabited types in non-exhaustive variants as
814-
// `TyErr`.
815-
(_, true, true) => cx.tcx.types.err,
816-
// Treat all non-visible fields as `TyErr`. They can't appear in
817-
// any other pattern from this match (because they are private), so
818-
// their type does not matter - but we don't want to know they are
819-
// uninhabited.
820-
(false, ..) => cx.tcx.types.err,
821-
(true, ..) => {
822-
let ty = field.ty(cx.tcx, substs);
823-
match ty.kind {
824-
// If the field type returned is an array of an unknown
825-
// size return an TyErr.
826-
ty::Array(_, len)
827-
if len
828-
.try_eval_usize(cx.tcx, cx.param_env)
829-
.is_none() =>
830-
{
831-
cx.tcx.types.err
790+
ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)],
791+
ty::Adt(adt, substs) => {
792+
if adt.is_box() {
793+
// Use T as the sub pattern type of Box<T>.
794+
vec![Pat::wildcard_from_ty(substs.type_at(0))]
795+
} else {
796+
let variant = &adt.variants[self.variant_index_for_adt(cx, adt)];
797+
let is_non_exhaustive =
798+
variant.is_field_list_non_exhaustive() && !cx.is_local(ty);
799+
variant
800+
.fields
801+
.iter()
802+
.map(|field| {
803+
let is_visible = adt.is_enum()
804+
|| field.vis.is_accessible_from(cx.module, cx.tcx);
805+
let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs));
806+
match (is_visible, is_non_exhaustive, is_uninhabited) {
807+
// Treat all uninhabited types in non-exhaustive variants as
808+
// `TyErr`.
809+
(_, true, true) => cx.tcx.types.err,
810+
// Treat all non-visible fields as `TyErr`. They can't appear
811+
// in any other pattern from this match (because they are
812+
// private), so their type does not matter - but we don't want
813+
// to know they are uninhabited.
814+
(false, ..) => cx.tcx.types.err,
815+
(true, ..) => {
816+
let ty = field.ty(cx.tcx, substs);
817+
match ty.kind {
818+
// If the field type returned is an array of an unknown
819+
// size return an TyErr.
820+
ty::Array(_, len)
821+
if len
822+
.try_eval_usize(cx.tcx, cx.param_env)
823+
.is_none() =>
824+
{
825+
cx.tcx.types.err
826+
}
827+
_ => ty,
832828
}
833-
_ => ty,
834829
}
835830
}
836-
}
837-
})
838-
.map(Pat::wildcard_from_ty)
839-
.collect()
831+
})
832+
.map(Pat::wildcard_from_ty)
833+
.collect()
834+
}
840835
}
841-
}
842-
_ => vec![],
836+
_ => vec![],
837+
},
838+
FixedLenSlice(_) | VarLenSlice(..) => match ty.kind {
839+
ty::Slice(ty) | ty::Array(ty, _) => {
840+
let arity = self.arity(cx, ty);
841+
(0..arity).map(|_| Pat::wildcard_from_ty(ty)).collect()
842+
}
843+
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
844+
},
845+
ConstantValue(..) | ConstantRange(..) => vec![],
843846
}
844847
}
845848

@@ -850,19 +853,19 @@ impl<'tcx> Constructor<'tcx> {
850853
/// A struct pattern's arity is the number of fields it contains, etc.
851854
fn arity<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> u64 {
852855
debug!("Constructor::arity({:#?}, {:?})", self, ty);
853-
match ty.kind {
854-
ty::Tuple(ref fs) => fs.len() as u64,
855-
ty::Slice(..) | ty::Array(..) => match *self {
856-
FixedLenSlice(length) => length,
857-
VarLenSlice(prefix, suffix) => prefix + suffix,
858-
ConstantValue(..) => 0,
859-
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
856+
match self {
857+
Single | Variant(_) => match ty.kind {
858+
ty::Tuple(ref fs) => fs.len() as u64,
859+
ty::Slice(..) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
860+
ty::Ref(..) => 1,
861+
ty::Adt(adt, _) => {
862+
adt.variants[self.variant_index_for_adt(cx, adt)].fields.len() as u64
863+
}
864+
_ => 0,
860865
},
861-
ty::Ref(..) => 1,
862-
ty::Adt(adt, _) => {
863-
adt.variants[self.variant_index_for_adt(cx, adt)].fields.len() as u64
864-
}
865-
_ => 0,
866+
FixedLenSlice(length) => *length,
867+
VarLenSlice(prefix, suffix) => prefix + suffix,
868+
ConstantValue(..) | ConstantRange(..) => 0,
866869
}
867870
}
868871

@@ -886,53 +889,49 @@ impl<'tcx> Constructor<'tcx> {
886889
pats: impl IntoIterator<Item = Pat<'tcx>>,
887890
) -> Pat<'tcx> {
888891
let mut subpatterns = pats.into_iter();
889-
let pat = match ty.kind {
890-
ty::Adt(..) | ty::Tuple(..) => {
891-
let subpatterns = subpatterns
892-
.enumerate()
893-
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
894-
.collect();
895-
896-
if let ty::Adt(adt, substs) = ty.kind {
897-
if adt.is_enum() {
898-
PatKind::Variant {
899-
adt_def: adt,
900-
substs,
901-
variant_index: self.variant_index_for_adt(cx, adt),
902-
subpatterns,
892+
893+
let pat = match self {
894+
Single | Variant(_) => match ty.kind {
895+
ty::Adt(..) | ty::Tuple(..) => {
896+
let subpatterns = subpatterns
897+
.enumerate()
898+
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
899+
.collect();
900+
901+
if let ty::Adt(adt, substs) = ty.kind {
902+
if adt.is_enum() {
903+
PatKind::Variant {
904+
adt_def: adt,
905+
substs,
906+
variant_index: self.variant_index_for_adt(cx, adt),
907+
subpatterns,
908+
}
909+
} else {
910+
PatKind::Leaf { subpatterns }
903911
}
904912
} else {
905913
PatKind::Leaf { subpatterns }
906914
}
907-
} else {
908-
PatKind::Leaf { subpatterns }
909915
}
910-
}
911-
912-
ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() },
913-
914-
ty::Slice(_) | ty::Array(..) => match self {
915-
FixedLenSlice(_) => {
916-
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
917-
}
918-
VarLenSlice(prefix_len, _suffix_len) => {
919-
let prefix = subpatterns.by_ref().take(*prefix_len as usize).collect();
920-
let suffix = subpatterns.collect();
921-
let wild = Pat::wildcard_from_ty(ty);
922-
PatKind::Slice { prefix, slice: Some(wild), suffix }
923-
}
924-
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
925-
},
926-
927-
_ => match *self {
928-
ConstantValue(value, _) => PatKind::Constant { value },
929-
ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange {
930-
lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
931-
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
932-
end,
933-
}),
916+
ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() },
917+
ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
934918
_ => PatKind::Wild,
935919
},
920+
FixedLenSlice(_) => {
921+
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
922+
}
923+
&VarLenSlice(prefix_len, _) => {
924+
let prefix = subpatterns.by_ref().take(prefix_len as usize).collect();
925+
let suffix = subpatterns.collect();
926+
let wild = Pat::wildcard_from_ty(ty);
927+
PatKind::Slice { prefix, slice: Some(wild), suffix }
928+
}
929+
&ConstantValue(value, _) => PatKind::Constant { value },
930+
&ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange {
931+
lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
932+
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
933+
end,
934+
}),
936935
};
937936

938937
Pat { ty, span: DUMMY_SP, kind: Box::new(pat) }

0 commit comments

Comments
 (0)