Move "async move" a few characters to the left in cx.spawn() (#26758)

This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052

TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger 
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki
2025-03-19 02:09:02 +00:00
committed by GitHub
parent 7f2e3fb5bd
commit 1aefa5178b
256 changed files with 3110 additions and 3200 deletions
+24 -21
View File
@@ -1144,9 +1144,9 @@ impl AssistantContext {
fn set_language(&mut self, cx: &mut Context<Self>) {
let markdown = self.language_registry.language_for_name("Markdown");
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
let markdown = markdown.await?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.buffer
.update(cx, |buffer, cx| buffer.set_language(Some(markdown), cx));
})
@@ -1188,7 +1188,7 @@ impl AssistantContext {
return;
};
let debounce = self.token_count.is_some();
self.pending_token_count = cx.spawn(|this, mut cx| {
self.pending_token_count = cx.spawn(async move |this, cx| {
async move {
if debounce {
cx.background_executor()
@@ -1197,13 +1197,14 @@ impl AssistantContext {
}
let token_count = cx.update(|cx| model.count_tokens(request, cx))?.await?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.token_count = Some(token_count);
this.start_cache_warming(&model, cx);
cx.notify()
})
}
.log_err()
.await
});
}
@@ -1342,7 +1343,7 @@ impl AssistantContext {
};
let model = Arc::clone(model);
self.pending_cache_warming_task = cx.spawn(|this, mut cx| {
self.pending_cache_warming_task = cx.spawn(async move |this, cx| {
async move {
match model.stream_completion(request, &cx).await {
Ok(mut stream) => {
@@ -1353,13 +1354,14 @@ impl AssistantContext {
log::warn!("Cache warming failed: {}", e);
}
};
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.update_cache_status_for_completion(cx);
})
.ok();
anyhow::Ok(())
}
.log_err()
.await
});
}
@@ -1916,7 +1918,7 @@ impl AssistantContext {
});
self.reparse(cx);
let insert_output_task = cx.spawn(|this, mut cx| async move {
let insert_output_task = cx.spawn(async move |this, cx| {
let run_command = async {
let mut stream = output.await?;
@@ -1933,7 +1935,7 @@ impl AssistantContext {
while let Some(event) = stream.next().await {
let event = event?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.buffer.update(cx, |buffer, _cx| {
buffer.finalize_last_transaction();
buffer.start_transaction()
@@ -2034,7 +2036,7 @@ impl AssistantContext {
})?;
}
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.buffer.update(cx, |buffer, cx| {
buffer.finalize_last_transaction();
buffer.start_transaction();
@@ -2080,7 +2082,7 @@ impl AssistantContext {
let command_result = run_command.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let version = this.version.clone();
let timestamp = this.next_timestamp();
let Some(invoked_slash_command) = this.invoked_slash_commands.get_mut(&command_id)
@@ -2210,7 +2212,7 @@ impl AssistantContext {
let pending_completion_id = post_inc(&mut self.completion_count);
let task = cx.spawn({
|this, mut cx| async move {
async move |this, cx| {
let stream = model.stream_completion(request, &cx);
let assistant_message_id = assistant_message.id;
let mut response_latency = None;
@@ -2225,7 +2227,7 @@ impl AssistantContext {
}
let event = event?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let message_ix = this
.message_anchors
.iter()
@@ -2264,7 +2266,7 @@ impl AssistantContext {
})?;
smol::future::yield_now().await;
}
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.pending_completions
.retain(|completion| completion.id != pending_completion_id);
this.summarize(false, cx);
@@ -2276,7 +2278,7 @@ impl AssistantContext {
let result = stream_completion.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let error_message = if let Some(error) = result.as_ref().err() {
if error.is::<PaymentRequiredError>() {
cx.emit(ContextEvent::ShowPaymentRequiredError);
@@ -2786,7 +2788,7 @@ impl AssistantContext {
cache: false,
});
self.pending_summary = cx.spawn(|this, mut cx| {
self.pending_summary = cx.spawn(async move |this, cx| {
async move {
let stream = model.stream_completion_text(request, &cx);
let mut messages = stream.await?;
@@ -2795,7 +2797,7 @@ impl AssistantContext {
while let Some(message) = messages.stream.next().await {
let text = message?;
let mut lines = text.lines();
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let version = this.version.clone();
let timestamp = this.next_timestamp();
let summary = this.summary.get_or_insert(ContextSummary::default());
@@ -2819,7 +2821,7 @@ impl AssistantContext {
}
}
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let version = this.version.clone();
let timestamp = this.next_timestamp();
if let Some(summary) = this.summary.as_mut() {
@@ -2837,6 +2839,7 @@ impl AssistantContext {
anyhow::Ok(())
}
.log_err()
.await
});
}
}
@@ -2943,12 +2946,12 @@ impl AssistantContext {
return;
}
self.pending_save = cx.spawn(|this, mut cx| async move {
self.pending_save = cx.spawn(async move |this, cx| {
if let Some(debounce) = debounce {
cx.background_executor().timer(debounce).await;
}
let (old_path, summary) = this.read_with(&cx, |this, _| {
let (old_path, summary) = this.read_with(cx, |this, _| {
let path = this.path.clone();
let summary = if let Some(summary) = this.summary.as_ref() {
if summary.done {
@@ -2963,7 +2966,7 @@ impl AssistantContext {
})?;
if let Some(summary) = summary {
let context = this.read_with(&cx, |this, cx| this.serialize(cx))?;
let context = this.read_with(cx, |this, cx| this.serialize(cx))?;
let mut discriminant = 1;
let mut new_path;
loop {
@@ -2995,7 +2998,7 @@ impl AssistantContext {
}
}
this.update(&mut cx, |this, _| this.path = Some(new_path))?;
this.update(cx, |this, _| this.path = Some(new_path))?;
}
Ok(())
@@ -907,7 +907,7 @@ impl ContextEditor {
if editor_state.opened_patch != patch {
state.update_task = Some({
let this = this.clone();
cx.spawn_in(window, |_, cx| async move {
cx.spawn_in(window, async move |_, cx| {
Self::update_patch_editor(this.clone(), patch, cx)
.await
.log_err();
@@ -1070,10 +1070,9 @@ impl ContextEditor {
})
.ok();
} else {
patch_state.update_task =
Some(cx.spawn_in(window, move |this, cx| async move {
Self::open_patch_editor(this, new_patch, cx).await.log_err();
}));
patch_state.update_task = Some(cx.spawn_in(window, async move |this, cx| {
Self::open_patch_editor(this, new_patch, cx).await.log_err();
}));
}
}
}
@@ -1103,10 +1102,10 @@ impl ContextEditor {
async fn open_patch_editor(
this: WeakEntity<Self>,
patch: AssistantPatch,
mut cx: AsyncWindowContext,
cx: &mut AsyncWindowContext,
) -> Result<()> {
let project = this.read_with(&cx, |this, _| this.project.clone())?;
let resolved_patch = patch.resolve(project.clone(), &mut cx).await;
let project = this.read_with(cx, |this, _| this.project.clone())?;
let resolved_patch = patch.resolve(project.clone(), cx).await;
let editor = cx.new_window_entity(|window, cx| {
let editor = ProposedChangesEditor::new(
@@ -1130,7 +1129,7 @@ impl ContextEditor {
editor
})?;
this.update(&mut cx, |this, _| {
this.update(cx, |this, _| {
if let Some(patch_state) = this.patches.get_mut(&patch.range) {
patch_state.editor = Some(PatchEditorState {
editor: editor.downgrade(),
@@ -1139,8 +1138,8 @@ impl ContextEditor {
patch_state.update_task.take();
}
})?;
this.read_with(&cx, |this, _| this.workspace.clone())?
.update_in(&mut cx, |workspace, window, cx| {
this.read_with(cx, |this, _| this.workspace.clone())?
.update_in(cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(editor.clone()), None, false, window, cx)
})
.log_err();
@@ -1151,11 +1150,11 @@ impl ContextEditor {
async fn update_patch_editor(
this: WeakEntity<Self>,
patch: AssistantPatch,
mut cx: AsyncWindowContext,
cx: &mut AsyncWindowContext,
) -> Result<()> {
let project = this.update(&mut cx, |this, _| this.project.clone())?;
let resolved_patch = patch.resolve(project.clone(), &mut cx).await;
this.update_in(&mut cx, |this, window, cx| {
let project = this.update(cx, |this, _| this.project.clone())?;
let resolved_patch = patch.resolve(project.clone(), cx).await;
this.update_in(cx, |this, window, cx| {
let patch_state = this.patches.get_mut(&patch.range)?;
let locations = resolved_patch
@@ -1625,14 +1624,14 @@ impl ContextEditor {
.map(|path| Workspace::project_path_for_path(project.clone(), &path, false, cx))
.collect::<Vec<_>>();
cx.spawn(move |_, cx| async move {
cx.spawn(async move |_, cx| {
let mut paths = vec![];
let mut worktrees = vec![];
let opened_paths = futures::future::join_all(tasks).await;
for (worktree, project_path) in opened_paths.into_iter().flatten() {
let Ok(worktree_root_name) =
worktree.read_with(&cx, |worktree, _| worktree.root_name().to_string())
worktree.read_with(cx, |worktree, _| worktree.root_name().to_string())
else {
continue;
};
@@ -1649,12 +1648,12 @@ impl ContextEditor {
};
window
.spawn(cx, |mut cx| async move {
.spawn(cx, async move |cx| {
let (paths, dragged_file_worktrees) = paths.await;
let cmd_name = FileSlashCommand.name();
context_editor_view
.update_in(&mut cx, |context_editor, window, cx| {
.update_in(cx, |context_editor, window, cx| {
let file_argument = paths
.into_iter()
.map(|path| path.to_string_lossy().to_string())
@@ -2200,9 +2199,9 @@ impl ContextEditor {
.log_err();
if let Some(client) = client {
cx.spawn(|this, mut cx| async move {
client.authenticate_and_connect(true, &mut cx).await?;
this.update(&mut cx, |_, cx| cx.notify())
cx.spawn(async move |this, cx| {
client.authenticate_and_connect(true, cx).await?;
this.update(cx, |_, cx| cx.notify())
})
.detach_and_log_err(cx)
}
@@ -3161,10 +3160,10 @@ impl FollowableItem for ContextEditor {
assistant_panel_delegate.open_remote_context(workspace, context_id, window, cx)
});
Some(window.spawn(cx, |mut cx| async move {
Some(window.spawn(cx, async move |cx| {
let context_editor = context_editor_task.await?;
context_editor
.update_in(&mut cx, |context_editor, window, cx| {
.update_in(cx, |context_editor, window, cx| {
context_editor.remote_id = Some(id);
context_editor.editor.update(cx, |editor, cx| {
editor.apply_update_proto(
@@ -164,9 +164,9 @@ impl PickerDelegate for SavedContextPickerDelegate {
cx: &mut Context<Picker<Self>>,
) -> Task<()> {
let search = self.store.read(cx).search(query, cx);
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
let matches = search.await;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
let host_contexts = this.delegate.store.read(cx).host_contexts();
this.delegate.matches = host_contexts
.iter()
@@ -100,7 +100,7 @@ impl ContextStore {
let fs = project.read(cx).fs().clone();
let languages = project.read(cx).languages().clone();
let telemetry = project.read(cx).client().telemetry().clone();
cx.spawn(|mut cx| async move {
cx.spawn(async move |cx| {
const CONTEXT_WATCH_DURATION: Duration = Duration::from_millis(100);
let (mut events, _) = fs.watch(contexts_dir(), CONTEXT_WATCH_DURATION).await;
@@ -125,16 +125,15 @@ impl ContextStore {
languages,
slash_commands,
telemetry,
_watch_updates: cx.spawn(|this, mut cx| {
_watch_updates: cx.spawn(async move |this, cx| {
async move {
while events.next().await.is_some() {
this.update(&mut cx, |this, cx| this.reload(cx))?
.await
.log_err();
this.update(cx, |this, cx| this.reload(cx))?.await.log_err();
}
anyhow::Ok(())
}
.log_err()
.await
}),
client_subscription: None,
_project_subscriptions: vec![
@@ -395,7 +394,7 @@ impl ContextStore {
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
let request = self.client.request(proto::CreateContext { project_id });
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
let response = request.await?;
let context_id = ContextId::from_proto(response.context_id);
let context_proto = response.context.context("invalid context")?;
@@ -421,8 +420,8 @@ impl ContextStore {
.collect::<Result<Vec<_>>>()
})
.await?;
context.update(&mut cx, |context, cx| context.apply_ops(operations, cx))?;
this.update(&mut cx, |this, cx| {
context.update(cx, |context, cx| context.apply_ops(operations, cx))?;
this.update(cx, |this, cx| {
if let Some(existing_context) = this.loaded_context_for_id(&context_id, cx) {
existing_context
} else {
@@ -457,7 +456,7 @@ impl ContextStore {
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
let saved_context = load.await?;
let context = cx.new(|cx| {
AssistantContext::deserialize(
@@ -471,7 +470,7 @@ impl ContextStore {
cx,
)
})?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
if let Some(existing_context) = this.loaded_context_for_path(&path, cx) {
existing_context
} else {
@@ -489,7 +488,7 @@ impl ContextStore {
) -> Task<Result<()>> {
let fs = self.fs.clone();
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
fs.remove_file(
&path,
RemoveOptions {
@@ -499,7 +498,7 @@ impl ContextStore {
)
.await?;
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.contexts.retain(|context| {
context
.upgrade()
@@ -565,7 +564,7 @@ impl ContextStore {
});
let prompt_builder = self.prompt_builder.clone();
let slash_commands = self.slash_commands.clone();
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
let response = request.await?;
let context_proto = response.context.context("invalid context")?;
let context = cx.new(|cx| {
@@ -590,8 +589,8 @@ impl ContextStore {
.collect::<Result<Vec<_>>>()
})
.await?;
context.update(&mut cx, |context, cx| context.apply_ops(operations, cx))?;
this.update(&mut cx, |this, cx| {
context.update(cx, |context, cx| context.apply_ops(operations, cx))?;
this.update(cx, |this, cx| {
if let Some(existing_context) = this.loaded_context_for_id(&context_id, cx) {
existing_context
} else {
@@ -700,12 +699,12 @@ impl ContextStore {
project_id,
contexts,
});
cx.spawn(|this, cx| async move {
cx.spawn(async move |this, cx| {
let response = request.await?;
let mut context_ids = Vec::new();
let mut operations = Vec::new();
this.read_with(&cx, |this, cx| {
this.read_with(cx, |this, cx| {
for context_version_proto in response.contexts {
let context_version = ContextVersion::from_proto(&context_version_proto);
let context_id = ContextId::from_proto(context_version_proto.context_id);
@@ -768,7 +767,7 @@ impl ContextStore {
fn reload(&mut self, cx: &mut Context<Self>) -> Task<Result<()>> {
let fs = self.fs.clone();
cx.spawn(|this, mut cx| async move {
cx.spawn(async move |this, cx| {
fs.create_dir(contexts_dir()).await?;
let mut paths = fs.read_dir(contexts_dir()).await?;
@@ -808,7 +807,7 @@ impl ContextStore {
}
contexts.sort_unstable_by_key(|context| Reverse(context.mtime));
this.update(&mut cx, |this, cx| {
this.update(cx, |this, cx| {
this.contexts_metadata = contexts;
cx.notify();
})
@@ -850,7 +849,7 @@ impl ContextStore {
cx.spawn({
let server = server.clone();
let server_id = server_id.clone();
|this, mut cx| async move {
async move |this, cx| {
let Some(protocol) = server.client() else {
return;
};
@@ -875,7 +874,7 @@ impl ContextStore {
})
.collect::<Vec<_>>();
this.update(&mut cx, |this, _cx| {
this.update( cx, |this, _cx| {
this.context_server_slash_command_ids
.insert(server_id.clone(), slash_command_ids);
})
@@ -59,7 +59,7 @@ impl SlashCommandCompletionProvider {
let command_name = command_name.to_string();
let editor = self.editor.clone();
let workspace = self.workspace.clone();
window.spawn(cx, |mut cx| async move {
window.spawn(cx, async move |cx| {
let matches = match_strings(
&candidates,
&command_name,
@@ -100,7 +100,7 @@ impl PickerDelegate for SlashCommandDelegate {
cx: &mut Context<Picker<Self>>,
) -> Task<()> {
let all_commands = self.all_commands.clone();
cx.spawn_in(window, |this, mut cx| async move {
cx.spawn_in(window, async move |this, cx| {
let filtered_commands = cx
.background_spawn(async move {
if query.is_empty() {
@@ -119,7 +119,7 @@ impl PickerDelegate for SlashCommandDelegate {
})
.await;
this.update_in(&mut cx, |this, window, cx| {
this.update_in(cx, |this, window, cx| {
this.delegate.filtered_commands = filtered_commands;
this.delegate.set_selected_index(0, window, cx);
cx.notify();