Use proper buffer versions when [de]serializing hint proto requests (#8502)
During inlay hint<->proto conversions, uses proper buffer versions and
never carries them across the .await points, to fix the
```
thread 'main' panicked at 'invalid anchor Anchor { timestamp: Lamport {0: 8558}, offset: 54, bias: Right, buffer_id: Some(BufferId(8)) }. buffer id: 8, version: Global {0: 8546, 1: 8378}'
/Users/administrator/actions-runner-2/_work/zed/zed/crates/text/src/text.rs:1919
<backtrace::capture::Backtrace>::create
<backtrace::capture::Backtrace>::new
Zed::init_panic_hook::{closure#0}
std::panicking::rust_panic_with_hook
std::panicking::begin_panic_handler::{{closure}}
std::sys_common::backtrace::__rust_end_short_backtrace
_rust_begin_unwind
core::panicking::panic_fmt
<text::BufferSnapshot>::summary_for_anchor::<usize>
<multi_buffer:⚓:Anchor as multi_buffer::ToOffset>::to_offset
<editor::display_map::DisplayMap>::splice_inlays
<editor::Editor>::splice_inlay_hints
editor::inlay_hint_cache::fetch_and_update_hints::{closure#0}::{closure#0}
<async_task::raw::RawTask<<async_task::runnable::Builder<_>>::spawn_local::Checked<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<(), anyhow::Error>>>>>, core::result::Result<(), anyhow::Error>, <gpui::executor::ForegroundExecutor>::spawn::inner<core::result::Result<(), anyhow::Error>>::{closure#0}, ()>>::run
<gpui::platform::mac::platform::MacPlatform as gpui::platform::Platform>::run
Zed::main
std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>
std::rt::lang_start::<()>::{closure#0}
std::rt::lang_start_internal
_main
```
class of panics.
Release Notes:
- Fixed occasional panics during collaborative editing with inlay hints
on both sides
Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
89caf06dbe
commit
e2bcb28286
1 changed files with 22 additions and 22 deletions
|
@ -5756,7 +5756,6 @@ impl Project {
|
||||||
let range_start = range.start;
|
let range_start = range.start;
|
||||||
let range_end = range.end;
|
let range_end = range.end;
|
||||||
let buffer_id = buffer.remote_id().into();
|
let buffer_id = buffer.remote_id().into();
|
||||||
let buffer_version = buffer.version().clone();
|
|
||||||
let lsp_request = InlayHints { range };
|
let lsp_request = InlayHints { range };
|
||||||
|
|
||||||
if self.is_local() {
|
if self.is_local() {
|
||||||
|
@ -5782,23 +5781,22 @@ impl Project {
|
||||||
buffer_id,
|
buffer_id,
|
||||||
start: Some(serialize_anchor(&range_start)),
|
start: Some(serialize_anchor(&range_start)),
|
||||||
end: Some(serialize_anchor(&range_end)),
|
end: Some(serialize_anchor(&range_end)),
|
||||||
version: serialize_version(&buffer_version),
|
version: serialize_version(&buffer_handle.read(cx).version()),
|
||||||
};
|
};
|
||||||
cx.spawn(move |project, cx| async move {
|
cx.spawn(move |project, cx| async move {
|
||||||
let response = client
|
let response = client
|
||||||
.request(request)
|
.request(request)
|
||||||
.await
|
.await
|
||||||
.context("inlay hints proto request")?;
|
.context("inlay hints proto request")?;
|
||||||
let hints_request_result = LspCommand::response_from_proto(
|
LspCommand::response_from_proto(
|
||||||
lsp_request,
|
lsp_request,
|
||||||
response,
|
response,
|
||||||
project.upgrade().ok_or_else(|| anyhow!("No project"))?,
|
project.upgrade().ok_or_else(|| anyhow!("No project"))?,
|
||||||
buffer_handle.clone(),
|
buffer_handle.clone(),
|
||||||
cx,
|
cx.clone(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.context("inlay hints proto response conversion")
|
||||||
hints_request_result.context("inlay hints proto response conversion")
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Task::ready(Err(anyhow!("project does not have a remote id")))
|
Task::ready(Err(anyhow!("project does not have a remote id")))
|
||||||
|
@ -8074,20 +8072,12 @@ impl Project {
|
||||||
.and_then(|buffer| buffer.upgrade())
|
.and_then(|buffer| buffer.upgrade())
|
||||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))
|
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))
|
||||||
})??;
|
})??;
|
||||||
let buffer_version = deserialize_version(&envelope.payload.version);
|
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
.update(&mut cx, |buffer, _| {
|
.update(&mut cx, |buffer, _| {
|
||||||
buffer.wait_for_version(buffer_version.clone())
|
buffer.wait_for_version(deserialize_version(&envelope.payload.version))
|
||||||
})?
|
})?
|
||||||
.await
|
.await
|
||||||
.with_context(|| {
|
.with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
|
||||||
format!(
|
|
||||||
"waiting for version {:?} for buffer {}",
|
|
||||||
buffer_version,
|
|
||||||
buffer.entity_id()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let start = envelope
|
let start = envelope
|
||||||
.payload
|
.payload
|
||||||
|
@ -8101,13 +8091,19 @@ impl Project {
|
||||||
.context("missing range end")?;
|
.context("missing range end")?;
|
||||||
let buffer_hints = this
|
let buffer_hints = this
|
||||||
.update(&mut cx, |project, cx| {
|
.update(&mut cx, |project, cx| {
|
||||||
project.inlay_hints(buffer, start..end, cx)
|
project.inlay_hints(buffer.clone(), start..end, cx)
|
||||||
})?
|
})?
|
||||||
.await
|
.await
|
||||||
.context("inlay hints fetch")?;
|
.context("inlay hints fetch")?;
|
||||||
|
|
||||||
Ok(this.update(&mut cx, |project, cx| {
|
Ok(this.update(&mut cx, |project, cx| {
|
||||||
InlayHints::response_to_proto(buffer_hints, project, sender_id, &buffer_version, cx)
|
InlayHints::response_to_proto(
|
||||||
|
buffer_hints,
|
||||||
|
project,
|
||||||
|
sender_id,
|
||||||
|
&buffer.read(cx).version(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
})?)
|
})?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8183,10 +8179,14 @@ impl Project {
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let buffer_version = buffer_handle.update(&mut cx, |buffer, _| buffer.version())?;
|
|
||||||
let response = this
|
let response = this
|
||||||
.update(&mut cx, |this, cx| {
|
.update(&mut cx, |this, cx| {
|
||||||
this.request_lsp(buffer_handle, LanguageServerToQuery::Primary, request, cx)
|
this.request_lsp(
|
||||||
|
buffer_handle.clone(),
|
||||||
|
LanguageServerToQuery::Primary,
|
||||||
|
request,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
})?
|
})?
|
||||||
.await?;
|
.await?;
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
|
@ -8194,7 +8194,7 @@ impl Project {
|
||||||
response,
|
response,
|
||||||
this,
|
this,
|
||||||
sender_id,
|
sender_id,
|
||||||
&buffer_version,
|
&buffer_handle.read(cx).version(),
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
})?
|
})?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue