mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-04 05:13:28 +00:00
Adds a dylint library under tooling/lints that flags Zed-specific anti-patterns: * shared_string_from_str_literal, * async_block_without_await, * entity_update_in_render, * notify_in_render, * owned_string_into_shared, * len_in_loop_condition, and * blocking_io_on_foreground. Includes UI tests, a single-lint helper, and workspace.metadata.dylint registration so cargo dylint --all discovers it. The library pins its own nightly toolchain (kept out of the main workspace) and tracks dylint 6. Release Notes: - N/A Self-Review Checklist: - [ ] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable Closes #ISSUE Release Notes: - N/A or Added/Fixed/Improved ...
86 lines
3 KiB
Markdown
86 lines
3 KiB
Markdown
# lints
|
|
|
|
A [dylint](https://github.com/trailofbits/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/from` etc where `SharedString::from_static` should be used instead.
|
|
- `async_block_without_await` — `async { … }` blocks whose body contains no `.await` expression.
|
|
- `entity_update_in_render` — `Entity::update`/`WeakEntity::update` mutating an entity inside `Render::render`.
|
|
- `notify_in_render` — `Context::notify()` called inside `Render::render`.
|
|
- `owned_string_into_shared` — `String::from(<lit>).into()` / `<lit>.to_string().into()` / `<lit>.to_owned().into()` whose target is `SharedString`, `Arc<str>`, `Rc<str>`, or `Cow<'_, 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-dylint` is the `cargo` subcommand that builds and runs the lints; `dylint-link` is 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](#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-warn` is required: after `-A warnings` silences the group, a plain
|
|
`-W <lint>` does not reliably re-enable a driver-registered lint.
|
|
- `DYLINT_RUSTFLAGS` is 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.
|