Skip to content

Commit d2b7711

Browse files
committed
Match on self first in subtract_constructor
1 parent 235b379 commit d2b7711

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -657,31 +657,43 @@ impl<'tcx> Constructor<'tcx> {
657657
param_env: ty::ParamEnv<'tcx>,
658658
other_ctors: &Vec<Constructor<'tcx>>,
659659
) -> Vec<Constructor<'tcx>> {
660-
let mut refined_ctors = vec![self.clone()];
661-
for other_ctor in other_ctors {
662-
if other_ctor == self {
663-
// If a constructor appears in a `match` arm, we can
664-
// eliminate it straight away.
665-
refined_ctors = vec![]
666-
} else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
667-
// Refine the required constructors for the type by subtracting
668-
// the range defined by the current constructor pattern.
669-
refined_ctors = interval.subtract_from(tcx, param_env, refined_ctors);
660+
match self {
661+
// Those constructors can only match themselves.
662+
Single | Variant(_) | FixedLenSlice(_) => {
663+
if other_ctors.iter().any(|c| c == self) {
664+
vec![]
665+
} else {
666+
vec![self.clone()]
667+
}
670668
}
669+
ConstantRange(..) | ConstantValue(..) => {
670+
let mut remaining_ctors = vec![self.clone()];
671+
for other_ctor in other_ctors {
672+
if other_ctor == self {
673+
// If a constructor appears in a `match` arm, we can
674+
// eliminate it straight away.
675+
remaining_ctors = vec![]
676+
} else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
677+
// Refine the required constructors for the type by subtracting
678+
// the range defined by the current constructor pattern.
679+
remaining_ctors = interval.subtract_from(tcx, param_env, remaining_ctors);
680+
}
671681

672-
// If the constructor patterns that have been considered so far
673-
// already cover the entire range of values, then we know the
674-
// constructor is not missing, and we can move on to the next one.
675-
if refined_ctors.is_empty() {
676-
break;
682+
// If the constructor patterns that have been considered so far
683+
// already cover the entire range of values, then we know the
684+
// constructor is not missing, and we can move on to the next one.
685+
if remaining_ctors.is_empty() {
686+
break;
687+
}
688+
}
689+
690+
// If a constructor has not been matched, then it is missing.
691+
// We add `remaining_ctors` instead of `self`, because then we can
692+
// provide more detailed error information about precisely which
693+
// ranges have been omitted.
694+
remaining_ctors
677695
}
678696
}
679-
680-
// If a constructor has not been matched, then it is missing.
681-
// We add `refined_ctors` instead of `self`, because then we can
682-
// provide more detailed error information about precisely which
683-
// ranges have been omitted.
684-
refined_ctors
685697
}
686698

687699
/// This returns one wildcard pattern for each argument to this constructor.

0 commit comments

Comments
 (0)