Filed here because the MCP scope used by the assistant session that produced #407 cannot write to `KSXGitHub/perfectionist`. Forward upstream when convenient. See #408 for the underlying rustfmt contradiction that forced us to suppress this lint at all. ## Summary When `perfectionist::macro_trailing_comma` is suppressed at crate scope with `#[expect]`, the rule does not register a fulfillment, so rustc's `unfulfilled_lint_expectations` lint fires. This makes the user-preferred `#[expect]` form unusable on its own, even though violations exist in the crate. ## Reproduction In a file with at least one `vec!` invocation that would trigger the rule (see #408 for the shapes that fire): ```rust #![cfg_attr(dylint_lib = "perfectionist", feature(register_tool))] #![cfg_attr(dylint_lib = "perfectionist", register_tool(perfectionist))] #![cfg_attr( dylint_lib = "perfectionist", expect( perfectionist::macro_trailing_comma, reason = "rustfmt collapses single-element multi-line vec!" ) )] ``` Running `RUSTFLAGS="-D warnings" cargo dylint --all -- --all-features --all-targets` reports: ``` error: this lint expectation is unfulfilled --> tests/tree_builder.rs:6:9 | 6 | perfectionist::macro_trailing_comma, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` The same crate without the `#[expect]` reports the underlying `macro_trailing_comma` violations, so the diagnostic is suppressible — but suppression appears to short-circuit the rule entirely instead of letting rustc track the fulfillment. ## Expected behaviour `macro_trailing_comma` should always emit its diagnostic with the appropriate span. rustc's `#[expect]` machinery is responsible for hiding the visible output *and* marking the expectation fulfilled. The rule should not early-exit when it sees a crate-level `#[allow]`/`#[expect]` of itself. ## Current workaround in this repo PR #407 pairs the `#[expect]` with `#[allow(unfulfilled_lint_expectations, reason = "perfectionist's macro_trailing_comma short-circuits when its lint is allowed/expected at crate scope")]`, which defeats the point of preferring `#[expect]` over `#[allow]`. ## Documentation gap, additionally The working suppression incantation is non-obvious and required several iterations during #407: ```rust #![cfg_attr(dylint_lib = "perfectionist", feature(register_tool))] #![cfg_attr(dylint_lib = "perfectionist", register_tool(perfectionist))] #![cfg_attr( dylint_lib = "perfectionist", expect(perfectionist::<rule>, reason = "…") )] #![allow(unexpected_cfgs, reason = "dylint_lib is not in --check-cfg")] ``` Without `register_tool`, stable consumers hit `error[E0710]: unknown tool name 'perfectionist'`. Without the `dylint_lib` cfg gate, every non-dylint `cargo check` fails. A README section describing this recipe would save downstream consumers a lot of debugging.