Skip to content

Commit b454581

Browse files
committed
Extract constructor application as a Constructor method
1 parent 0c02c19 commit b454581

File tree

1 file changed

+64
-42
lines changed

1 file changed

+64
-42
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,67 @@ impl<'tcx> Constructor<'tcx> {
674674
_ => 0,
675675
}
676676
}
677+
678+
/// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
679+
/// must have as many elements as this constructor's arity.
680+
///
681+
/// Examples:
682+
/// self: Single
683+
/// ty: tuple of 3 elements
684+
/// pats: [10, 20, _] => (10, 20, _)
685+
///
686+
/// self: Option::Some
687+
/// ty: Option<bool>
688+
/// pats: [false] => Some(false)
689+
fn apply<'a>(
690+
&self,
691+
cx: &MatchCheckCtxt<'a, 'tcx>,
692+
ty: Ty<'tcx>,
693+
pats: impl IntoIterator<Item = Pat<'tcx>>,
694+
) -> Pat<'tcx> {
695+
let mut pats = pats.into_iter();
696+
let pat = match ty.kind {
697+
ty::Adt(..) | ty::Tuple(..) => {
698+
let pats = pats
699+
.enumerate()
700+
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
701+
.collect();
702+
703+
if let ty::Adt(adt, substs) = ty.kind {
704+
if adt.is_enum() {
705+
PatKind::Variant {
706+
adt_def: adt,
707+
substs,
708+
variant_index: self.variant_index_for_adt(cx, adt),
709+
subpatterns: pats,
710+
}
711+
} else {
712+
PatKind::Leaf { subpatterns: pats }
713+
}
714+
} else {
715+
PatKind::Leaf { subpatterns: pats }
716+
}
717+
}
718+
719+
ty::Ref(..) => PatKind::Deref { subpattern: pats.nth(0).unwrap() },
720+
721+
ty::Slice(_) | ty::Array(..) => {
722+
PatKind::Slice { prefix: pats.collect(), slice: None, suffix: vec![] }
723+
}
724+
725+
_ => match *self {
726+
ConstantValue(value, _) => PatKind::Constant { value },
727+
ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange {
728+
lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
729+
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
730+
end,
731+
}),
732+
_ => PatKind::Wild,
733+
},
734+
};
735+
736+
Pat { ty, span: DUMMY_SP, kind: Box::new(pat) }
737+
}
677738
}
678739

679740
#[derive(Clone, Debug)]
@@ -778,50 +839,11 @@ impl<'tcx> Witness<'tcx> {
778839
let arity = ctor.arity(cx, ty);
779840
let pat = {
780841
let len = self.0.len() as u64;
781-
let mut pats = self.0.drain((len - arity) as usize..).rev();
782-
783-
match ty.kind {
784-
ty::Adt(..) | ty::Tuple(..) => {
785-
let pats = pats
786-
.enumerate()
787-
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
788-
.collect();
789-
790-
if let ty::Adt(adt, substs) = ty.kind {
791-
if adt.is_enum() {
792-
PatKind::Variant {
793-
adt_def: adt,
794-
substs,
795-
variant_index: ctor.variant_index_for_adt(cx, adt),
796-
subpatterns: pats,
797-
}
798-
} else {
799-
PatKind::Leaf { subpatterns: pats }
800-
}
801-
} else {
802-
PatKind::Leaf { subpatterns: pats }
803-
}
804-
}
805-
806-
ty::Ref(..) => PatKind::Deref { subpattern: pats.nth(0).unwrap() },
807-
808-
ty::Slice(_) | ty::Array(..) => {
809-
PatKind::Slice { prefix: pats.collect(), slice: None, suffix: vec![] }
810-
}
811-
812-
_ => match *ctor {
813-
ConstantValue(value, _) => PatKind::Constant { value },
814-
ConstantRange(lo, hi, ty, end, _) => PatKind::Range(PatRange {
815-
lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
816-
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
817-
end,
818-
}),
819-
_ => PatKind::Wild,
820-
},
821-
}
842+
let pats = self.0.drain((len - arity) as usize..).rev();
843+
ctor.apply(cx, ty, pats)
822844
};
823845

824-
self.0.push(Pat { ty, span: DUMMY_SP, kind: Box::new(pat) });
846+
self.0.push(pat);
825847

826848
self
827849
}

0 commit comments

Comments
 (0)