core-agent-ide/tools/argument-comment-lint
Michael Bolin b87ba0a3cc
Publish runnable DotSlash package for argument-comment lint (#15198)
## Why

To date, the argument-comment linter introduced in
https://github.com/openai/codex/pull/14651 had to be built from source
to run, which can be a bit slow (both for local dev and when it is run
in CI). Because of the potential slowness, I did not wire it up to run
as part of `just clippy` or anything like that. As a result, I have seen
a number of occasions where folks put up PRs that violate the lint, see
it fail in CI, and then have to put up their PR again.

The goal of this PR is to pre-build a runnable version of the linter and
then make it available via a DotSlash file. Once it is available, I will
update `just clippy` and other touchpoints to make it a natural part of
the dev cycle so lint violations should get flagged _before_ putting up
a PR for review.

To get things started, we will build the DotSlash file as part of an
alpha release. Though I don't expect the linter to change often, so I'll
probably change this to only build as part of mainline releases once we
have a working DotSlash file. (Ultimately, we should probably move the
linter into its own repo so it can have its own release cycle.)

## What Changed
- add a reusable `rust-release-argument-comment-lint.yml` workflow that
builds host-specific archives for macOS arm64, Linux arm64/x64, and
Windows x64
- wire `rust-release.yml` to publish the `argument-comment-lint`
DotSlash manifest on all releases for now, including alpha tags
- package a runnable layout instead of a bare library

The Unix archive layout is:

```text
argument-comment-lint/
  bin/
    argument-comment-lint
    cargo-dylint
  lib/
    libargument_comment_lint@nightly-2025-09-18-<target>.dylib|so
```

On Windows the same layout is published as a `.zip`, with `.exe` and
`.dll` filenames instead.

DotSlash resolves the package entrypoint to
`argument-comment-lint/bin/argument-comment-lint`. That runner finds the
sibling bundled `cargo-dylint` binary plus the single packaged Dylint
library under `lib/`, then invokes `cargo-dylint dylint --lib-path
<that-library>` with the repo's default lint settings.
2026-03-19 18:59:02 +00:00
..
.cargo Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00
src Publish runnable DotSlash package for argument-comment lint (#15198) 2026-03-19 18:59:02 +00:00
ui Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00
.gitignore Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00
Cargo.lock Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00
Cargo.toml Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00
README.md Publish runnable DotSlash package for argument-comment lint (#15198) 2026-03-19 18:59:02 +00:00
run.sh Apply argument comment lint across codex-rs (#14652) 2026-03-16 16:48:15 -07:00
rust-toolchain Add argument-comment Dylint runner (#14651) 2026-03-14 08:18:04 -07:00

argument-comment-lint

Isolated Dylint library for enforcing Rust argument comments in the exact /*param*/ shape.

Prefer self-documenting APIs over comment-heavy call sites when possible. If a call site would otherwise read like foo(false) or bar(None), consider an enum, named helper, newtype, or another idiomatic Rust API shape first, and use an argument comment only when a smaller compatibility-preserving change is more appropriate.

It provides two lints:

  • argument_comment_mismatch (warn by default): validates that a present /*param*/ comment matches the resolved callee parameter name.
  • uncommented_anonymous_literal_argument (allow by default): flags anonymous literal-like arguments such as None, true, false, and numeric literals when they do not have a preceding /*param*/ comment.

String and char literals are exempt because they are often already self-descriptive at the callsite.

Behavior

Given:

fn create_openai_url(base_url: Option<String>, retry_count: usize) -> String {
    let _ = (base_url, retry_count);
    String::new()
}

This is accepted:

create_openai_url(/*base_url*/ None, /*retry_count*/ 3);

This is warned on by argument_comment_mismatch:

create_openai_url(/*api_base*/ None, 3);

This is only warned on when uncommented_anonymous_literal_argument is enabled:

create_openai_url(None, 3);

Development

Install the required tooling once:

cargo install cargo-dylint dylint-link
rustup toolchain install nightly-2025-09-18 \
  --component llvm-tools-preview \
  --component rustc-dev \
  --component rust-src

Run the lint crate tests:

cd tools/argument-comment-lint
cargo test

GitHub releases also publish a DotSlash file named argument-comment-lint for macOS arm64, Linux arm64, Linux x64, and Windows x64. The published package contains a small runner executable, a bundled cargo-dylint, and the prebuilt lint library.

Run the lint against codex-rs from the repo root:

./tools/argument-comment-lint/run.sh -p codex-core
just argument-comment-lint -p codex-core

If no package selection is provided, run.sh defaults to checking the codex-rs workspace with --workspace --no-deps.

Repo runs also promote uncommented_anonymous_literal_argument to an error by default:

./tools/argument-comment-lint/run.sh -p codex-core

The wrapper does that by setting DYLINT_RUSTFLAGS, and it leaves an explicit existing setting alone. It also defaults CARGO_INCREMENTAL=0 unless you have already set it, because the current nightly Dylint flow can otherwise hit a rustc incremental compilation ICE locally. To override that behavior for an ad hoc run:

DYLINT_RUSTFLAGS="-A uncommented-anonymous-literal-argument" \
CARGO_INCREMENTAL=1 \
  ./tools/argument-comment-lint/run.sh -p codex-core

To expand target coverage for an ad hoc run:

./tools/argument-comment-lint/run.sh -p codex-core -- --all-targets