lint!: upgrade perfectionist#412
Conversation
Bump `perfectionist` past `0.0.0-rc.7` to its current `master` HEAD, which introduces the `non_exhaustive_error` rule and a suite of `single_letter_*` rules. Wire `non_exhaustive_error` in as a deny-level lint at the crate root and address the violations it surfaces: - Add `#[non_exhaustive]` to `args::fraction::ConversionError` and `args::fraction::FromStrError`. - Drop the unused `derive_more::Error` derive from `bytes_format::parsed_value::ParsedValue`. The enum is a formatter return value rather than an error type, so it no longer participates in the rule. The new `single_letter_*` rules also surface unrelated violations, addressed as follows: - Rename trait-method parameters `a` / `b` to `path` / `prefix` in `app::overlapping_arguments::Api::starts_with`, and rename the closure parameter `r` to `range` in `usage_md`. - Configure the rule's `comparison_methods` allowlist in `dylint.toml` to include the project-specific helper `sort_reflection_by` and the `into-sorted` crate's `into_sorted_by`, both of which take comparison closures whose `|a, b|` parameters CLAUDE.md explicitly permits. - Allow `single_letter_let_binding` at the `args` module level because `clap_derive`'s `default_value_t` expansion produces a `let s = ...` binding that is outside our control. Register the `perfectionist` tool and gate the deny directive on `cfg(dylint_lib = "perfectionist")` so non-dylint builds do not see an unknown lint tool. Declare the matching `check-cfg` entry in `Cargo.toml` to keep `unexpected_cfgs` quiet on ordinary builds. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
Performance Regression Reportscommit: c54849b There are no regressions. |
Bump `perfectionist` from `3acd734` to `a21a146`. The upstream delta adds three rules: `arc_rc_clone`, `derive_ordering`, and `prefer_raw_string`. `derive_ordering` is silent; the other two surface reasonable violations: - `arc_rc_clone`: switch `progress.clone()` to `Arc::clone(&progress)` in `reporter::progress_and_error_reporter` to make the cheap refcount bump explicit. - `prefer_raw_string`: rewrite the three string literals that embed escaped quotes as raw strings, in `reporter::error_report::text_report` and `tests::cli_errors`. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
The new rule `macro_argument_binding` flags 25 sites across the codebase. Investigation showed every single one to be a false positive belonging to one of five upstream bug classes, filed as #415, #416, #417, #418, and #419. None of the suggested "bind to a `let` first" fixes are correct here: - The 13 `debug_assert_op!` / `debug_assert_op_expr!` sites would have their arguments forced to run in release builds (#415), defeating the entire point of `debug_assert_*`. - The `make_const!` and `bump!` matchers (#416) use definition / compound-assignment shapes that have no `let`-binding form. - `app::App::run` passes the unit literal `()`, which the rule's grammar fails to recognise as trivial (#417). - `debug_assert_op_expr!`'s middle operator argument (`==`, `>`) is a bare token, not an expression at all (#418). - The late pass anchors item-position macro violations at the crate root (#419), which is why module-scope `#[expect]` cannot suppress them and `proportion_bar.rs`'s `make_const!` macro had to be expanded into five `pub const` lines by hand. Apply `#[cfg_attr(dylint_lib = "perfectionist", expect(...))]` at the smallest scope each false positive permits (function scope where the macro call is statement-position, crate root in `tests/bytes_format.rs` where the call is item-position). Rewrite the `link!` / `symlink!` macros in `tests/_utils.rs` as closures so the test-utility module needs no suppression. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
Configure the rule for `prefix_then_alphabetical` with an explicit `prefix` that encodes the project's preferred derive families in order: standard, comparison, `Hash`, formatting / error, conversions, reference wrappers, iteration, arithmetic operator pairs and folds, and integer-format derives. Anything not in the prefix (`Setters`, `SmartDefault`, `Parser`, …) falls in ASCII- case-insensitive alphabetical order after, matching the existing convention. Reorder 18 derive lists across the codebase to satisfy the rule. Every case had derive-more-style traits mixed into the standard- trait block, contradicting the convention CONTRIBUTING.md already documents; the rule's suggestions match that documented intent. Document the rule in `CONTRIBUTING.md`'s derive-ordering section, and drop the now-redundant within-line ordering bullet from the shared AI-instructions template (the rule enforces it). The line-splitting convention (separate `#[cfg_attr(...)]` line for feature-gated derives) is not enforced by the rule and stays in the contributing guide as a manual style preference. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
PR 52 (`93cb529`) fixes four of the five `macro_argument_binding` bug classes filed earlier: - #415 — `debug_assert_*` trivial-comparison no longer flagged when the comparison is over side-effect-free operands. Removed function-scope `#[expect]` suppressions in `data_tree::hardlink`, `visualizer::methods::bar_table`, and `visualizer::methods::initial_table`. - #416 — `name = value` / `name += value` DSL matchers no longer flagged. Removed the function-scope suppression on `reporter::progress_and_error_reporter::report`. The narrower `->` / `in` separators used by `tests::bytes_format::test_case!` are not yet covered, so its crate-root suppression remains, with the reason updated to point at the partial fix. - #417 — unit literal `()` is now trivial. Removed the function-scope suppression on `app::App::run`. - #418 — bare operator tokens (`==`, `>`) used as positional separators in `debug_assert_op_expr!` are no longer flagged. The lone residual flag in `visualizer::methods::tree_table` (`debug_assert_op_expr!(intermediate_table.len(), ==, ...)`) is correct rule behaviour: the rule cannot prove `Vec::len` is pure. Replaced the broad suppression with a narrower one citing `Vec::len`'s `O(1)`-pure-read contract. PR 43, folded into PR 52's branch, splits `single_letter_names` into separate per-rule config keys. Migrate the `comparison_methods` allowlist from `[perfectionist::single_letter_names]` to the new `[perfectionist::single_letter_closure_param]` section so the project-specific `sort_reflection_by` / `into_sorted_by` helpers remain exempt from the closure-parameter check. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
8925331 redesigns `macro_argument_binding` from "flag every macro with a non-trivial top-level argument" to a curated `AllowAndDeny` mode: only invocations on the built-in deny list (`debug_assert`, `debug_assert_eq`, `debug_assert_ne`) plus user `deny_extra` trigger the rule, and the built-in allow list silences common once-only macros (`format`, `vec`, `assert`, …). The trivial- expression grammar also gains a pure-getter postfix walker so `vec.len()`, `s.is_empty()`, `opt.as_ref()`, and the rest of the built-in zero-arg list stay trivial. Adopt the new config knobs: - `deny_extra = ["debug_assert_op", "debug_assert_op_expr"]` enrolls the `assert-cmp` family alongside the std `debug_assert*` macros so non-trivial arguments still get caught despite their conditional `cfg(debug_assertions)` expansion. - `allow_extra = ["bump", "visualize", "test_case"]` catalogues the three remaining project-defined macros that expand each top-level argument exactly once. The combination eliminates two suppressions that were necessary under PR 52's head (`93cb529`): - `src/visualizer/methods/tree_table.rs` — `intermediate_table .len()` is now trivial via the built-in pure-getter list. - `tests/bytes_format.rs` — `test_case!` is in `allow_extra`, so the rule no longer fires on its `name -> value in system == expected` DSL invocations. The crate-root suppression and the `register_tool(perfectionist)` it required are gone. The late-pass anchoring bug #419 is mechanistically unchanged: `src/rules/macro_argument_binding/late.rs` is byte-identical between `93cb529` and `8925331`. The new `allow_extra` / `deny_extra` mechanism sidesteps #419 in practice for user-defined macros (config-level allow needs no `#[expect]`), but the underlying anchoring bug for item-position macro expansions still exists. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
Apply the project owner's review comments: - Reorder the `derive_ordering` prefix so `Display` sits right after `Debug`, `SmartDefault` sits next to `Default`, and reference wrappers (`AsRef`, `AsMut`, `Deref`, `DerefMut`) come before conversions (`From`, `Into`, …). Drop the in-array group labels — the new layout no longer maps onto a clean "standard / comparison / Hash / derive_more" story and the labels were misleading. Drop the verbose prefatory comments under each `dylint.toml` table heading. Collapse `allow_extra` and `comparison_methods` to single lines. - Replace `#[non_exhaustive]` with `#[cfg_attr(dylint_lib = "perfectionist", expect(perfectionist::non_exhaustive_error, reason = "…"))]` on `args::fraction::ConversionError` and `args::fraction::FromStrError`. Both error types are explicitly exhaustive: their constructor and parser each have a closed set of failure modes that any future addition would break as an API change anyway. - Revert the closure rewrites in `tests/_utils.rs` and restore the `link!` / `symlink!` macros. The upstream `macro_argument_binding` redesign in perfectionist 8925331 silences these once they are listed in `allow_extra`, so the closures are no longer needed. - Reapply 20 derive-list reorders that the new prefix makes the rule prefer, including the `Debug, Display, Error, …` shape called out in the review for the `hardlink::hardlink_list::reflection::ConversionError` derive, and the `Debug, Display, Default, Clone, Copy, …, AsRef, Deref, Into` shape called out for the `Fraction` derive. - Refresh the CONTRIBUTING.md derive-ordering paragraph and example to match the new prefix layout. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
|
Addressed in f792aa0. Per-comment status:
Twenty derive lists across the codebase were reordered to match the new prefix. CI is green locally with Generated by Claude Code |
perfectionist and enable non_exhaustive_errorperfectionist
Two more review comments: - Restore the `make_const!` macro in `visualizer::proportion_bar`. The matcher syntax (`$name:ident = $content:literal`) is now silenced by perfectionist `93cb529`'s extension of `looks_like_expression` to top-level `=` markers; adding `make_const` to `allow_extra` covers the residual unknown-macro flag from `AllowAndDeny` mode. - Drop the experiment with `perfectionist::non_exhaustive_error`. Remove the deny directive at the crate root, and remove the `#[cfg_attr(... expect(perfectionist::non_exhaustive_error, ...))]` suppressions added on `args::fraction::ConversionError` and `args::fraction::FromStrError` in the previous commit (those types are explicitly exhaustive, so the rule was telling them to add `#[non_exhaustive]` they did not want; the right resolution is to drop the rule, not work around it). https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
There was a problem hiding this comment.
Pull request overview
This pull request updates the repository’s Dylint setup to track the current perfectionist master (via a pinned revision) and applies collateral code/doc changes so the codebase complies with the newer lint set (derive ordering, single-letter name rules, and related cleanup).
Changes:
- Upgrade
perfectionistindylint.tomland add explicit lint configuration (derive_ordering,macro_argument_binding,single_letter_closure_param). - Adjust Rust code to satisfy the new/stricter linting rules (derive ordering, identifier renames,
Arc::clone, and removing an inappropriatederive_more::Errorderive). - Add build “plumbing” for Dylint-only cfg/tool registration and declare the
dylint_libcfg inCargo.tomlto avoidunexpected_cfgsnoise.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/cli_errors.rs | Updates expected stderr strings to raw string literals (escaping cleanup). |
| tests/_utils.rs | Renames a single-letter closure param to satisfy single-letter naming lint. |
| template/ai-instructions/shared.md | Removes a derive-order bullet from shared AI instructions template. |
| src/visualizer/tree.rs | Reorders derives to match configured derive_ordering. |
| src/visualizer/proportion_bar.rs | Reorders derives to match configured derive_ordering. |
| src/usage_md.rs | Renames a closure param to avoid single-letter naming lint. |
| src/reporter/progress_report.rs | Reorders derives (incl. Setters) per lint configuration. |
| src/reporter/progress_and_error_reporter.rs | Uses Arc::clone(&...) instead of .clone() for clarity. |
| src/reporter/error_report/text_report.rs | Switches expected string to raw literal (escaping cleanup). |
| src/os_string_display.rs | Reorders derive list to match configured derive_ordering. |
| src/lib.rs | Adds Dylint-only register_tool(perfectionist)/feature gating. |
| src/json_data/binary_version.rs | Reorders derives to match configured derive_ordering. |
| src/inode.rs | Reorders derives to match configured derive_ordering. |
| src/hardlink/hardlink_list/summary.rs | Reorders derives (incl. Setters) per lint configuration. |
| src/hardlink/hardlink_list.rs | Reorders derives to match configured derive_ordering. |
| src/device.rs | Reorders derives to match configured derive_ordering. |
| src/bytes_format/parsed_value.rs | Drops derive_more::Error from a non-error return value type. |
| src/args/threads.rs | Reorders derives to match configured derive_ordering. |
| src/args/fraction.rs | Reorders derives to match configured derive_ordering. |
| src/args/depth.rs | Reorders derives to match configured derive_ordering. |
| src/args.rs | Adds Dylint-only module-level allow for a proc-macro false positive; reorders derives. |
| src/app/overlapping_arguments/test_remove_overlapping_paths.rs | Renames trait method params to descriptive identifiers. |
| src/app/overlapping_arguments.rs | Renames trait method params to descriptive identifiers. |
| dylint.toml | Pins perfectionist by rev and adds lint configuration blocks. |
| CONTRIBUTING.md | Updates derive-ordering documentation to reflect lint enforcement/config. |
| CLAUDE.md | Removes derive-order bullet from instructions. |
| AGENTS.md | Removes derive-order bullet from instructions. |
| .github/copilot-instructions.md | Removes derive-order bullet from instructions. |
| Cargo.toml | Declares dylint_lib cfg in unexpected_cfgs check-cfg list. |
Comments suppressed due to low confidence (2)
src/args/fraction.rs:21
- The PR description mentions adding
#[non_exhaustive]toConversionErrorto satisfyperfectionist::non_exhaustive_error, but this enum is still exhaustive. If you do enable that lint, annotate this enum (and update any exhaustive matches); otherwise update the PR description to match the actual behavior.
This issue also appears on line 44 of the same file.
/// Error that occurs when calling [`Fraction::new`].
#[derive(Debug, Display, Error, Clone, Copy, PartialEq, Eq)]
pub enum ConversionError {
/// Provided value is greater than or equal to 1.
#[display("greater than or equal to 1")]
UpperBound,
/// Provided value is less than 0.
#[display("less than 0")]
LowerBound,
}
src/args/fraction.rs:49
- The PR description mentions adding
#[non_exhaustive]toFromStrErrorto satisfyperfectionist::non_exhaustive_error, but this enum is still exhaustive. If you do enable that lint, annotate this enum (and update any exhaustive matches); otherwise update the PR description to match the actual behavior.
/// Error that occurs when parsing a string as [`Fraction`].
#[derive(Debug, Display, Error, Clone, PartialEq, Eq)]
pub enum FromStrError {
ParseFloatError(ParseFloatError),
Conversion(ConversionError),
}
Picks up everything since `8925331`: - KSXGitHub/perfectionist#52 merged with no behavioural delta from the PR-head SHA we tested earlier. - KSXGitHub/perfectionist#54 adds `into_sorted_by` / `into_sorted_unstable_by` (and the `_key` siblings) to the built-in `single_letter_closure_param` allowlist, so they no longer need to be configured per project. - KSXGitHub/perfectionist#55 switches several rules from "configure replaces the default" to "configure extends the default" (with a paired `ignore_*` knob to subtract). Closes the issue we filed as #413. - KSXGitHub/perfectionist#56 enables `deny_unknown_fields` on the config tables; typos and stale field names now fail to load rather than silently no-oping. - KSXGitHub/perfectionist#58 renames a handful of config fields: `comparison_methods` → `extra_trivial_callback_methods`, `let_binding_allowed_idents` → `allowed_idents`, and so on. - KSXGitHub/perfectionist#62 adds a `Span::in_external_macro` check on `single_letter_let_binding`'s `LetStmt` span, intending to silence proc-macro-synthesised bindings such as `clap_derive`'s `default_value_t`. It does not actually catch the `clap_derive` case in this codebase: the rule still fires on the three `default_value_t` attributes in `args::Args`, so the module-level `allow` workaround stays in place. See #410 follow-up. - KSXGitHub/perfectionist#63 teaches `single_letter_closure_param` to recognise macro-call bodies as trivial wrappers, so `.pipe(|x| vec![x])` is once again accepted. Reverts the `|x|` → `|command|` rename in `tests::_utils`. Migrate the local config: - `[perfectionist::single_letter_closure_param]` switches from `comparison_methods = [<every default plus our extras>]` to `extra_trivial_callback_methods = ["sort_reflection_by"]`. The 17 default entries no longer need to be listed, and `into_sorted_by` is now part of the upstream defaults so it can also be dropped. - `[perfectionist::macro_argument_binding]`'s `deny_extra` and `allow_extra` knobs are unchanged — those names did not move. - The crate-root `register_tool(perfectionist)` is preserved alongside the still-required `args.rs` workaround. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
KSXGitHub/perfectionist#66 extends the proc-macro-synthesised skip from `single_letter_let_binding` to the rest of the single-letter family and `arc_rc_clone`. The expanded check walks the relevant span's expansion chain rather than only calling `Span::in_external_macro`, which catches `clap_derive`'s `default_value_t` synthesis where the previous statement-span- only check did not. With that, the `clap_derive` `let s` false positive originally filed as #410 — and re-surfaced after the apparent #62 fix — is fully resolved. Drop the module-level `allow(perfectionist::single_letter_let_binding)` from `src/args.rs`. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
Five new commits since `3ca7f01`: - KSXGitHub/perfectionist#65 finishes `macro_argument_binding`'s non-expression-marker list. `looks_like_expression` now skips top-level `->` and `in` tokens alongside the `=` / `+=` / `:` / bare-operator markers added earlier. Resolves the residual case of the issue we filed as #416, where `tests::bytes_format::test_case!`'s `name -> value in system == expected` DSL was still flagged even after the `=` / `+=` fixes. - KSXGitHub/perfectionist#67 introduces a crate-wide `[perfectionist]` config table with `enable` / `disable` arrays, and shifts `non_exhaustive_error`'s default state to `Disabled` (opt-in via `[perfectionist] enable = ["non_exhaustive_error"]`). This codebase already retired the rule in d845841, so the new upstream default matches our intent — no configuration needed. - KSXGitHub/perfectionist#68, KSXGitHub/perfectionist#69, KSXGitHub/perfectionist#70 are documentation-only. Drop the entire `[perfectionist::macro_argument_binding] allow_extra` list. Every entry it carried — `bump`, `link`, `make_const`, `symlink`, `test_case`, `visualize` — is now silenced by the rule's own per-argument trivial-expression and DSL-separator checks. Concretely: - `bump!(items += 1)` — `+=` skipped (PR #52). - `make_const!(LEVEL0_BLOCK = '█')` — `=` skipped (PR #52). - `visualize!(tree, ())` — `tree` is a trivial path, `()` is the unit literal classified as trivial in PR #52. - `link!("a" -> "b")` / `symlink!("a" -> "b")` — `->` skipped (PR #65). - `test_case!(plain_number -> 65_535 in PlainNumber == "65535")` — `->` and `in` skipped (PR #65). `deny_extra` stays as-is — the `assert_cmp::debug_assert_op*` family still needs explicit denial so non-trivial arguments inside them get caught. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
`Generic Parameter Naming` and `Variable and Closure Parameter Naming` describe rules that `perfectionist` enforces in full. Add the same "enforced by `perfectionist::<rule>`" footnote that `Module Organization` and `Derive Macro Ordering` already carry. The textual guidance and worked examples stay; readers and AI agents now have the breadcrumb to the configured rule and its relevant `dylint.toml` knobs (`short_impl_max_lines`, `allowed_idents`, `extra_trivial_callback_methods`). https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
23 commits since `0.0.0-rc.12`. The functional ones that matter for this codebase: - KSXGitHub/perfectionist#72 adds the curated `core` / `std` compile-time macros (`stringify!`, `concat!`, `cfg!`, `option_env!`, the `assert*` family, etc.) to `macro_argument_binding`'s built-in allow list. - KSXGitHub/perfectionist#82 reframes the rule's classifier from "non-trivial expressions" to "impure expressions" and renames the four `extra_trivial_*` / `ignore_trivial_*` knobs (methods and macros) to `extra_pure_*` / `ignore_pure_*`. The diagnostic text was updated to match. No effect here — we set none of those knobs. - KSXGitHub/perfectionist#84 drops the per-rule `enabled` config knob from `macro_argument_binding`, `macro_trailing_comma`, and `prefer_raw_string`. Users relying on `[perfectionist::<rule>] enabled = false` migrate to `[perfectionist] disable = ["<rule>"]`. We never set that knob; nothing to change. - KSXGitHub/perfectionist#95 drops the redundant `style = "preserve"` variant from `derive_ordering`. We use `style = "prefix_then_alphabetical"`; unaffected. The rest of the delta is pages styling (#86, #87, #94, #97, #98, #99), docs (#73, #75, #76, #77, #80, #81, #83, #96), CI / dependency bumps (#79, #88-93), and the rc.13 release. Clean build against `0.0.0-rc.14`, full test suite green, no config migration needed and no source changes triggered. No new bugs surface in this codebase. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
Upgrades
perfectionistfrom0.0.0-rc.7to commit3ca7f01(currentmaster). The branch went through several rounds of upstream churn, including a major redesign ofmacro_argument_bindinginKSXGitHub/perfectionist#52, a split ofsingle_letter_namesinto per-rule config keys, and the addition ofderive_ordering,arc_rc_clone,prefer_raw_string, andnon_exhaustive_error. Final state below; commit history records the intermediate stops.derive_ordering(enabled)Configured for
prefix_then_alphabeticalwith an explicit prefix that encodes the project convention:Debug, formatting/error derives, defaults (Default,SmartDefault),Clone/Copy, comparison andHash, reference wrappers, conversions, iteration, arithmetic operator pairs and folds, integer-format derives. Anything not in the prefix (Setters,Parser, …) falls alphabetically after. 20 derive lists reordered to satisfy it.macro_argument_binding(enabled, configured)The
AllowAndDenydefault plus two config knobs:deny_extra = ["debug_assert_op", "debug_assert_op_expr"]enrolls theassert-cmpfamily alongsidedebug_assert*.allow_extra = ["bump", "link", "make_const", "symlink", "test_case", "visualize"]catalogues the project's user-defined macros, all of which expand each top-level argument exactly once.single_letter_*family (enabled)Api::starts_with'sa/bparams topath/prefix; closure paramr→rangeinusage_md.extra_trivial_callback_methods = ["sort_reflection_by"]for the project-private comparator helper.arc_rc_clone,prefer_raw_string(enabled)progress.clone()→Arc::clone(&progress)inreporter::progress_and_error_reporter.reporter::error_report::text_reportandtests::cli_errors.non_exhaustive_error(not enabled)Briefly enabled mid-PR. The experiment caught a real bug —
bytes_format::parsed_value::ParsedValuewas derivingderive_more::Errordespite not being an error type — which is fixed by dropping that derive. The rule also asked for#[non_exhaustive]onargs::fraction::ConversionErrorandargs::fraction::FromStrError, but both are explicitly exhaustive (their constructor and parser each have a closed set of failure modes), so adding#[non_exhaustive]would have been a misstatement. Retired the rule and reverted the two annotations. TheParsedValuecleanup remains.Plumbing
#![cfg_attr(dylint_lib = "perfectionist", feature(register_tool), register_tool(perfectionist))]at the crate root so non-dylint builds stay clean.[lints.rust] unexpected_cfgs.check-cfginCargo.tomldeclares thedylint_libcfg.Filed upstream issues
Tracked here because my GitHub scope did not include the
perfectionistrepo:perfectionist::single_letter_let_bindingfires insideclap_derive'sdefault_value_texpansion #410perfectionist::single_letter_closure_param's "trivial wrapper" classifier ignores macro-call bodies #411perfectionist::single_letter_closure_paramdefaultcomparison_methodsomits common third-party comparators likeinto_sorted_by#413perfectionist::macro_argument_binding's suggested fix breaks the debug-only contract of thedebug_assert_*family #415perfectionist::macro_argument_bindingflagsname = value/name += valueDSL matchers as non-trivial expressions #416perfectionist::macro_argument_bindingtreats the unit literal()as a non-trivial expression #417perfectionist::macro_argument_bindingtreats bare operator tokens (==,>, …) as non-trivial expressions #418perfectionist::macro_argument_bindinglate-pass anchors item-position macro violations at the crate root, breaking scoped#[expect]#419, closed as not reproducible on the current toolchainTest plan
TEST_SKIP='fs_errors cross_device_excludes_mount' FMT=true LINT=true BUILD=true TEST=true DOC=true DYLINT=true ./test.sh(the two skipped tests require root and FUSE/squashfs-tools respectively, per the harness's own skip hints).https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ