Fix panic when editor::OpenSelectionsInMultibuffer only has pending selection (#32842)

On the panics dashboard, saw this panic of `There must be at least one
selection` in `open_locations_in_multibuffer`. Only seems to have
happened once in the past month.

Fix is to include the pending selection. Since `selections.all()` cannot
provide anchor selections, added `selections.all_anchors()` which only
really does any work if there is a pending selection.

Also fixes a corner case in jump-to-definitions where if the definition
is `HoverLink::InlayHint` and the `compute_target_location` fails for
all definitions it could potentially also trigger this case (and return
`Navigated::Yes` instead of `Navigated::No`

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-06-17 02:35:14 -06:00 committed by GitHub
parent 0e794fa0ac
commit 2f3acb6185
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 60 additions and 25 deletions

View file

@ -15130,16 +15130,21 @@ impl Editor {
})
.context("location tasks preparation")?;
let locations = future::join_all(location_tasks)
let locations: Vec<Location> = future::join_all(location_tasks)
.await
.into_iter()
.filter_map(|location| location.transpose())
.collect::<Result<_>>()
.context("location tasks")?;
if locations.is_empty() {
return Ok(Navigated::No);
}
let Some(workspace) = workspace else {
return Ok(Navigated::No);
};
let opened = workspace
.update_in(cx, |workspace, window, cx| {
Self::open_locations_in_multibuffer(
@ -15303,6 +15308,11 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Workspace>,
) {
if locations.is_empty() {
log::error!("bug: open_locations_in_multibuffer called with empty list of locations");
return;
}
// If there are multiple definitions, open them in a multibuffer
locations.sort_by_key(|location| location.buffer.read(cx).remote_id());
let mut locations = locations.into_iter().peekable();
@ -18289,18 +18299,18 @@ impl Editor {
return;
};
let title = multibuffer.title(cx).to_string();
let locations = self
.selections
.disjoint_anchors()
.iter()
.map(|range| Location {
.all_anchors(cx)
.into_iter()
.map(|selection| Location {
buffer: buffer.clone(),
range: range.start.text_anchor..range.end.text_anchor,
range: selection.start.text_anchor..selection.end.text_anchor,
})
.collect::<Vec<_>>();
let title = multibuffer.title(cx).to_string();
cx.spawn_in(window, async move |_, cx| {
workspace.update_in(cx, |workspace, window, cx| {
Self::open_locations_in_multibuffer(