Skip to content

Provide a new build-lints crate to hold future custom linters, and run it in CI - #195

Open
drauschenbach wants to merge 3 commits into
cppalliance:masterfrom
drauschenbach:david/new-runvil-lints-crate
Open

drauschenbach wants to merge 3 commits into
cppalliance:masterfrom
drauschenbach:david/new-runvil-lints-crate

Conversation

@drauschenbach

@drauschenbach drauschenbach commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a new lints/build-lints crate, which is a dylint based library for custom workspace rules.

Its first lint, io_try_without_context, rejects a ? that converts a std::io::Error into another error type without adding context. A bare I/O error says "No such file or directory (os error 2)" and nothing about which file or what was being done.

The first lint

io_try_without_context is the dylint project's sample lint. It also happens to be a good one, so it is included here to seed the pattern of where new lints go. It is a hard error by default. It flags x? when:

  • x is a Result<_, std::io::Error>, and
  • the enclosing function, closure or try block returns a different error type, so ? converts the error
    through From.

It doesn't flag ? from one std::io::Result into another. No conversion happens there, and the caller that converts away from std::io::Error is where the context goes. This also keeps std::io::Read and Write implementations easy to write.

Any conversion before the ? satisfies the lint: .map_err(...) into Error with Error::with_cause, anyhow's .context(...), or a crate's own conversion.

The crate

  • Location: lints/build-lints/, outside both the cargo workspace and crates/. A dylint library builds on a
    nightly with rustc_private, while the workspace is pinned to stable 1.99. The build-xtask structural
    checks apply to every crate under crates/, and this crate couldn't satisfy them.
  • Toolchain: pinned to nightly-2026-08-20, paired with the clippy_utils git rev in its Cargo.toml. The two
    change together (cargo dylint upgrade).
  • Name: build-lints, not runvil-lints, because AGENTS.md defines every runvil-* crate as the Engine.
  • Wiring: the root Cargo.toml lists the library under [workspace.metadata.dylint], so cargo dylint --all
    runs it from the repo root.
  • More lints: register_lints registers each lint by hand, so the library can hold more than one; each lint
    is its own module with a UI test under ui/.

CI and docs

  • CI: a new dylint job is added to ci-green. It installs cargo-dylint and dylint-link 6.3.2 and reads the
    nightly from lints/build-lints/rust-toolchain.toml, so the date lives only in that file. Because cargo
    dylint compiles the desktop app, it uses check-workshop-linux's setup: ubuntu-22.04, the Tauri packages,
    npm ci and the stub sidecar. It then runs the lint's UI tests and cargo dylint --all -- --locked
    --workspace --all-targets --all-features, and checks the tree is clean.
  • AGENTS.md: the Verification section gets the custom-lints command, what to install first, and how to add
    a new lint.
  • Plan: vibe/2026-11/2026-11-01-new-lints-crate.md.

Testing

  • cargo test in lints/build-lints: the UI test passes. It covers four flagged cases (a custom From, the
    spelled-out Result, Box, a closure) and four allowed ones (map_err first, io to io, a non-io
    Result, Option).
  • cargo dylint --all -- --locked --workspace --all-targets --all-features: no hits.
  • Both clippy runs with CARGO_BUILD_WARNINGS=deny, cargo fmt --all --check, cargo test -p build-xtask and
    the docs-claims scan: all clean.
  • nextest for runvil, build-xtask, build-ui and workshop-run-log: 340 passed.
  • nextest for the Workshop crates: 313 passed, 1 failed.
    realtime_relay::overload::stalled_browser_cleanup_is_bounded_after_gateway_disconnect fails on every
    run, including with this PR's crate changes stashed, so it was already failing before this PR.
  • The new dylint CI job hasn't run on GitHub yet; this PR will be its first run.

@drauschenbach
drauschenbach force-pushed the david/new-runvil-lints-crate branch from 7b5f63d to fbe8f00 Compare November 4, 2026 18:54
@drauschenbach drauschenbach changed the title Provide a new build-lints crate that creates a place to hold new custom lints, and run it in CI Provide a new build-lints crate to hold future custom lints, and run it in CI Nov 4, 2026
@drauschenbach drauschenbach changed the title Provide a new build-lints crate to hold future custom lints, and run it in CI Provide a new build-lints crate to hold future custom linters, and run it in CI Nov 4, 2026
@drauschenbach
drauschenbach marked this pull request as ready for review November 4, 2026 22:13
awheeler294 added a commit to awheeler294/dylints that referenced this pull request Nov 7, 2026
Moved from lints/build-lints in cppalliance/runvil#195 so the lints can
be shared across the runvil project's repositories. A repository names
this library in its root [workspace.metadata.dylint] as a git source
pinned by rev. Adds a README, AGENTS.md, and CI running fmt, clippy, and
the UI tests on the pinned nightly.

Co-authored-by: David Rauschenbach <david@cppalliance.org>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant