mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-11 05:00:16 +00:00
editor: Ensure allocation reuse (#14577)
In #14567 I claimed that the underlying allocation is reused. And it was. At the time I've submitted a PR I was using `.filter_map(|x| x)`, which got flagged by clippy as something that could be simplified to `.flatten()` - that however broke the allocation reuse promise. Thus, this PR goes back to using `filter_map` and additionally in debug builds it performs checks for allocation reuse. With .flatten in place, a bunch of unit test fail on that branch, so the checks do work. Release Notes: - N/A
This commit is contained in:
parent
1b85438df9
commit
09c497f744
3 changed files with 19 additions and 8 deletions
|
@ -817,8 +817,11 @@ fn consolidate_inlay_edits(mut edits: Vec<InlayEdit>) -> Vec<InlayEdit> {
|
||||||
.then_with(|| b.old.end.cmp(&a.old.end))
|
.then_with(|| b.old.end.cmp(&a.old.end))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let _old_alloc_ptr = edits.as_ptr();
|
||||||
let mut inlay_edits = edits.into_iter();
|
let mut inlay_edits = edits.into_iter();
|
||||||
let inlay_edits = if let Some(mut first_edit) = inlay_edits.next() {
|
let inlay_edits = if let Some(mut first_edit) = inlay_edits.next() {
|
||||||
|
// This code relies on reusing allocations from the Vec<_> - at the time of writing .flatten() prevents them.
|
||||||
|
#[allow(clippy::filter_map_identity)]
|
||||||
let mut v: Vec<_> = inlay_edits
|
let mut v: Vec<_> = inlay_edits
|
||||||
.scan(&mut first_edit, |prev_edit, edit| {
|
.scan(&mut first_edit, |prev_edit, edit| {
|
||||||
if prev_edit.old.end >= edit.old.start {
|
if prev_edit.old.end >= edit.old.start {
|
||||||
|
@ -831,10 +834,10 @@ fn consolidate_inlay_edits(mut edits: Vec<InlayEdit>) -> Vec<InlayEdit> {
|
||||||
Some(Some(prev)) // Yield the previous edit
|
Some(Some(prev)) // Yield the previous edit
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
v.push(first_edit.clone());
|
v.push(first_edit.clone());
|
||||||
|
debug_assert_eq!(_old_alloc_ptr, v.as_ptr(), "Inlay edits were reallocated");
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -850,9 +853,11 @@ fn consolidate_fold_edits(mut edits: Vec<FoldEdit>) -> Vec<FoldEdit> {
|
||||||
.cmp(&b.old.start)
|
.cmp(&b.old.start)
|
||||||
.then_with(|| b.old.end.cmp(&a.old.end))
|
.then_with(|| b.old.end.cmp(&a.old.end))
|
||||||
});
|
});
|
||||||
|
let _old_alloc_ptr = edits.as_ptr();
|
||||||
let mut fold_edits = edits.into_iter();
|
let mut fold_edits = edits.into_iter();
|
||||||
let fold_edits = if let Some(mut first_edit) = fold_edits.next() {
|
let fold_edits = if let Some(mut first_edit) = fold_edits.next() {
|
||||||
|
// This code relies on reusing allocations from the Vec<_> - at the time of writing .flatten() prevents them.
|
||||||
|
#[allow(clippy::filter_map_identity)]
|
||||||
let mut v: Vec<_> = fold_edits
|
let mut v: Vec<_> = fold_edits
|
||||||
.scan(&mut first_edit, |prev_edit, edit| {
|
.scan(&mut first_edit, |prev_edit, edit| {
|
||||||
if prev_edit.old.end >= edit.old.start {
|
if prev_edit.old.end >= edit.old.start {
|
||||||
|
@ -865,7 +870,7 @@ fn consolidate_fold_edits(mut edits: Vec<FoldEdit>) -> Vec<FoldEdit> {
|
||||||
Some(Some(prev)) // Yield the previous edit
|
Some(Some(prev)) // Yield the previous edit
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
v.push(first_edit.clone());
|
v.push(first_edit.clone());
|
||||||
v
|
v
|
||||||
|
|
|
@ -103,9 +103,12 @@ impl TabMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _old_alloc_ptr = fold_edits.as_ptr();
|
||||||
// Combine any edits that overlap due to the expansion.
|
// Combine any edits that overlap due to the expansion.
|
||||||
let mut fold_edits = fold_edits.into_iter();
|
let mut fold_edits = fold_edits.into_iter();
|
||||||
let fold_edits = if let Some(mut first_edit) = fold_edits.next() {
|
let fold_edits = if let Some(mut first_edit) = fold_edits.next() {
|
||||||
|
// This code relies on reusing allocations from the Vec<_> - at the time of writing .flatten() prevents them.
|
||||||
|
#[allow(clippy::filter_map_identity)]
|
||||||
let mut v: Vec<_> = fold_edits
|
let mut v: Vec<_> = fold_edits
|
||||||
.scan(&mut first_edit, |state, edit| {
|
.scan(&mut first_edit, |state, edit| {
|
||||||
if state.old.end >= edit.old.start {
|
if state.old.end >= edit.old.start {
|
||||||
|
@ -119,10 +122,10 @@ impl TabMap {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
v.push(first_edit);
|
v.push(first_edit);
|
||||||
|
debug_assert_eq!(v.as_ptr(), _old_alloc_ptr, "Fold edits were reallocated");
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
|
|
@ -1009,8 +1009,11 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consolidate_wrap_edits(edits: Vec<WrapEdit>) -> Vec<WrapEdit> {
|
fn consolidate_wrap_edits(edits: Vec<WrapEdit>) -> Vec<WrapEdit> {
|
||||||
|
let _old_alloc_ptr = edits.as_ptr();
|
||||||
let mut wrap_edits = edits.into_iter();
|
let mut wrap_edits = edits.into_iter();
|
||||||
let wrap_edits = if let Some(mut first_edit) = wrap_edits.next() {
|
let wrap_edits = if let Some(mut first_edit) = wrap_edits.next() {
|
||||||
|
// This code relies on reusing allocations from the Vec<_> - at the time of writing .flatten() prevents them.
|
||||||
|
#[allow(clippy::filter_map_identity)]
|
||||||
let mut v: Vec<_> = wrap_edits
|
let mut v: Vec<_> = wrap_edits
|
||||||
.scan(&mut first_edit, |prev_edit, edit| {
|
.scan(&mut first_edit, |prev_edit, edit| {
|
||||||
if prev_edit.old.end >= edit.old.start {
|
if prev_edit.old.end >= edit.old.start {
|
||||||
|
@ -1022,10 +1025,10 @@ fn consolidate_wrap_edits(edits: Vec<WrapEdit>) -> Vec<WrapEdit> {
|
||||||
Some(Some(prev)) // Yield the previous edit
|
Some(Some(prev)) // Yield the previous edit
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten()
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
v.push(first_edit.clone());
|
v.push(first_edit.clone());
|
||||||
|
debug_assert_eq!(v.as_ptr(), _old_alloc_ptr, "Wrap edits were reallocated");
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
|
|
Loading…
Reference in a new issue