Fix window crash (#57203)

Closes ZED-86Q

Fixes this (rare) crash by making entity creation via a window context
infallible.

The shape of the result is a bit clunky due to the type signatures
involved. The real solution is to remove AsyncWindowContext entirely and
move it's fallible APIs into WindowHandle, but until then this will give
you a simple starting point.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki 2026-05-19 17:05:34 -07:00 committed by GitHub
parent d42edc15f9
commit 952119de41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -378,12 +378,21 @@ impl AppContext for AsyncWindowContext {
where where
T: 'static, T: 'static,
{ {
// Associate the new entity with our captured window so that let mut build_entity = Some(build_entity);
// `with_window` can resolve a dispatch target before the entity has match self.app.update_window(self.window, |_, _, cx| {
// been rendered. cx.new(
self.app build_entity
.update_window(self.window, |_, _, cx| cx.new(build_entity)) .take()
.expect("window was unexpectedly closed") .expect("build_entity is taken exactly once"),
)
}) {
Ok(entity) => entity,
Err(_) => self.app.new(
build_entity
.take()
.expect("update_window returned Err without invoking the closure"),
),
}
} }
fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> { fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> {
@ -395,11 +404,19 @@ impl AppContext for AsyncWindowContext {
reservation: Reservation<T>, reservation: Reservation<T>,
build_entity: impl FnOnce(&mut Context<T>) -> T, build_entity: impl FnOnce(&mut Context<T>) -> T,
) -> Entity<T> { ) -> Entity<T> {
self.app let mut args = Some((reservation, build_entity));
.update_window(self.window, |_, _, cx| { match self.app.update_window(self.window, |_, _, cx| {
let (reservation, build_entity) = args.take().expect("args are taken exactly once");
cx.insert_entity(reservation, build_entity) cx.insert_entity(reservation, build_entity)
}) }) {
.expect("window was unexpectedly closed") Ok(entity) => entity,
Err(_) => {
let (reservation, build_entity) = args
.take()
.expect("update_window returned Err without invoking the closure");
self.app.insert_entity(reservation, build_entity)
}
}
} }
fn update_entity<T: 'static, R>( fn update_entity<T: 'static, R>(