Avoid panics when normalizing completion label with invalid ranges (#23712)

Dev builds show panics related to completion label normalization

<details>
<summary>Panic</summary>

```
index out of bounds: the len is 103 but the index is 103
zed::reliability::init_panic_hook::{{closure}}::h78130eff43c84f6f+110375521
std::panicking::rust_panic_with_hook::hfe205f6954b2c97b+87457752
std::panicking::begin_panic_handler::{{closure}}::h6cb44b3a50f28c44+87456967
std::sys::backtrace::__rust_end_short_backtrace::hf1c1f2a92799bb0e+87449337
rust_begin_unwind+87456084
core::panicking::panic_fmt::h3d8fc78294164da7+7033011
core::panicking::panic_bounds_check::h9397cb495d89a72d+7033511
project::lsp_store::ensure_uniform_list_compatible_label::haf80316ce11edd67+72663592
project::lsp_store::populate_labels_for_completions::{{closure}}::hc93c3c540ef7d2d6+72642960
project::lsp_store::LspStore::completions::{{closure}}::{{closure}}::hb4b5432e24432ca8+72336627
async_task::raw::RawTask<F,T,S,M>::run::hf444c3dc07dd583b+68504803
<gpui::platform::linux::wayland::client::WaylandClient as gpui::platform::linux::platform::LinuxClient>::run::hbf5a316eb781a10d+50646579
gpui::platform::linux::platform::<impl gpui::platform::Platform for P>::run::hc85518d4552fc4cd+50496669
gpui::app::App::run::hca4e2eaf984ca6f6+109905269
zed::main::h849467ac1a6d32c9+110413414
std::sys::backtrace::__rust_begin_short_backtrace::h81b5ee155a7cf505+110835475
std::rt::lang_start::{{closure}}::h48a83f884cfb6865+110834761
std::rt::lang_start_internal::h5e7c81cecd7f0954+87382485
main+110425932
__libc_start_call_main+22789462491720
__libc_start_main_alias_1+22789462491915
_start+10436606
```
</details>

This can only happen when either `label.runs` or `label.filter_range`
has a range that's larger than the label text, which is an error.
Instead of panicking, log such errors and fall back to last index (which
is not really helpful, but still).

Release Notes:

- N/A
This commit is contained in:
Kirill Bulatov 2025-01-27 16:18:39 +02:00 committed by GitHub
parent 06d00b940d
commit 5bde053b0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8801,16 +8801,59 @@ fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
return;
}
for (range, _) in &mut label.runs {
range.start = offset_map[range.start];
range.end = offset_map[range.end];
let last_index = new_idx;
let mut run_ranges_errors = Vec::new();
label.runs.retain_mut(|(range, _)| {
match offset_map.get(range.start) {
Some(&start) => range.start = start,
None => {
run_ranges_errors.push(range.clone());
return false;
}
}
match offset_map.get(range.end) {
Some(&end) => range.end = end,
None => {
run_ranges_errors.push(range.clone());
range.end = last_index;
}
}
true
});
if !run_ranges_errors.is_empty() {
log::error!(
"Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
label.text
);
}
let mut wrong_filter_range = None;
if label.filter_range == (0..label.text.len()) {
label.filter_range = 0..new_text.len();
} else {
label.filter_range.start = offset_map[label.filter_range.start];
label.filter_range.end = offset_map[label.filter_range.end];
let mut original_filter_range = Some(label.filter_range.clone());
match offset_map.get(label.filter_range.start) {
Some(&start) => label.filter_range.start = start,
None => {
wrong_filter_range = original_filter_range.take();
label.filter_range.start = last_index;
}
}
match offset_map.get(label.filter_range.end) {
Some(&end) => label.filter_range.end = end,
None => {
wrong_filter_range = original_filter_range.take();
label.filter_range.end = last_index;
}
}
}
if let Some(wrong_filter_range) = wrong_filter_range {
log::error!(
"Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
label.text
);
}
label.text = new_text;