Skip to content

Commit c6c8625

Browse files
committed
Special-case subtracting from a range if that range is not an IntRange
1 parent 6de7afd commit c6c8625

File tree

1 file changed

+36
-21
lines changed

1 file changed

+36
-21
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -763,31 +763,46 @@ impl<'tcx> Constructor<'tcx> {
763763
remaining_ctors
764764
}
765765
ConstantRange(..) | ConstantValue(..) => {
766-
let mut remaining_ctors = vec![self.clone()];
767-
for other_ctor in other_ctors {
768-
if other_ctor == self {
769-
// If a constructor appears in a `match` arm, we can
770-
// eliminate it straight away.
771-
remaining_ctors = vec![]
772-
} else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
773-
// Refine the required constructors for the type by subtracting
774-
// the range defined by the current constructor pattern.
775-
remaining_ctors = interval.subtract_from(tcx, param_env, remaining_ctors);
766+
if let Some(_self_range) = IntRange::from_ctor(tcx, param_env, self) {
767+
let mut remaining_ctors = vec![self.clone()];
768+
for other_ctor in other_ctors {
769+
if other_ctor == self {
770+
// If a constructor appears in a `match` arm, we can
771+
// eliminate it straight away.
772+
remaining_ctors = vec![]
773+
} else if let Some(interval) =
774+
IntRange::from_ctor(tcx, param_env, other_ctor)
775+
{
776+
// Refine the required constructors for the type by subtracting
777+
// the range defined by the current constructor pattern.
778+
remaining_ctors =
779+
interval.subtract_from(tcx, param_env, remaining_ctors);
780+
}
781+
782+
// If the constructor patterns that have been considered so far
783+
// already cover the entire range of values, then we know the
784+
// constructor is not missing, and we can move on to the next one.
785+
if remaining_ctors.is_empty() {
786+
break;
787+
}
776788
}
777789

778-
// If the constructor patterns that have been considered so far
779-
// already cover the entire range of values, then we know the
780-
// constructor is not missing, and we can move on to the next one.
781-
if remaining_ctors.is_empty() {
782-
break;
790+
// If a constructor has not been matched, then it is missing.
791+
// We add `remaining_ctors` instead of `self`, because then we can
792+
// provide more detailed error information about precisely which
793+
// ranges have been omitted.
794+
remaining_ctors
795+
} else {
796+
if other_ctors.iter().any(|c| {
797+
c == self
798+
// FIXME(Nadrieril): This condition looks fishy
799+
|| IntRange::from_ctor(tcx, param_env, c).is_some()
800+
}) {
801+
vec![]
802+
} else {
803+
vec![self.clone()]
783804
}
784805
}
785-
786-
// If a constructor has not been matched, then it is missing.
787-
// We add `remaining_ctors` instead of `self`, because then we can
788-
// provide more detailed error information about precisely which
789-
// ranges have been omitted.
790-
remaining_ctors
791806
}
792807
// This constructor is never covered by anything else
793808
NonExhaustive => vec![NonExhaustive],

0 commit comments

Comments
 (0)