Skip to content

Commit 244ac8d

Browse files
committed
Tidy up
1 parent c8ac41e commit 244ac8d

File tree

1 file changed

+66
-55
lines changed

1 file changed

+66
-55
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@
5151
/// or `None`). This operation returns zero or more altered pattern-stacks, as follows.
5252
/// We look at the pattern `p_1` on top of the stack, and we have four cases:
5353
/// 1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We push
54-
/// onto the stack the arguments of this constructor, and return the result:
54+
/// onto the stack the arguments of this constructor, and return the result:
5555
/// r_1, .., r_a, p_2, .., p_n
56-
/// 2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and return nothing.
56+
/// 2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and return
57+
/// nothing.
5758
/// 3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c`
58-
/// has arguments (its arity), and return the resulting stack:
59+
/// has arguments (its arity), and return the resulting stack:
5960
/// _, .., _, p_2, .., p_n
6061
/// 4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting stack:
6162
/// S(c, (r_1, p_2, .., p_n))
@@ -84,15 +85,18 @@
8485
/// Inductive step. (`n > 0`)
8586
/// We look at `p_1`, the head of the pattern-stack `p`.
8687
///
87-
/// We first generate the list of constructors that are covered by a pattern `pat`. We name this operation
88-
/// `pat_constructors`.
89-
/// - If `pat == c(r_1, .., r_a)`, i.e. we have a constructor pattern. Then we just return `c`:
88+
/// We first generate the list of constructors that are covered by a pattern `pat`. We name
89+
/// this operation `pat_constructors`.
90+
/// - If `pat == c(r_1, .., r_a)`, i.e. we have a constructor pattern. Then we just
91+
/// return `c`:
9092
/// `pat_constructors(pat) = [c]`
9193
///
92-
/// - If `pat == _`, then we return the list of all possible constructors for the relevant type:
94+
/// - If `pat == _`, then we return the list of all possible constructors for the
95+
/// relevant type:
9396
/// `pat_constructors(pat) = all_constructors(pat.ty)`
9497
///
95-
/// - If `pat == r_1 | r_2`, then we return the constructors for either branch of the OR-pattern:
98+
/// - If `pat == r_1 | r_2`, then we return the constructors for either branch of the
99+
/// OR-pattern:
96100
/// `pat_constructors(pat) = pat_constructors(r_1) + pat_constructors(r_2)`
97101
///
98102
/// Then for each constructor `c` in `pat_constructors(p_1)`, we want to check whether a value
@@ -101,13 +105,13 @@
101105
/// For that, we only care about those rows of `M` whose first component covers the
102106
/// constructor `c`; and for those rows that do, we want to unpack the arguments to `c` to check
103107
/// further that `p` matches additional values.
104-
/// This is where specialization comes in: this check amounts to computing `U(S(c, M), S(c, p))`.
105-
/// More details can be found in the paper.
108+
/// This is where specialization comes in: this check amounts to computing `U(S(c, M), S(c,
109+
/// p))`. More details can be found in the paper.
106110
///
107111
/// Thus we get: `U(M, p) := ∃(c ϵ pat_constructors(p_1)) U(S(c, M), S(c, p))`
108112
///
109-
/// Note that for c ϵ pat_constructors(p_1), `S(c, P)` always returns exactly one element, so the
110-
/// formula above makes sense.
113+
/// Note that for c ϵ pat_constructors(p_1), `S(c, P)` always returns exactly one element, so
114+
/// the formula above makes sense.
111115
///
112116
/// This algorithm however has a lot of practical issues. Most importantly, it may not terminate
113117
/// in the presence of recursive types, since we always unpack all constructors as much
@@ -601,7 +605,7 @@ impl<'tcx> Constructor<'tcx> {
601605
match self {
602606
Wildcard => true,
603607
MissingConstructors(_) => bug!(
604-
"Not sure if MissingConstructors should count as a wildcard. Shouldn't happen anyways."
608+
"Not sure if MissingConstructors should be a wildcard. Shouldn't happen anyways."
605609
),
606610
_ => false,
607611
}
@@ -640,38 +644,44 @@ impl<'tcx> Constructor<'tcx> {
640644
// Any base constructor can be used unchanged.
641645
Single | Variant(_) | ConstantValue(_) | FixedLenSlice(_) => smallvec![self],
642646
ConstantRange(..) if should_treat_range_exhaustively(cx.tcx, &self) => {
643-
// For exhaustive integer matching, some constructors are grouped within other constructors
644-
// (namely integer typed values are grouped within ranges). However, when specialising these
645-
// constructors, we want to be specialising for the underlying constructors (the integers), not
646-
// the groups (the ranges). Thus we need to split the groups up. Splitting them up naïvely would
647-
// mean creating a separate constructor for every single value in the range, which is clearly
648-
// impractical. However, observe that for some ranges of integers, the specialisation will be
649-
// identical across all values in that range (i.e., there are equivalence classes of ranges of
650-
// constructors based on their `is_useful_specialized` outcome). These classes are grouped by
651-
// the patterns that apply to them (in the matrix `P`). We can split the range whenever the
652-
// patterns that apply to that range (specifically: the patterns that *intersect* with that range)
653-
// change.
654-
// Our solution, therefore, is to split the range constructor into subranges at every single point
655-
// the group of intersecting patterns changes (using the method described below).
656-
// And voilà! We're testing precisely those ranges that we need to, without any exhaustive matching
657-
// on actual integers. The nice thing about this is that the number of subranges is linear in the
658-
// number of rows in the matrix (i.e., the number of cases in the `match` statement), so we don't
659-
// need to be worried about matching over gargantuan ranges.
647+
// For exhaustive integer matching, some constructors are grouped within other
648+
// constructors (namely integer typed values are grouped within ranges). However,
649+
// when specialising these constructors, we want to be specialising for the
650+
// underlying constructors (the integers), not the groups (the ranges). Thus we
651+
// need to split the groups up. Splitting them up naïvely would mean creating a
652+
// separate constructor for every single value in the range, which is clearly
653+
// impractical. However, observe that for some ranges of integers, the
654+
// specialisation will be identical across all values in that range (i.e., there
655+
// are equivalence classes of ranges of constructors based on their
656+
// `is_useful_specialized` outcome). These classes are grouped by the patterns that
657+
// apply to them (in the matrix `P`). We can split the range whenever the patterns
658+
// that apply to that range (specifically: the patterns that *intersect* with that
659+
// range) change.
660+
// Our solution, therefore, is to split the range constructor into subranges at
661+
// every single point the group of intersecting patterns changes (using the method
662+
// described below). And voilà! We're testing precisely those ranges that we need
663+
// to, without any exhaustive matching on actual integers. The nice thing about
664+
// this is that the number of subranges is linear in the number of rows in the
665+
// matrix (i.e., the number of cases in the `match` statement), so we don't need to
666+
// be worried about matching over gargantuan ranges.
660667
//
661-
// Essentially, given the first column of a matrix representing ranges, looking like the following:
668+
// Essentially, given the first column of a matrix representing ranges, looking
669+
// like the following:
662670
//
663671
// |------| |----------| |-------| ||
664672
// |-------| |-------| |----| ||
665673
// |---------|
666674
//
667-
// We split the ranges up into equivalence classes so the ranges are no longer overlapping:
675+
// We split the ranges up into equivalence classes so the ranges are no longer
676+
// overlapping:
668677
//
669678
// |--|--|||-||||--||---|||-------| |-|||| ||
670679
//
671-
// The logic for determining how to split the ranges is fairly straightforward: we calculate
672-
// boundaries for each interval range, sort them, then create constructors for each new interval
673-
// between every pair of boundary points. (This essentially sums up to performing the intuitive
674-
// merging operation depicted above.)
680+
// The logic for determining how to split the ranges is fairly straightforward: we
681+
// calculate boundaries for each interval range, sort them, then create
682+
// constructors for each new interval between every pair of boundary points. (This
683+
// essentially sums up to performing the intuitive merging operation depicted
684+
// above.)
675685

676686
// We only care about finding all the subranges within the range of the constructor
677687
// range. Anything else is irrelevant, because it is guaranteed to result in
@@ -709,9 +719,9 @@ impl<'tcx> Constructor<'tcx> {
709719
let mut borders: Vec<_> = row_borders.chain(ctor_borders).collect();
710720
borders.sort_unstable();
711721

712-
// We're going to iterate through every adjacent pair of borders, making sure that each
713-
// represents an interval of nonnegative length, and convert each such interval
714-
// into a constructor.
722+
// We're going to iterate through every adjacent pair of borders, making sure that
723+
// each represents an interval of nonnegative length, and convert each such
724+
// interval into a constructor.
715725
borders
716726
.windows(2)
717727
.filter_map(|window| match (window[0], window[1]) {
@@ -785,8 +795,8 @@ impl<'tcx> Constructor<'tcx> {
785795
// to them and we can ignore the other ones. Otherwise, we have to try all
786796
// existing constructors one-by-one.
787797
if is_non_exhaustive {
788-
// We pretend the type has an additional `_` constructor, that counts as a missing
789-
// constructor. So we return that constructor.
798+
// We pretend the type has an additional `_` constructor, that counts as a
799+
// missing constructor. So we return that constructor.
790800
smallvec![Wildcard]
791801
} else if !missing_ctors.is_empty() {
792802
if head_ctors.is_empty() {
@@ -795,17 +805,17 @@ impl<'tcx> Constructor<'tcx> {
795805
smallvec![Wildcard]
796806
} else {
797807
// Otherwise, we have a set of missing constructors that is neither empty
798-
// not equal to all_constructors. Since all missing constructors will behave
799-
// the same (i.e. will be matched only by wildcards), we return a metaconstructor
800-
// that contains all of them at once.
808+
// not equal to all_constructors. Since all missing constructors will
809+
// behave the same (i.e. will be matched only by wildcards), we return a
810+
// metaconstructor that contains all of them at once.
801811
smallvec![MissingConstructors(missing_ctors)]
802812
}
803813
} else {
804-
// Here we know there are no missing constructors, so we have to try all existing
805-
// constructors one-by-one.
814+
// Here we know there are no missing constructors, so we have to try all
815+
// existing constructors one-by-one.
806816
let (all_ctors, _) = missing_ctors.into_inner();
807-
// Recursively split newly generated list of constructors. This list must not contain
808-
// any wildcards so we don't recurse infinitely.
817+
// Recursively split newly generated list of constructors. This list must not
818+
// contain any wildcards so we don't recurse infinitely.
809819
all_ctors
810820
.into_iter()
811821
.flat_map(|ctor| ctor.split_meta_constructor(cx, pcx, head_ctors))
@@ -816,8 +826,9 @@ impl<'tcx> Constructor<'tcx> {
816826
}
817827
}
818828

819-
/// Returns a collection of constructors that spans the constructors covered by `self`, subtracted
820-
/// by the constructors covered by `head_ctors`: i.e., `self \ head_ctors` (in set notation).
829+
/// Returns a collection of constructors that spans the constructors covered by `self`,
830+
/// subtracted by the constructors covered by `head_ctors`: i.e., `self \ head_ctors` (in set
831+
/// notation).
821832
fn subtract_meta_constructor(
822833
self,
823834
_pcx: PatCtxt<'tcx>,
@@ -1091,11 +1102,11 @@ impl<'tcx> Constructor<'tcx> {
10911102
let wild = Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) };
10921103
PatKind::Slice { prefix, slice: Some(wild), suffix: vec![] }
10931104
} else {
1094-
// We don't want to output a variable-length slice pattern if the slice_patterns
1095-
// feature is not enabled.
1096-
// The constructor covers infinitely many slice lengths, but for diagnostic purposes
1097-
// it is correct to return only some examples of non-covered patterns. So we just
1098-
// return the smallest length pattern here.
1105+
// We don't want to output a variable-length slice pattern if the
1106+
// slice_patterns feature is not enabled.
1107+
// The constructor covers infinitely many slice lengths, but for diagnostic
1108+
// purposes it is correct to return only some examples of non-covered
1109+
// patterns. So we just return the smallest length pattern here.
10991110
PatKind::Slice { prefix, slice: None, suffix: vec![] }
11001111
}
11011112
}

0 commit comments

Comments
 (0)