lints
A dylint library that flags various bad patterns in our codebase.
Install dylint, a pinned nightly toolchain and the necessary tools with
cargo install cargo-dylint dylint-link
cd tooling/lints
rustup toolchain install
The channel and its components (rustc-dev, rust-src, llvm-tools-preview)
are declared in tooling/lints/rust-toolchain.toml, so rustup toolchain install
picks them up automatically when run from that directory.
Demo
./single-lint blocking_io_on_foreground
Current lints
shared_string_from_str_literal—SharedString::new/frometc whereSharedString::from_staticshould be used instead.async_block_without_await—async { … }blocks whose body contains no.awaitexpression.entity_update_in_render—Entity::update/WeakEntity::updatemutating an entity insideRender::render.notify_in_render—Context::notify()called insideRender::render.owned_string_into_shared—String::from(<lit>).into()/<lit>.to_string().into()/<lit>.to_owned().into()whose target isSharedString,Arc<str>,Rc<str>, orCow<'_, str>.blocking_io_on_foreground- Catch blocking IO calls that are called on the main thread (but not on closures or background threads)
How to run
Ideally you run this as part of the clippy script in the zed/scripts directory since this will also run our other linters.
Prerequisites
Install both tools (version 6 or later):
cargo install cargo-dylint dylint-link
cargo-dylintis thecargosubcommand that builds and runs the lints;dylint-linkis the linker used to build the lint library.
The workspace registers this library under [workspace.metadata.dylint] in the
root Cargo.toml, so Dylint discovers it automatically — you do not pass a
--path. The first run builds the library against its pinned nightly (see
rust-toolchain.toml) and is slow; later runs are cached.
Run all lints against the whole repo
cargo dylint --all -- --workspace
Run all lints against a single crate
cargo dylint --all -- -p project_panel
Run a single lint
The library loads every lint at once. To run just one, use the single-lint
helper, which silences the rest and force-enables the one you name:
tooling/lints/single-lint blocking_io_on_foreground -p project_panel
The first argument is the lint name (one of the snake_case identifiers under
Current lints); everything after it is passed to cargo check
and defaults to --workspace. Under the hood the script runs:
DYLINT_RUSTFLAGS="-A warnings --force-warn <lint>" cargo dylint --all -- <args>
It also handles two non-obvious gotchas:
--force-warnis required: after-A warningssilences the group, a plain-W <lint>does not reliably re-enable a driver-registered lint.DYLINT_RUSTFLAGSis not part of Cargo's fingerprint, so the script cleans the targeted package(s) first; otherwise Cargo replays a stale cache and the filter appears to do nothing.