Skip to content

Commit 61b6363

Browse files
committed
Add more detail to the split_grouped_constructors comment
1 parent c421af9 commit 61b6363

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/librustc_mir/hair/pattern/_match.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -1396,9 +1396,9 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Construct
13961396
/// impractical. However, observe that for some ranges of integers, the specialisation will be
13971397
/// identical across all values in that range (i.e. there are equivalence classes of ranges of
13981398
/// constructors based on their `is_useful_specialised` outcome). These classes are grouped by
1399-
/// the patterns that apply to them (both in the matrix `P` and in the new row `p_{m + 1}`). We
1400-
/// can split the range whenever the patterns that apply to that range (specifically: the patterns
1401-
/// that *intersect* with that range) change.
1399+
/// the patterns that apply to them (in the matrix `P`). We can split the range whenever the
1400+
/// patterns that apply to that range (specifically: the patterns that *intersect* with that range)
1401+
/// change.
14021402
/// Our solution, therefore, is to split the range constructor into subranges at every single point
14031403
/// the group of intersecting patterns changes, which we can compute by converting each pattern to
14041404
/// a range and recording its endpoints, then creating subranges between each consecutive pair of
@@ -1407,6 +1407,21 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Construct
14071407
/// on actual integers. The nice thing about this is that the number of subranges is linear in the
14081408
/// number of rows in the matrix (i.e. the number of cases in the `match` statement), so we don't
14091409
/// need to be worried about matching over gargantuan ranges.
1410+
///
1411+
/// Essentially, given the first column of a matrix representing ranges, looking like the following:
1412+
///
1413+
/// |------| |----------| |-------| ||
1414+
/// |-------| |-------| |----| ||
1415+
/// |---------|
1416+
///
1417+
/// We truncate the ranges so that they lie inside each range constructor and then split them
1418+
/// up into equivalence classes so the ranges are no longer overlapping:
1419+
///
1420+
/// |--|--|||-||||--||---|||-------| |-|||| ||
1421+
///
1422+
/// The logic for determining how to split the ranges is a little involved: we need to make sure
1423+
/// that we have a new range for each subrange for which a different set of rows coïncides, but
1424+
/// essentially reduces to case analysis on the endpoints of the ranges.
14101425
fn split_grouped_constructors<'p, 'a: 'p, 'tcx: 'a>(
14111426
tcx: TyCtxt<'a, 'tcx, 'tcx>,
14121427
ctors: Vec<Constructor<'tcx>>,
@@ -1420,10 +1435,9 @@ fn split_grouped_constructors<'p, 'a: 'p, 'tcx: 'a>(
14201435
// For now, only ranges may denote groups of "subconstructors", so we only need to
14211436
// special-case constant ranges.
14221437
ConstantRange(..) if should_treat_range_exhaustively(tcx, &ctor) => {
1423-
// We only care about finding all the subranges within the range of the intersection
1424-
// of the new pattern `p_({m + 1},1)` (here `pat`) and the constructor range.
1425-
// Anything else is irrelevant, because it is guaranteed to result in `NotUseful`,
1426-
// which is the default case anyway, and can be ignored.
1438+
// We only care about finding all the subranges within the range of the constructor
1439+
// range. Anything else is irrelevant, because it is guaranteed to result in
1440+
// `NotUseful`, which is the default case anyway, and can be ignored.
14271441
let ctor_range = IntRange::from_ctor(tcx, &ctor).unwrap();
14281442

14291443
// We're going to collect all the endpoints in the new pattern so we can create
@@ -1479,6 +1493,9 @@ fn split_grouped_constructors<'p, 'a: 'p, 'tcx: 'a>(
14791493
// sure we're enumerating precisely the correct ranges. Too few and the matching is
14801494
// actually incorrect. Too many and our diagnostics are poorer. This involves some
14811495
// case analysis.
1496+
// In essence, we need to ensure that every time the set of row-ranges that are
1497+
// overlapping changes (as we go through the values covered by the ranges), we split
1498+
// into a new subrange.
14821499
while let Some(b) = points.next() {
14831500
// a < b (strictly)
14841501
if let Endpoint::Both = a.1 {
@@ -1522,7 +1539,7 @@ fn constructor_intersects_pattern<'p, 'a: 'p, 'tcx: 'a>(
15221539
let (pat_lo, pat_hi) = pat.range.into_inner();
15231540
let (ctor_lo, ctor_hi) = ctor.range.into_inner();
15241541
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
1525-
Some(vec![])
1542+
vec![]
15261543
})
15271544
}
15281545
_ => None,

0 commit comments

Comments
 (0)