From f829523340a84624b07a929b5092a5b996f090a6 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 9 Nov 2021 05:44:02 +0200 Subject: [PATCH] Simplify range comparison code Reword the `Kind` type so that the `cmp` function is simpler. --- clippy_lints/src/matches.rs | 65 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 7a528cb0b3891..cedf0777ac451 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1698,75 +1698,58 @@ pub fn overlapping(ranges: &[SpannedRange]) -> Option<(&SpannedRange, & where T: Copy + Ord, { - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - enum Kind<'a, T> { - Start(T, &'a SpannedRange), - End(EndBound, &'a SpannedRange), + #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] + enum BoundKind { + EndExcluded, + Start, + EndIncluded, } - impl<'a, T: Copy> Kind<'a, T> { - fn value(self) -> T { - match self { - Kind::Start(t, _) | Kind::End(EndBound::Included(t) | EndBound::Excluded(t), _) => t, - } - } - } + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + struct RangeBound<'a, T>(T, BoundKind, &'a SpannedRange); - impl<'a, T: Copy + Ord> PartialOrd for Kind<'a, T> { + impl<'a, T: Copy + Ord> PartialOrd for RangeBound<'a, T> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } - impl<'a, T: Copy + Ord> Ord for Kind<'a, T> { - fn cmp(&self, other: &Self) -> Ordering { - match self.value().cmp(&other.value()) { - Ordering::Equal => match (self, other) { - // End excluded before start and end included - (Kind::End(EndBound::Excluded(_), _), Kind::Start(..) | Kind::End(EndBound::Included(_), _)) => { - Ordering::Less - }, - (Kind::Start(..) | Kind::End(EndBound::Included(_), _), Kind::End(EndBound::Excluded(_), _)) => { - Ordering::Greater - }, - - // Start before end included - (Kind::Start(..), Kind::End(EndBound::Included(_), _)) => Ordering::Less, - (Kind::End(EndBound::Included(_), _), Kind::Start(..)) => Ordering::Greater, - - _ => Ordering::Equal, - }, - other => other, - } + impl<'a, T: Copy + Ord> Ord for RangeBound<'a, T> { + fn cmp(&self, RangeBound(other_value, other_kind, _): &Self) -> Ordering { + let RangeBound(self_value, self_kind, _) = *self; + (self_value, self_kind).cmp(&(*other_value, *other_kind)) } } let mut values = Vec::with_capacity(2 * ranges.len()); - for r in ranges { - values.push(Kind::Start(r.node.0, r)); - values.push(Kind::End(r.node.1, r)); + for r @ SpannedRange { node: (start, end), .. } in ranges { + values.push(RangeBound(*start, BoundKind::Start, r)); + values.push(match end { + EndBound::Excluded(val) => RangeBound(*val, BoundKind::EndExcluded, r), + EndBound::Included(val) => RangeBound(*val, BoundKind::EndIncluded, r), + }); } values.sort(); let mut started = vec![]; - for value in values { - match value { - Kind::Start(_, r) => started.push(r), - Kind::End(_, er) => { + for RangeBound(_, kind, r) in values { + match kind { + BoundKind::Start => started.push(r), + BoundKind::EndExcluded | BoundKind::EndIncluded => { let mut overlap = None; while let Some(sr) = started.pop() { - if sr == er { + if sr == r { break; } overlap = Some(sr); } if let Some(sr) = overlap { - return Some((er, sr)); + return Some((r, sr)); } }, }