diff options
| author | Nadrieril <nadrieril+git@gmail.com> | 2019-11-09 09:43:15 +0000 |
|---|---|---|
| committer | Nadrieril <nadrieril+git@gmail.com> | 2019-11-15 16:14:34 +0000 |
| commit | c6c862574de4245698452f46025163434a9fbbe1 (patch) | |
| tree | f414ad11efea8da66a6ce6375299eb4967d020ff | |
| parent | 6de7afdf9529ec66bc2fabe7ce012a885cd48002 (diff) | |
| download | rust-c6c862574de4245698452f46025163434a9fbbe1.tar.gz rust-c6c862574de4245698452f46025163434a9fbbe1.zip | |
Special-case subtracting from a range if that range is not an IntRange
| -rw-r--r-- | src/librustc_mir/hair/pattern/_match.rs | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 1b589d5ac84..b84af467d0c 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -763,31 +763,46 @@ impl<'tcx> Constructor<'tcx> { remaining_ctors } ConstantRange(..) | ConstantValue(..) => { - let mut remaining_ctors = vec![self.clone()]; - for other_ctor in other_ctors { - if other_ctor == self { - // If a constructor appears in a `match` arm, we can - // eliminate it straight away. - remaining_ctors = vec![] - } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) { - // Refine the required constructors for the type by subtracting - // the range defined by the current constructor pattern. - remaining_ctors = interval.subtract_from(tcx, param_env, remaining_ctors); + if let Some(_self_range) = IntRange::from_ctor(tcx, param_env, self) { + let mut remaining_ctors = vec![self.clone()]; + for other_ctor in other_ctors { + if other_ctor == self { + // If a constructor appears in a `match` arm, we can + // eliminate it straight away. + remaining_ctors = vec![] + } else if let Some(interval) = + IntRange::from_ctor(tcx, param_env, other_ctor) + { + // Refine the required constructors for the type by subtracting + // the range defined by the current constructor pattern. + remaining_ctors = + interval.subtract_from(tcx, param_env, remaining_ctors); + } + + // If the constructor patterns that have been considered so far + // already cover the entire range of values, then we know the + // constructor is not missing, and we can move on to the next one. + if remaining_ctors.is_empty() { + break; + } } - // If the constructor patterns that have been considered so far - // already cover the entire range of values, then we know the - // constructor is not missing, and we can move on to the next one. - if remaining_ctors.is_empty() { - break; + // If a constructor has not been matched, then it is missing. + // We add `remaining_ctors` instead of `self`, because then we can + // provide more detailed error information about precisely which + // ranges have been omitted. + remaining_ctors + } else { + if other_ctors.iter().any(|c| { + c == self + // FIXME(Nadrieril): This condition looks fishy + || IntRange::from_ctor(tcx, param_env, c).is_some() + }) { + vec![] + } else { + vec![self.clone()] } } - - // If a constructor has not been matched, then it is missing. - // We add `remaining_ctors` instead of `self`, because then we can - // provide more detailed error information about precisely which - // ranges have been omitted. - remaining_ctors } // This constructor is never covered by anything else NonExhaustive => vec![NonExhaustive], |
