Skip to content

Commit 149792b

Browse files
committed
pat_constructors returns at most one constructor
I tracked the origins of `pat_constructors` returning a `Vec` to commit 9b3f9d9. It was indeed specifically for variable-length slice patterns.
1 parent d7044f2 commit 149792b

File tree

1 file changed

+16
-24
lines changed

1 file changed

+16
-24
lines changed

src/librustc_mir/hair/pattern/_match.rs

+16-24
Original file line numberDiff line numberDiff line change
@@ -1615,13 +1615,13 @@ pub fn is_useful<'p, 'a, 'tcx>(
16151615

16161616
debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v.head());
16171617

1618-
if let Some(constructors) = pat_constructors(cx, v.head(), pcx) {
1619-
debug!("is_useful - expanding constructors: {:#?}", constructors);
1618+
if let Some(constructor) = pat_constructor(cx, v.head(), pcx) {
1619+
debug!("is_useful - expanding constructor: {:#?}", constructor);
16201620
split_grouped_constructors(
16211621
cx.tcx,
16221622
cx.param_env,
16231623
pcx,
1624-
constructors,
1624+
vec![constructor],
16251625
matrix,
16261626
pcx.span,
16271627
Some(hir_id),
@@ -1634,7 +1634,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
16341634
debug!("is_useful - expanding wildcard");
16351635

16361636
let used_ctors: Vec<Constructor<'_>> =
1637-
matrix.heads().flat_map(|p| pat_constructors(cx, p, pcx).unwrap_or(vec![])).collect();
1637+
matrix.heads().filter_map(|p| pat_constructor(cx, p, pcx)).collect();
16381638
debug!("used_ctors = {:#?}", used_ctors);
16391639
// `all_ctors` are all the constructors for the given type, which
16401640
// should all be represented (or caught with the wild pattern `_`).
@@ -1777,47 +1777,39 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
17771777
.unwrap_or(NotUseful)
17781778
}
17791779

1780-
/// Determines the constructors that the given pattern can be specialized to.
1781-
///
1782-
/// In most cases, there's only one constructor that a specific pattern
1783-
/// represents, such as a specific enum variant or a specific literal value.
1784-
/// Slice patterns, however, can match slices of different lengths. For instance,
1785-
/// `[a, b, tail @ ..]` can match a slice of length 2, 3, 4 and so on.
1786-
///
1780+
/// Determines the constructor that the given pattern can be specialized to.
17871781
/// Returns `None` in case of a catch-all, which can't be specialized.
1788-
fn pat_constructors<'tcx>(
1782+
fn pat_constructor<'tcx>(
17891783
cx: &mut MatchCheckCtxt<'_, 'tcx>,
17901784
pat: &Pat<'tcx>,
17911785
pcx: PatCtxt<'tcx>,
1792-
) -> Option<Vec<Constructor<'tcx>>> {
1786+
) -> Option<Constructor<'tcx>> {
17931787
match *pat.kind {
1794-
PatKind::AscribeUserType { ref subpattern, .. } => pat_constructors(cx, subpattern, pcx),
1788+
PatKind::AscribeUserType { ref subpattern, .. } => pat_constructor(cx, subpattern, pcx),
17951789
PatKind::Binding { .. } | PatKind::Wild => None,
1796-
PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(vec![Single]),
1790+
PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(Single),
17971791
PatKind::Variant { adt_def, variant_index, .. } => {
1798-
Some(vec![Variant(adt_def.variants[variant_index].def_id)])
1792+
Some(Variant(adt_def.variants[variant_index].def_id))
17991793
}
1800-
PatKind::Constant { value } => Some(vec![ConstantValue(value, pat.span)]),
1801-
PatKind::Range(PatRange { lo, hi, end }) => Some(vec![ConstantRange(
1794+
PatKind::Constant { value } => Some(ConstantValue(value, pat.span)),
1795+
PatKind::Range(PatRange { lo, hi, end }) => Some(ConstantRange(
18021796
lo.eval_bits(cx.tcx, cx.param_env, lo.ty),
18031797
hi.eval_bits(cx.tcx, cx.param_env, hi.ty),
18041798
lo.ty,
18051799
end,
18061800
pat.span,
1807-
)]),
1801+
)),
18081802
PatKind::Array { .. } => match pcx.ty.kind {
1809-
ty::Array(_, length) => {
1810-
Some(vec![FixedLenSlice(length.eval_usize(cx.tcx, cx.param_env))])
1811-
}
1803+
ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(cx.tcx, cx.param_env))),
18121804
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty),
18131805
},
18141806
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
18151807
let prefix = prefix.len() as u64;
18161808
let suffix = suffix.len() as u64;
18171809
if slice.is_some() {
1818-
Some(vec![VarLenSlice(prefix, suffix)])
1810+
Some(VarLenSlice(prefix, suffix))
18191811
} else {
1820-
Some(vec![FixedLenSlice(prefix + suffix)])
1812+
Some(FixedLenSlice(prefix + suffix))
18211813
}
18221814
}
18231815
PatKind::Or { .. } => {

0 commit comments

Comments
 (0)