Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ nursery = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
cargo_common_metadata = "allow"
multiple_crate_versions = "allow"
# The task scheduling workflow is a single-threaded async task, so Send bounds are unnecessary.
future_not_send = "allow"

[workspace.dependencies]
allocator-api2 = { version = "0.2.21", default-features = false, features = ["alloc", "std"] }
Expand Down
5 changes: 0 additions & 5 deletions crates/fspy/src/arena.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#![expect(
clippy::future_not_send,
reason = "ouroboros generates async builder methods that cannot satisfy Send bounds"
)]

use allocator_api2::vec::Vec;
use bumpalo::Bump;

Expand Down
5 changes: 0 additions & 5 deletions crates/fspy/src/ipc.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#![expect(
clippy::future_not_send,
reason = "ouroboros generates async builder methods that cannot satisfy Send bounds"
)]

use std::io;

use bincode::borrow_decode_from_slice;
Expand Down
8 changes: 0 additions & 8 deletions crates/vite_task/src/session/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,6 @@ fn detect_globbed_input_change(

// Basic database operations
impl ExecutionCache {
#[expect(
clippy::future_not_send,
reason = "tokio MutexGuard is !Send but this future only runs on a single-threaded runtime"
)]
#[expect(
clippy::significant_drop_tightening,
reason = "lock guard cannot be dropped earlier because prepared statement borrows connection"
Expand Down Expand Up @@ -370,10 +366,6 @@ impl ExecutionCache {
self.get_key_by_value("task_fingerprints", execution_cache_key).await
}

#[expect(
clippy::future_not_send,
reason = "tokio MutexGuard is !Send but this future only runs on a single-threaded runtime"
)]
#[expect(
clippy::significant_drop_tightening,
reason = "lock guard must be held while executing the prepared statement"
Expand Down
4 changes: 0 additions & 4 deletions crates/vite_task/src/session/execute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ impl ExecutionContext<'_> {
///
/// Returns `true` if all tasks succeeded, `false` if any task failed.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "uses !Send types internally")]
async fn execute_expanded_graph(
&mut self,
graph: &ExecutionGraph,
Expand Down Expand Up @@ -132,7 +131,6 @@ impl ExecutionContext<'_> {
///
/// Returns `true` if the execution failed (non-zero exit or infrastructure error).
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "uses !Send types internally")]
async fn execute_leaf(
&mut self,
display: &ExecutionItemDisplay,
Expand Down Expand Up @@ -196,7 +194,6 @@ impl ExecutionContext<'_> {
/// Errors (cache lookup failure, spawn failure, cache update failure) are reported
/// through `leaf_reporter.finish()` and do not abort the caller.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "uses !Send types internally")]
#[expect(
clippy::too_many_lines,
reason = "sequential cache check, execute, and update steps are clearer in one function"
Expand Down Expand Up @@ -531,7 +528,6 @@ impl Session<'_> {
/// Returns `Err(ExitStatus)` to indicate the caller should exit with the given status code.
/// Returns `Ok(())` when all tasks succeeded.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "uses !Send types internally")]
pub(crate) async fn execute_graph(
&self,
execution_graph: ExecutionGraph,
Expand Down
1 change: 0 additions & 1 deletion crates/vite_task/src/session/execute/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ pub struct TrackedPathAccesses {
/// - `path_accesses` if provided, fspy will be used to track file accesses. If `None`, fspy is disabled.
/// - `resolved_negatives` - resolved negative glob patterns for filtering fspy-tracked paths.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "uses !Send dyn AsyncWrite writers internally")]
#[expect(
clippy::too_many_lines,
reason = "spawn logic is inherently sequential and splitting would reduce clarity"
Expand Down
32 changes: 0 additions & 32 deletions crates/vite_task/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,6 @@ impl<'a> Session<'a> {
///
/// Returns an error if the task graph cannot be loaded from the workspace configuration.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
pub async fn ensure_task_graph_loaded(
&mut self,
) -> Result<&IndexedTaskGraph, TaskGraphLoadError> {
Expand Down Expand Up @@ -251,10 +247,6 @@ impl<'a> Session<'a> {
///
/// Returns an error if planning or execution fails.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
pub async fn main(mut self, command: Command) -> anyhow::Result<ExitStatus> {
match self.main_inner(command).await {
Ok(()) => Ok(ExitStatus::SUCCESS),
Expand All @@ -266,10 +258,6 @@ impl<'a> Session<'a> {
/// # Panics
///
/// Panics if parsing a hardcoded bare `RunCommand` fails (should never happen).
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
async fn main_inner(&mut self, command: Command) -> Result<(), SessionError> {
match command.into_resolved() {
ResolvedCommand::Cache { ref subcmd } => self.handle_cache_command(subcmd),
Expand Down Expand Up @@ -343,10 +331,6 @@ impl<'a> Session<'a> {
///
/// In non-interactive mode, prints the task list (or "did you mean" suggestions)
/// and returns `Err(SessionError::EarlyExit(_))` — no further execution needed.
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
#[expect(
clippy::too_many_lines,
reason = "builds interactive/non-interactive select items and handles selection"
Expand Down Expand Up @@ -594,10 +578,6 @@ impl<'a> Session<'a> {
///
/// Returns an error if planning or execution of the synthetic command fails.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
#[expect(
clippy::large_futures,
reason = "execution plan future is large but only awaited once"
Expand Down Expand Up @@ -657,10 +637,6 @@ impl<'a> Session<'a> {
///
/// Returns an error if the plan request cannot be parsed or if planning fails.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
pub async fn plan_from_cli_run(
&mut self,
cwd: Arc<AbsolutePath>,
Expand All @@ -672,10 +648,6 @@ impl<'a> Session<'a> {

/// Internal: plans execution from a resolved run command.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
async fn plan_from_cli_run_resolved(
&mut self,
cwd: Arc<AbsolutePath>,
Expand Down Expand Up @@ -711,10 +683,6 @@ impl<'a> Session<'a> {
///
/// Used by the interactive task selector, which constructs the request
/// directly (bypassing CLI specifier parsing).
#[expect(
clippy::future_not_send,
reason = "session is single-threaded, futures do not need to be Send"
)]
async fn plan_from_query(
&mut self,
request: QueryPlanRequest,
Expand Down
4 changes: 0 additions & 4 deletions crates/vite_task/src/session/reporter/labeled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,6 @@ mod tests {
reporter.new_leaf_execution(display, leaf_kind, all_ancestors_single_node)
}

#[expect(
clippy::future_not_send,
reason = "LeafExecutionReporter futures are !Send in single-threaded reporter tests"
)]
async fn suggestion_for(
display: &ExecutionItemDisplay,
leaf_kind: &LeafExecutionKind,
Expand Down
1 change: 0 additions & 1 deletion crates/vite_task_bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ async fn main() -> anyhow::Result<ExitCode> {
Ok(exit_status.0.into())
}

#[expect(clippy::future_not_send, reason = "Session contains !Send types; single-threaded runtime")]
async fn run() -> anyhow::Result<ExitStatus> {
let args = Args::parse();
let mut owned_config = OwnedSessionConfig::default();
Expand Down
4 changes: 0 additions & 4 deletions crates/vite_task_graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,6 @@ impl IndexedTaskGraph {
clippy::too_many_lines,
reason = "graph loading is inherently sequential and multi-step"
)]
#[expect(
clippy::future_not_send,
reason = "UserConfigLoader uses async_trait(?Send) so the future is intentionally not Send"
)]
pub async fn load(
workspace_root: &WorkspaceRoot,
config_loader: &dyn loader::UserConfigLoader,
Expand Down
1 change: 0 additions & 1 deletion crates/vite_task_plan/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ pub trait TaskGraphLoader {
/// # Errors
/// Returns an error if task graph loading, query, or execution planning fails.
#[tracing::instrument(level = "debug", skip_all)]
#[expect(clippy::future_not_send, reason = "PlanRequestParser and TaskGraphLoader are !Send")]
#[expect(clippy::implicit_hasher, reason = "FxHashMap is the only hasher used in this codebase")]
pub async fn plan_query(
query_plan_request: QueryPlanRequest,
Expand Down
2 changes: 0 additions & 2 deletions crates/vite_task_plan/src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ fn effective_cache_config(
/// `false` when the task itself is being executed as a hook, so that hooks are
/// never expanded more than one level deep (matching npm behavior).
#[expect(clippy::too_many_lines, reason = "sequential planning steps are clearer in one function")]
#[expect(clippy::future_not_send, reason = "PlanContext contains !Send dyn PlanRequestParser")]
async fn plan_task_as_execution_node(
task_node_index: TaskNodeIndex,
mut context: PlanContext<'_>,
Expand Down Expand Up @@ -626,7 +625,6 @@ fn plan_spawn_execution(
/// `vp run build` produces a different query than the script's `vp run -r build`,
/// so the skip rule doesn't fire, but the prune rule catches root in the result).
/// Like the skip rule, extra args don't affect this — only the `TaskQuery` matters.
#[expect(clippy::future_not_send, reason = "PlanContext contains !Send dyn PlanRequestParser")]
pub async fn plan_query_request(
query: Arc<TaskQuery>,
plan_options: PlanOptions,
Expand Down
Loading