Skip to content

Commit 798b9ff

Browse files
committed
Tweak comments
1 parent 0383539 commit 798b9ff

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
/// The specialisation of a row vector is computed by `specialize`.
6363
///
6464
/// It is computed as follows. For each row `p_i` of P, we have four cases:
65-
/// 1.1. `p_(i,1)= c(r_1, .., r_a)`. Then `S(c, P)` has a corresponding row:
65+
/// 1.1. `p_(i,1) = c(r_1, .., r_a)`. Then `S(c, P)` has a corresponding row:
6666
/// r_1, .., r_a, p_(i,2), .., p_(i,n)
6767
/// 1.2. `p_(i,1) = c'(r_1, .., r_a')` where `c ≠ c'`. Then `S(c, P)` has no
6868
/// corresponding row.
@@ -85,6 +85,9 @@
8585
/// D((r_1, p_(i,2), .., p_(i,n)))
8686
/// D((r_2, p_(i,2), .., p_(i,n)))
8787
///
88+
/// Note that the OR-patterns are not always used directly in Rust, but are used to derive
89+
/// the exhaustive integer matching rules, so they're written here for posterity.
90+
///
8891
/// The algorithm for computing `U`
8992
/// -------------------------------
9093
/// The algorithm is inductive (on the number of columns: i.e. components of tuple patterns).
@@ -97,7 +100,8 @@
97100
/// then `U(P, p_{m + 1})` is false.
98101
/// - Otherwise, `P` must be empty, so `U(P, p_{m + 1})` is true.
99102
///
100-
/// Inductive step. (`n > 0`, i.e. 1 or more tuple pattern components)
103+
/// Inductive step. (`n > 0`, i.e. whether there's at least one column
104+
/// [which may then be expanded into further columns later])
101105
/// We're going to match on the new pattern, `p_{m + 1}`.
102106
/// - If `p_{m + 1} == c(r_1, .., r_a)`, then we have a constructor pattern.
103107
/// Thus, the usefulness of `p_{m + 1}` can be reduced to whether it is useful when
@@ -926,6 +930,46 @@ impl<'tcx> IntRange<'tcx> {
926930
}
927931
}
928932

933+
// Find those constructors that are not matched by any non-wildcard patterns in the current column.
934+
fn compute_missing_ctors<'a, 'tcx: 'a>(
935+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
936+
all_ctors: &Vec<Constructor<'tcx>>,
937+
used_ctors: &Vec<Constructor<'tcx>>,
938+
) -> Vec<Constructor<'tcx>> {
939+
let mut missing_ctors = vec![];
940+
941+
for req_ctor in all_ctors {
942+
let mut refined_ctors = vec![req_ctor.clone()];
943+
for used_ctor in used_ctors {
944+
if used_ctor == req_ctor {
945+
// If a constructor appears in a `match` arm, we can
946+
// eliminate it straight away.
947+
refined_ctors = vec![]
948+
} else if tcx.features().exhaustive_integer_patterns {
949+
if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
950+
// Refine the required constructors for the type by subtracting
951+
// the range defined by the current constructor pattern.
952+
refined_ctors = interval.subtract_from(tcx, refined_ctors);
953+
}
954+
}
955+
956+
// If the constructor patterns that have been considered so far
957+
// already cover the entire range of values, then we the
958+
// constructor is not missing, and we can move on to the next one.
959+
if refined_ctors.is_empty() {
960+
break;
961+
}
962+
}
963+
// If a constructor has not been matched, then it is missing.
964+
// We add `refined_ctors` instead of `req_ctor`, because then we can
965+
// provide more detailed error information about precisely which
966+
// ranges have been omitted.
967+
missing_ctors.extend(refined_ctors);
968+
}
969+
970+
missing_ctors
971+
}
972+
929973
/// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html
930974
/// The algorithm from the paper has been modified to correctly handle empty
931975
/// types. The changes are:
@@ -1017,38 +1061,6 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
10171061
let all_ctors = all_constructors(cx, pcx);
10181062
debug!("all_ctors = {:#?}", all_ctors);
10191063

1020-
// `missing_ctors` are those that should have appeared
1021-
// as patterns in the `match` expression, but did not.
1022-
let mut missing_ctors = vec![];
1023-
for req_ctor in &all_ctors {
1024-
let mut refined_ctors = vec![req_ctor.clone()];
1025-
for used_ctor in &used_ctors {
1026-
if used_ctor == req_ctor {
1027-
// If a constructor appears in a `match` arm, we can
1028-
// eliminate it straight away.
1029-
refined_ctors = vec![]
1030-
} else if cx.tcx.features().exhaustive_integer_patterns {
1031-
if let Some(interval) = IntRange::from_ctor(cx.tcx, used_ctor) {
1032-
// Refine the required constructors for the type by subtracting
1033-
// the range defined by the current constructor pattern.
1034-
refined_ctors = interval.subtract_from(cx.tcx, refined_ctors);
1035-
}
1036-
}
1037-
1038-
// If the constructor patterns that have been considered so far
1039-
// already cover the entire range of values, then we the
1040-
// constructor is not missing, and we can move on to the next one.
1041-
if refined_ctors.is_empty() {
1042-
break;
1043-
}
1044-
}
1045-
// If a constructor has not been matched, then it is missing.
1046-
// We add `refined_ctors` instead of `req_ctor`, because then we can
1047-
// provide more detailed error information about precisely which
1048-
// ranges have been omitted.
1049-
missing_ctors.extend(refined_ctors);
1050-
}
1051-
10521064
// `missing_ctors` is the set of constructors from the same type as the
10531065
// first column of `matrix` that are matched only by wildcard patterns
10541066
// from the first column.
@@ -1067,11 +1079,10 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
10671079
// be a privately-empty enum is when the exhaustive_patterns
10681080
// feature flag is not present, so this is only
10691081
// needed for that case.
1082+
let missing_ctors = compute_missing_ctors(cx.tcx, &all_ctors, &used_ctors);
10701083

1071-
let is_privately_empty =
1072-
all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty);
1073-
let is_declared_nonexhaustive =
1074-
cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty);
1084+
let is_privately_empty = all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty);
1085+
let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty);
10751086
debug!("missing_ctors={:#?} is_privately_empty={:#?} is_declared_nonexhaustive={:#?}",
10761087
missing_ctors, is_privately_empty, is_declared_nonexhaustive);
10771088

0 commit comments

Comments
 (0)