diagnostics: Keep diagnostic excerpt ranges properly ordered (#42298)

Fixes ZED-2CQ

We were doing the binary search by buffer points, but due to await
points within this function we could end up mixing points of differing
buffer versions.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-11-09 10:55:56 +00:00
committed by GitHub
parent 81d38d9872
commit b7d4d1791a
6 changed files with 103 additions and 70 deletions
+2 -2
View File
@@ -1148,9 +1148,9 @@ impl MultiBuffer {
let mut counts: Vec<usize> = Vec::new();
for range in expanded_ranges {
if let Some(last_range) = merged_ranges.last_mut() {
debug_assert!(
assert!(
last_range.context.start <= range.context.start,
"Last range: {last_range:?} Range: {range:?}"
"ranges must be sorted: {last_range:?} <= {range:?}"
);
if last_range.context.end >= range.context.start
|| last_range.context.end.row + 1 == range.context.start.row
+8 -10
View File
@@ -172,7 +172,7 @@ impl MultiBuffer {
.into_iter()
.chunk_by(|id| self.paths_by_excerpt.get(id).cloned())
.into_iter()
.flat_map(|(k, v)| Some((k?, v.into_iter().collect::<Vec<_>>())))
.filter_map(|(k, v)| Some((k?, v.into_iter().collect::<Vec<_>>())))
.collect::<Vec<_>>();
let snapshot = self.snapshot(cx);
@@ -280,7 +280,7 @@ impl MultiBuffer {
.excerpts_by_path
.range(..path.clone())
.next_back()
.map(|(_, value)| *value.last().unwrap())
.and_then(|(_, value)| value.last().copied())
.unwrap_or(ExcerptId::min());
let existing = self
@@ -299,6 +299,7 @@ impl MultiBuffer {
let snapshot = self.snapshot(cx);
let mut next_excerpt_id =
// is this right? What if we remove the last excerpt, then we might reallocate with a wrong mapping?
if let Some(last_entry) = self.snapshot.borrow().excerpt_ids.last() {
last_entry.id.0 + 1
} else {
@@ -311,20 +312,16 @@ impl MultiBuffer {
excerpts_cursor.next();
loop {
let new = new_iter.peek();
let existing = if let Some(existing_id) = existing_iter.peek() {
let locator = snapshot.excerpt_locator_for_id(*existing_id);
let existing = if let Some(&existing_id) = existing_iter.peek() {
let locator = snapshot.excerpt_locator_for_id(existing_id);
excerpts_cursor.seek_forward(&Some(locator), Bias::Left);
if let Some(excerpt) = excerpts_cursor.item() {
if excerpt.buffer_id != buffer_snapshot.remote_id() {
to_remove.push(*existing_id);
to_remove.push(existing_id);
existing_iter.next();
continue;
}
Some((
*existing_id,
excerpt.range.context.to_point(buffer_snapshot),
))
Some((existing_id, excerpt.range.context.to_point(buffer_snapshot)))
} else {
None
}
@@ -332,6 +329,7 @@ impl MultiBuffer {
None
};
let new = new_iter.peek();
if let Some((last_id, last)) = to_insert.last_mut() {
if let Some(new) = new
&& last.context.end >= new.context.start