Skip to content

fix(deps): async-trait 0.1.92 for clippy::double_must_use - #87

Closed
bkataru wants to merge 45 commits into
mainfrom
fix/async-trait-092-double-must-use
Closed

bkataru wants to merge 45 commits into
mainfrom
fix/async-trait-092-double-must-use

Conversation

@bkataru

@bkataru bkataru commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

fix(deps): async-trait 0.1.92 for clippy::double_must_use

Fixes #86. Lockfile-only — unblocks #82 (RUSTSEC-2026-0285), which is the
only open, high-severity, fixable item in this repo.

Root cause

async-trait 0.1.89 pushes a bare #[must_use] onto every function it
generates:

// async-trait-0.1.89/src/expand.rs:69
method.attrs.push(parse_quote!(#[must_use]));

Those generated fns return Pin<Box<dyn Future>>, and both Pin and Box
are #[must_use] types. So clippy 1.99.0's double_must_use — "has a
#[must_use] attribute with no message, but returns a type already
considered as #[must_use]"
— fires, and -D warnings makes it an error.

There is no #[must_use] in pawan's source. It is synthesised at macro
expansion. This is why a source grep for #[must_use] finds nothing and the
bug looks unreproducible. Clippy says so itself:

note: this error originates in the attribute macro `async_trait`
note: the return type is pinned boxed `futures::Future` trait object

0.1.92 removes that push. The fix is upstream, not a suppression — which
is why no #[allow(clippy::double_must_use)] appears in this diff.

The four sites (all #[async_trait], none in code added here)

crates/pawan-core/src/agent/backend/mod.rs:18:15
crates/pawan-core/src/agent/pool.rs:44:28
crates/pawan-core/src/coordinator/mod.rs:444:15
crates/pawan-core/src/tools/mod.rs:42:15

Verification — both directions, CI's exact flags

Toolchain clippy 1.99.0, the version CI resolves, on origin/main @ de893a9:

arm async-trait command exit sites
A (baseline) 0.1.89 cargo clippy --workspace --exclude eruka-web -- -D warnings 101 4
B (treatment) 0.1.92 same 0 0

Workspace build also clean (exit=0, 11m04s, all five crates).

The exit-code flip is the load-bearing part — 101 → 0, not merely fewer
printed lines. Same tree, same crate, same toolchain; only the macro version
differs.

Note on method: an earlier baseline of mine omitted -D warnings and
reported exit=0 while printing all four sites. A warning-level lint
exits 0 and would let a broken PR merge, so the numbers above are from
flagged runs matching ci.yml:36.

The larger issue this does not fix

pawan pins no toolchain. There is no rust-toolchain.toml on main, and
CI uses floating dtolnay/rust-toolchain@stable. Consequences, both observed
here:

  • A clippy release turned main red days later with no commit to point at.
  • Reproducing it needs 1.99.0, which is installed on the host — but the
    active toolchain is 1.95.0 and the default is 1.98.0, so cargo picks
    1.95.0 and the lint does not exist there. Two separate lanes ran the wrong
    toolchain and reported the lint as unreproducible.

Pinning the toolchain (or passing an explicit toolchain: to the CI action)
stops the whole class of "green until a toolchain release changes it". This
PR fixes one instance; that decision is separate and is the owner's.

Scope

Cargo.lock only, 1 file / +14 −3. async-trait = "0.1" already admits
0.1.92, so no Cargo.toml change. syn v3.0.6 comes along transitively.

bkataru added 30 commits May 30, 2026 02:33
T45–T49: TUI slash handler fixes, test fixes, cleanup
- Remove unused imports (PawanConfig, ToolDefinition) in execute.rs
- Remove dead duplicate functions from construction.rs (already in mod.rs)
- Gate test-only re-exports behind #[cfg(test)] in agent/mod.rs, config/mod.rs
- Remove unused QUEUE_DONE_TTL_MS constant from tools/task.rs
- Add #[allow(dead_code)] on future-API items in pawan-cli (theme, layout, etc.)
- Add v0.5.7 changelog entry with refactoring, features, and test summary
- Update test counts from 988+ to 1627+ across README, crate READMEs, and docs
- pawan-core: remove unused imports, fix mut variables
- pawan-cli: fix clamp, sort_by_key, checked_div, needless borrows
- rename ExportFormat::from_str to parse to avoid std trait confusion
- fix unused variables in tests with .. rest patterns
fix: resolve all clippy -D warnings across workspace
- README.md, crate READMEs, guide.md, triage.md, CHANGELOG.md
docs: update test count and version refs for v0.5.7
…#27)

* fix: remove maki refs, fix NVIDIA model catalog auth, trim fallback list

- Remove 'inspired by maki-ui' from theme.rs and layout.rs comments
- Send Authorization Bearer header when NVIDIA_API_KEY is set
- Replace 500+ hardcoded models with 13 curated fallback models
- Fix clippy sort_by_key and redundant import warnings

* fix: update model catalog tests and snapshot for curated fallback list

- Lower test_default_models_not_empty threshold from 50 to 10
- Accept new model selector snapshot with 13 curated models

* refactor: decompose high-CRAP functions into focused helpers

CRAP Reduction (execute.rs):
- execute_with_all_callbacks: 730 lines → 179 lines (75% reduction)
- Extracted 9 helpers: inject_eruka_context, build_user_prompt,
  apply_iteration_budgets, call_llm_with_retry, accumulate_token_usage,
  strip_thinking_blocks, handle_no_tool_response, check_tool_permissions,
  execute_pending_tools, collect_tool_results

CRAP Reduction (session_ops.rs):
- export_as_html: CC 46 → ~3 (4 helpers: build_html_header, build_html_footer,
  render_message_html, render_tool_calls_html)
- generate_handoff_prompt: CC 49 → ~4 (5 helpers: extract_recent_context,
  extract_mentioned_files, extract_task_items, extract_constraints,
  build_prompt_header)

All 1643 tests pass. Clippy clean.

* refactor: decompose main.rs run(), parse_compaction_summary, quality_score_for

CRAP Reduction:
- main.rs run(): CC 60 → ~30 via setup_config, resolve_session_resume extraction
- parse_compaction_summary: CC 35 → 1 via 6 helper functions (extract_section_content,
  parse_summary_field, parse_token_counts, parse_compressed_sections,
  parse_preserved_sections, parse_numbered_items)
- quality_score_for: CC 37 → 1 via 3 helpers (score_by_vendor, score_by_capability,
  score_by_size)

Coverage baseline captured: 77.28% lines / 79.08% functions / 76.83% branches
All 1643 tests pass. Clippy clean.

* chore(pawan): sync 3 file(s)

* test: add unit tests for pure TUI functions

- scrollbar.rs: 9 tests (construction, render edge cases, color handling)
- fuzzy_search.rs: 12 tests (filter, navigation, command_prefix)
- status_bar.rs: 11 tests (abbrev_model, format_tokens, context_bar)

All 1655 tests pass. Clippy clean.

* refactor(tui): convert render.rs to render/ directory module

* chore(pawan): sync 3 file(s)

* refactor(cli): decompose high-complexity main.rs run functions

Break down run_headless (CC=51), run_commit (CC=40), run_doctor (CC=31),
and run_tasks (CC=31) into focused helper functions to reduce cyclomatic
complexity and CRAP scores. Behavior preserved verbatim.

* test(tui): relocate render snapshots and make CWD redaction width-stable

Move render snapshots into render/snapshots/ after the render module split
and regenerate them against current TUI output. Pad the [CWD] redaction to
preserve line width so the welcome box border stays aligned regardless of
working-directory length, making the snapshot portable across environments.

* refactor: decompose high-complexity functions across cli and core

Decompose App::main_loop, MiseTool::execute, OpenAiCompatBackend
streaming/generate, App::slash_route, and handle_input_panel_key into
focused helper functions. Behavior preserved verbatim.
- LspTool::execute: 10 tests (error paths, arg validation, schema)
- InjectionDetector: 22 tests (scan_file, scan_file_streaming, helpers)
- main.rs helpers: 20 tests (parse_git_status, commit prompt, headless)
- TUI model picker: 8 tests (navigation, input, selection)

Total workspace tests: 1715+
- Workspace version 0.5.8, workspace deps pawan-core/pawan-mcp 0.5.8
- CHANGELOG: add v0.5.8 entry (CRAP reduction, render decomposition, 60 tests)
- Fix CHANGELOG corruption (embedded line numbers, snapshot tags)
- Update test counts 1643→1779 across README, guide, triage, crate READMEs
- Regenerate insta welcome snapshots for v0.5.8
- Update pawan-api health endpoint version in README
TUI redesign + animate-core value tweens (v0.5.9)
chore: v0.5.9 version bump + docs update
Replaces the unmaintained `atty 0.2.14` crate with the stdlib `std::io::IsTerminal` trait (stable since Rust 1.70). Resolves RUSTSEC-2024-0375 (unmaintained) and RUSTSEC-2021-0145 (Windows unaligned read) for pawan-cli's direct dependency on `atty`.

**Changes**
- `crates/pawan-cli/src/main.rs`: 3 call sites switched from `atty::is(Stream::*)` to `std::io::{stdin,stderr}().is_terminal()` (one new `use std::io::IsTerminal;` import)
- `crates/pawan-cli/Cargo.toml`: drop `atty = "0.2.14"`
- `Cargo.lock`: atty and its transitive `hermit-abi` are no longer resolved
- `.cargo/audit.toml`: document accepted-risk suppressions for the 11 advisories (5 vulnerabilities + 6 unmaintained warnings) that remain in the lockfile but are out of reach or already patched
- `cargo fmt --all`: bring workspace into compliance with the current rustfmt (35 files, 446+/396-, no semantic changes)
- Refresh stale welcome-screen snapshot (v0.5.8 → v0.5.9) for the lib and bin targets

**Verification**
- `cargo check -p pawan`: clean
- `cargo test -p pawan`: 269/269 pass locally
- `cargo audit`: clean (0 advisories with the new `.cargo/audit.toml` suppressions)
- `cargo fmt --all -- --check`: clean

**Note on CI**
The 4 `test_render_welcome_snapshot` / `test_session_tags_persist_on_save` failures in CI are pre-existing on `main` (the welcome snapshot still has v0.5.8 but the code is v0.5.9, and `test_session_tags_persist_on_save` is environment-flaky on the session-dir path). The atty fix is unrelated to those failures. They should be addressed in a separate PR.

Closes #4 (RUSTSEC-2024-0375) and #13 (RUSTSEC-2021-0145) via auto-close on merge.
Adds RMUX-backed terminal workflow support, /rmux typed slash command, /model key-release fix, and PTY-backed TUI QA.
Bump workspace crates to v0.5.10 and finalize release notes after RMUX terminal workflow integration.
Adds RMUX live roundtrip testing, kill_session support, /rmux kill routing, and stricter RMUX validation/diagnostics.
Bump workspace crates to v0.5.11 and finalize release notes for RMUX hardening.
Render RMUX snapshot tool results as terminal-focused TUI cards and switch fixed TUI statics to LazyLock.
Bump workspace crates to v0.5.12 and finalize release notes for RMUX snapshot cards.
Adds rmux list_sessions support, /rmux list routing, live roundtrip list assertions, and docs.
Bump workspace crates to v0.5.13 and finalize release notes for RMUX session discovery.
Adds rmux list_panes support, /rmux panes routing, live pane inventory assertions, and docs.
Bump workspace crates to v0.5.14 and finalize release notes for RMUX pane discovery.
Renders rmux list_panes tool results as active-pane inventory cards while preserving generic tool rendering.
Bump workspace crates to v0.5.15 and finalize release notes for RMUX pane-list cards.
Renders rmux list_sessions tool results as active-session inventory cards while preserving other tool rendering.
Bump workspace crates to v0.5.16 and finalize release notes for RMUX session-list cards.
Renders rmux send, key, wait, and kill tool results as action-focused TUI cards.
Bump workspace crates to v0.5.17 and finalize release notes for RMUX status cards.
bkataru added 7 commits June 14, 2026 07:38
Track and render model picker catalog source metadata for fallback vs live NVIDIA catalogs.
async-trait 0.1.89 (src/expand.rs:69) pushes a bare #[must_use] onto
every generated async-trait fn. Those fns return Pin<Box<dyn Future>>,
which is itself #[must_use], so clippy 1.99.0's new double_must_use lint
fires and -D warnings turns it into an error.

0.1.92 removes that push. Lockfile-only: the declared range is already
"0.1", so no Cargo.toml change.

Verified on origin/main @ 46b8118 with clippy 1.99.0 (ci.yml:36 flags):
  async-trait 0.1.89 -> cargo clippy --workspace --exclude eruka-web -- -D warnings
      exit=101, 4 sites
  async-trait 0.1.92 -> same command
      exit=0, 0 sites

Fixes #86. Unblocks #82 (RUSTSEC-2026-0285).
@bkataru

bkataru commented Oct 4, 2026 •

Copy link
Copy Markdown
Member Author

Subsumed by a single verified lockfile, posted on #83. This PR's CI cannot go green on its own: cargo audit fails on advisories outside its scope, and Check & Lint fails on clippy::double_must_use. Combining this bump with async-trait 0.1.92 + rustls 0.23.45 + quinn-proto 0.11.15 + crossbeam-epoch 0.9.20 + h2 0.4.16 + plist 1.10.1 takes the gate from 7 vulnerabilities to 1 with clippy exit 0 and 1826/1826 nextest green (lockfile sha 9dc234af6eba1997, lint result carries a planted-violation control at exit 101). No new PR opened — this needs review, not re-derivation. One caveat: h2 0.3.27 remains and no lockfile can clear it (see #81).

@bkataru

bkataru commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Closing as duplicate — the async-trait 0.1.92 bump landed via #94 (merged, cleared the clippy wall). Thanks for the equivalent work.

@bkataru bkataru closed this Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

main is red on clippy::double_must_use (new stable lint vs -D warnings) — blocks every PR

1 participant