Skip to content

Commit 36e4955

Browse files
committed
Assert highlight merge invariants in debug mode
1 parent d7ed3fe commit 36e4955

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

helix-core/src/syntax.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,10 @@ struct Merge<I: Iterator<Item = HighlightEvent>> {
18641864
right_queue: Vec<HighlightEvent>,
18651865

18661866
merge_queue: VecDeque<HighlightEvent>,
1867+
1868+
// These fields are only used to assert the invariants in debug builds.
1869+
prior_left: Option<std::ops::Range<usize>>,
1870+
prior_right: Option<std::ops::Range<usize>>,
18671871
}
18681872

18691873
/// Merges two HighlightEvent iterators.
@@ -1900,6 +1904,47 @@ pub fn merge<I: Iterator<Item = HighlightEvent>>(
19001904
left_queue: Vec::new(),
19011905
right_queue: Vec::new(),
19021906
merge_queue: VecDeque::new(),
1907+
prior_left: None,
1908+
prior_right: None,
1909+
}
1910+
}
1911+
1912+
impl<I: Iterator<Item = HighlightEvent>> Merge<I> {
1913+
/// Checks the invariants for the highlight event streams in `left` and `right`.
1914+
/// See the documentation for [merge] above.
1915+
fn check_invariants(&mut self) -> (bool, bool, bool, bool, bool, bool) {
1916+
let (left_min_width_1, left_monotonically_increasing, left_non_overlapping) =
1917+
match self.left.peek() {
1918+
Some(HighlightEvent::Source { start, end }) => match self.prior_left.take() {
1919+
Some(prior) => {
1920+
self.prior_left = Some(*start..*end);
1921+
(start != end, *start > prior.start, *start >= prior.end)
1922+
}
1923+
None => (true, true, true),
1924+
},
1925+
_ => (true, true, true),
1926+
};
1927+
1928+
let (right_min_width_1, right_monotonically_increasing, right_non_overlapping) =
1929+
match self.right.peek() {
1930+
Some(HighlightEvent::Source { start, end }) => match self.prior_right.take() {
1931+
Some(prior) => {
1932+
self.prior_right = Some(*start..*end);
1933+
(start != end, *start > prior.start, *start >= prior.end)
1934+
}
1935+
None => (start != end, true, true),
1936+
},
1937+
_ => (true, true, true),
1938+
};
1939+
1940+
(
1941+
left_min_width_1,
1942+
left_monotonically_increasing,
1943+
left_non_overlapping,
1944+
right_min_width_1,
1945+
right_monotonically_increasing,
1946+
right_non_overlapping,
1947+
)
19031948
}
19041949
}
19051950

@@ -1915,6 +1960,11 @@ impl<I: Iterator<Item = HighlightEvent>> Iterator for Merge<I> {
19151960
}
19161961

19171962
loop {
1963+
debug_assert_eq!(
1964+
(true, true, true, true, true, true),
1965+
self.check_invariants()
1966+
);
1967+
19181968
match (self.left.peek_mut(), self.right.peek_mut()) {
19191969
// Left starts before right.
19201970
(

0 commit comments

Comments
 (0)