From f7268c30ae617b690a69b0be0e48a621b8179f40 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Fri, 16 Oct 2026 06:32:02 -0700 Subject: [PATCH 1/3] chore(lint): deny clippy async-hazard lints Add await_holding_lock, await_holding_refcell_ref and await_holding_invalid_type (deny) plus large_futures (warn) to the workspace clippy lints, with an await-holding-invalid-types list of std sync guards and RefCell borrows that must not live across .await. --- .clippy.toml | 10 ++++++++++ Cargo.toml | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/.clippy.toml b/.clippy.toml index 61fdd2ffb..50dfb9e0b 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1,11 @@ msrv = "1.95.0" + +# Types that must never be held across an `.await` point +# (enforced by clippy::await_holding_invalid_type, see Cargo.toml). +await-holding-invalid-types = [ + { path = "std::sync::MutexGuard", reason = "std mutex guard blocks the async worker; drop before .await or use tokio::sync::Mutex" }, + { path = "std::sync::RwLockReadGuard", reason = "std rwlock guard blocks the async worker; drop before .await" }, + { path = "std::sync::RwLockWriteGuard", reason = "std rwlock guard blocks the async worker; drop before .await" }, + { path = "std::cell::Ref", reason = "RefCell borrow across .await panics on re-entrant borrow" }, + { path = "std::cell::RefMut", reason = "RefCell borrow across .await panics on re-entrant borrow" }, +] diff --git a/Cargo.toml b/Cargo.toml index 98558afa9..b1c48fd67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -224,3 +224,9 @@ debug = false [workspace.lints.clippy] cognitive_complexity = "warn" too_many_lines = "warn" +# Async hazards: a sync guard held across `.await` can deadlock the runtime +# or block a worker thread. Type list lives in clippy.toml. +await_holding_lock = "deny" +await_holding_refcell_ref = "deny" +await_holding_invalid_type = "deny" +large_futures = "warn" From 15aff19cef4dbdd77c5543248af0664ef849e7a0 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sat, 24 Oct 2026 03:25:02 -0700 Subject: [PATCH 2/3] fix(lint): heap the 64 KiB archive-hash buffer and set large_futures threshold to 32 KiB The buffer was held across .await, making resolve_archive_source's future 64 KiB. The default 16 KiB threshold also flagged every build orchestrator's composed pipeline future (17-25 KiB) under -D warnings. Co-Authored-By: Claude --- .clippy.toml | 6 ++++++ crates/fbuild-packages-fetch/src/platformio_repository.rs | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.clippy.toml b/.clippy.toml index 50dfb9e0b..d44863072 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -9,3 +9,9 @@ await-holding-invalid-types = [ { path = "std::cell::Ref", reason = "RefCell borrow across .await panics on re-entrant borrow" }, { path = "std::cell::RefMut", reason = "RefCell borrow across .await panics on re-entrant borrow" }, ] + +# clippy::large_futures (warn, so fatal under -D warnings). The default 16 KiB +# flags every build-orchestrator pipeline future (17-25 KiB of composed +# state); 32 KiB still catches real mistakes such as a 64 KiB stack buffer +# held across `.await`. +future-size-threshold = 32768 diff --git a/crates/fbuild-packages-fetch/src/platformio_repository.rs b/crates/fbuild-packages-fetch/src/platformio_repository.rs index 3182d05e3..f94bb3031 100644 --- a/crates/fbuild-packages-fetch/src/platformio_repository.rs +++ b/crates/fbuild-packages-fetch/src/platformio_repository.rs @@ -162,7 +162,9 @@ pub async fn resolve_archive_source( .await .map_err(|error| RepositoryError::Archive(error.to_string()))?; let mut hasher = Sha256::new(); - let mut buffer = [0_u8; 64 * 1024]; + // Heap, not stack: the buffer is held across `.await`, so an array would + // make this future 64 KiB (clippy::large_futures). + let mut buffer = vec![0_u8; 64 * 1024]; loop { let read = file .read(&mut buffer) From 50e3f3bee2bf9bb76443ef7513df4d853b563813 Mon Sep 17 00:00:00 2001 From: Zach Vorhies Date: Sat, 24 Oct 2026 03:34:57 -0700 Subject: [PATCH 3/3] docs(lint): name .clippy.toml correctly in the Cargo.toml lint comment Co-Authored-By: Claude --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9050678f6..194148244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -225,7 +225,7 @@ debug = false cognitive_complexity = "warn" too_many_lines = "warn" # Async hazards: a sync guard held across `.await` can deadlock the runtime -# or block a worker thread. Type list lives in clippy.toml. +# or block a worker thread. Type list lives in .clippy.toml. await_holding_lock = "deny" await_holding_refcell_ref = "deny" await_holding_invalid_type = "deny"