From c69912c76a8ee359ef4224d983e63e3178334f32 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 26 Sep 2025 17:17:36 +0200 Subject: [PATCH] Forbid `std::process::Command` spawning, replace with `smol` where appropriate (#38894) std commands can block for an arbitrary duration and so runs risk of blocking tasks for too long. This replaces all such uses where sensible with async processes. Release Notes: - N/A *or* Added/Fixed/Improved ... --- Cargo.toml | 1 + clippy.toml | 11 +++ crates/auto_update/src/auto_update.rs | 21 +++--- crates/auto_update_helper/src/updater.rs | 1 + crates/cli/build.rs | 1 + crates/cli/src/main.rs | 4 ++ crates/collections/src/collections.rs | 19 ----- crates/crashes/src/crashes.rs | 11 +-- .../src/explorer_command_injector.rs | 1 + crates/extension/src/extension_builder.rs | 40 +++++++---- crates/extension_cli/src/main.rs | 3 +- crates/fs/src/fs.rs | 25 ++++--- crates/git/src/repository.rs | 70 ++++++++++++------- crates/gpui/build.rs | 1 + crates/gpui/src/platform/linux/platform.rs | 22 ++++-- crates/gpui/src/platform/mac/platform.rs | 11 ++- crates/gpui/src/platform/windows/platform.rs | 5 ++ crates/media/build.rs | 1 + crates/project/src/environment.rs | 2 +- crates/project/src/git_store.rs | 2 +- crates/project/src/terminals.rs | 6 +- crates/remote_server/build.rs | 1 + crates/remote_server/src/unix.rs | 67 ++++++++++-------- crates/system_specs/src/system_specs.rs | 4 ++ crates/util/src/shell_env.rs | 11 ++- crates/util/src/util.rs | 4 +- crates/vim/src/command.rs | 11 ++- crates/zed/build.rs | 1 + crates/zed/src/main.rs | 2 +- tooling/perf/Cargo.toml | 1 + tooling/xtask/src/tasks/clippy.rs | 1 + 31 files changed, 220 insertions(+), 141 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a40d75fb72f5f0c05ec6d8a4130fab90d256f866..60722aca42712698912cf600ccb867b97a16d8b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -862,6 +862,7 @@ todo = "deny" declare_interior_mutable_const = "deny" redundant_clone = "deny" +disallowed_methods = "deny" # We currently do not restrict any style rules # as it slows down shipping code to Zed. diff --git a/clippy.toml b/clippy.toml index e606ad4c79b5cfe289b1f8460b1f46715103fe1b..57f6f59385a4885730015c3d09f040a5f340d379 100644 --- a/clippy.toml +++ b/clippy.toml @@ -5,3 +5,14 @@ ignore-interior-mutability = [ # and Hash impls do not use fields with interior mutability. "agent::context::AgentContextKey" ] +disallowed-methods = [ + { path = "std::process::Command::spawn", reason = "Spawning `std::process::Command` can block the current thread for an unknown duration", replacement = "smol::process::Command::spawn" }, + { path = "std::process::Command::output", reason = "Spawning `std::process::Command` can block the current thread for an unknown duration", replacement = "smol::process::Command::output" }, + { path = "std::process::Command::status", reason = "Spawning `std::process::Command` can block the current thread for an unknown duration", replacement = "smol::process::Command::status" }, +] +disallowed-types = [ + # { path = "std::collections::HashMap", replacement = "collections::HashMap" }, + # { path = "std::collections::HashSet", replacement = "collections::HashSet" }, + # { path = "indexmap::IndexSet", replacement = "collections::IndexSet" }, + # { path = "indexmap::IndexMap", replacement = "collections::IndexMap" }, +] diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs index 31121aa6f6d68984e1b9a81a4e500d6a3e9c21d1..0d66ddf52fcec527b63f2f57c7a32c62b65bcf3a 100644 --- a/crates/auto_update/src/auto_update.rs +++ b/crates/auto_update/src/auto_update.rs @@ -310,10 +310,10 @@ impl AutoUpdater { // the app after an update, we use `set_restart_path` to run the auto // update helper instead of the app, so that it can overwrite the app // and then spawn the new binary. - let quit_subscription = Some(cx.on_app_quit(|_, _| async move { - #[cfg(target_os = "windows")] - finalize_auto_update_on_quit(); - })); + #[cfg(target_os = "windows")] + let quit_subscription = Some(cx.on_app_quit(|_, _| finalize_auto_update_on_quit())); + #[cfg(not(target_os = "windows"))] + let quit_subscription = None; cx.on_app_restart(|this, _| { this.quit_subscription.take(); @@ -942,11 +942,12 @@ async fn install_release_windows(downloaded_installer: PathBuf) -> Result