Skip to content

Commit a2624f2

Browse files
committed
Rewrite constructor_intersects_pattern as a match
1 parent a66dcd5 commit a2624f2

File tree

1 file changed

+49
-44
lines changed

1 file changed

+49
-44
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,52 +1940,55 @@ fn slice_pat_covered_by_const<'tcx>(
19401940
// This has a single call site that can be hot
19411941
#[inline(always)]
19421942
fn constructor_intersects_pattern<'p, 'tcx>(
1943-
tcx: TyCtxt<'tcx>,
1944-
param_env: ty::ParamEnv<'tcx>,
1943+
cx: &MatchCheckCtxt<'_, 'tcx>,
19451944
ctor: &Constructor<'tcx>,
19461945
pat: &'p Pat<'tcx>,
19471946
) -> Option<PatStack<'p, 'tcx>> {
19481947
trace!("constructor_intersects_pattern {:#?}, {:#?}", ctor, pat);
1949-
if let Single = ctor {
1950-
Some(PatStack::default())
1951-
} else if let IntRange(ctor) = ctor {
1952-
let pat = match *pat.kind {
1953-
PatKind::Constant { value } => IntRange::from_const(tcx, param_env, value)?,
1954-
PatKind::Range(PatRange { lo, hi, end }) => {
1955-
IntRange::from_range(tcx, param_env, lo, hi, &end)?
1956-
}
1957-
_ => bug!("`constructor_intersects_pattern` called with {:?}", pat),
1958-
};
1948+
match ctor {
1949+
Single => Some(PatStack::default()),
1950+
IntRange(ctor) => {
1951+
let pat = match *pat.kind {
1952+
PatKind::Constant { value } => IntRange::from_const(cx.tcx, cx.param_env, value)?,
1953+
PatKind::Range(PatRange { lo, hi, end }) => {
1954+
IntRange::from_range(cx.tcx, cx.param_env, lo, hi, &end)?
1955+
}
1956+
_ => bug!("`constructor_intersects_pattern` called with {:?}", pat),
1957+
};
19591958

1960-
ctor.intersection(tcx, &pat)?;
1961-
1962-
// Constructor splitting should ensure that all intersections we encounter are actually
1963-
// inclusions.
1964-
let (pat_lo, pat_hi) = pat.range.into_inner();
1965-
let (ctor_lo, ctor_hi) = ctor.range.clone().into_inner();
1966-
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
1967-
1968-
Some(PatStack::default())
1969-
} else {
1970-
// Fallback for non-ranges and ranges that involve floating-point numbers, which are not
1971-
// conveniently handled by `IntRange`. For these cases, the constructor may not be a range
1972-
// so intersection actually devolves into being covered by the pattern.
1973-
let (pat_from, pat_to, pat_end) = match *pat.kind {
1974-
PatKind::Constant { value } => (value, value, RangeEnd::Included),
1975-
PatKind::Range(PatRange { lo, hi, end }) => (lo, hi, end),
1976-
_ => bug!("`constructor_intersects_pattern` called with {:?}", pat),
1977-
};
1978-
let (ctor_from, ctor_to, ctor_end) = match *ctor {
1979-
ConstantValue(value) => (value, value, RangeEnd::Included),
1980-
ConstantRange(from, to, range_end) => (from, to, range_end),
1981-
_ => bug!("`constructor_intersects_pattern` called with {:?}", ctor),
1982-
};
1983-
let order_to = compare_const_vals(tcx, ctor_to, pat_to, param_env, pat_from.ty)?;
1984-
let order_from = compare_const_vals(tcx, ctor_from, pat_from, param_env, pat_from.ty)?;
1985-
let included = (order_from != Ordering::Less)
1986-
&& ((order_to == Ordering::Less)
1987-
|| (pat_end == ctor_end && order_to == Ordering::Equal));
1988-
if included { Some(PatStack::default()) } else { None }
1959+
ctor.intersection(cx.tcx, &pat)?;
1960+
1961+
// Constructor splitting should ensure that all intersections we encounter are actually
1962+
// inclusions.
1963+
let (pat_lo, pat_hi) = pat.range.into_inner();
1964+
let (ctor_lo, ctor_hi) = ctor.range.clone().into_inner();
1965+
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
1966+
1967+
Some(PatStack::default())
1968+
}
1969+
ConstantValue(..) | ConstantRange(..) => {
1970+
// Fallback for non-ranges and ranges that involve floating-point numbers, which are
1971+
// not conveniently handled by `IntRange`. For these cases, the constructor may not be
1972+
// a range so intersection actually devolves into being covered by the pattern.
1973+
let (pat_from, pat_to, pat_end) = match *pat.kind {
1974+
PatKind::Constant { value } => (value, value, RangeEnd::Included),
1975+
PatKind::Range(PatRange { lo, hi, end }) => (lo, hi, end),
1976+
_ => bug!("`constructor_intersects_pattern` called with {:?}", pat),
1977+
};
1978+
let (ctor_from, ctor_to, ctor_end) = match *ctor {
1979+
ConstantValue(value) => (value, value, RangeEnd::Included),
1980+
ConstantRange(from, to, range_end) => (from, to, range_end),
1981+
_ => bug!(),
1982+
};
1983+
let order_to = compare_const_vals(cx.tcx, ctor_to, pat_to, cx.param_env, pat_from.ty)?;
1984+
let order_from =
1985+
compare_const_vals(cx.tcx, ctor_from, pat_from, cx.param_env, pat_from.ty)?;
1986+
let included = (order_from != Ordering::Less)
1987+
&& ((order_to == Ordering::Less)
1988+
|| (pat_end == ctor_end && order_to == Ordering::Equal));
1989+
if included { Some(PatStack::default()) } else { None }
1990+
}
1991+
_ => bug!("`constructor_intersects_pattern` called with {:?}", ctor),
19891992
}
19901993
}
19911994

@@ -2122,9 +2125,11 @@ fn specialize_one_pattern<'p, 'a: 'p, 'p2: 'p, 'tcx>(
21222125
// If the constructor is a:
21232126
// - Single value: add a row if the pattern contains the constructor.
21242127
// - Range: add a row if the constructor intersects the pattern.
2125-
constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat)
2126-
.into_iter()
2127-
.collect()
2128+
if let Some(ps) = constructor_intersects_pattern(cx, constructor, pat) {
2129+
smallvec![ps]
2130+
} else {
2131+
smallvec![]
2132+
}
21282133
}
21292134

21302135
PatKind::Array { ref prefix, ref slice, ref suffix }

0 commit comments

Comments
 (0)