# iter clippy-sweep — clear all 61 `cargo clippy` warnings

**Date:** 2026-05-14
**Started from:** 04258c5 (post-WhatsNew of rustdoc-sweep + drift-test-narrowing)
**Status:** DONE

## Summary

Hygiene sweep against `cargo clippy --workspace --all-targets`. Before:
61 warnings across all eight crates. After: zero. Tests stay 563 green;
`cargo doc --workspace --no-deps` stays at zero warnings (the
rustdoc-sweep baseline); all three bench scripts (`bench/check.py`,
`bench/compile_check.py`, `bench/cross_lang.py`) all exit 0 against
the existing baselines — a free Stabilitätsbeweis that the sweep
touched no semantics.

Twelve warning classes, fixed with three different shapes:

- **Pure documentation fixes** (~32 warnings). `doc_lazy_continuation`
  on multi-line `///` and `//!` comments where clippy parsed the
  second line as a list continuation; resolved by either adding a
  blank line, escaping the marker, or rephrasing the offending line.
  Affected: `lex.rs:235-243` (3-line bullet list), `lib.rs:2360-2368`
  in `ailang-check` (3-line bullet list), `lib.rs:3736` in
  `ailang-check` (a `> 1` numeric comparison parsed as a quote
  marker; rephrased to "any cardinality above one"), `drop.rs:570-585`
  (numbered list + paragraph mix), `e2e.rs:915-920` (a `+ three
  primitive instances` line where `+` was parsed as bullet marker),
  `e2e.rs:1607-1614`, `typeclass_22b3.rs:706-708`, `eq_ord_e2e.rs:13`.
  Plus four `empty_line_after_doc_comments` hits in
  `workspace.rs:1675-2506` — these were `///` doc-comments left
  orphaned by form-a.1 Task 5 test relocation; converted to plain
  `//` comments (eight blocks total) since they no longer document
  any function.

- **Idiomatic refactors** (8 warnings). `err_expect` (5 hits in
  `parse.rs`): `.err().expect("…")` → `.expect_err("…")`.
  `useless_conversion` (3 hits): `.extend(x.into_iter())` → `.extend(x)`
  in `desugar.rs:275` + `lift.rs:201`; `vec!["x".into()]` →
  `vec!["x"]` in `lib.rs:5522` (where the call-site `fn_def`
  parameter is `Vec<&str>` so the conversion was identity).
  `redundant_closure` (2 hits): `|f| collect_pattern_binders(f)` →
  `collect_pattern_binders` in `linearity.rs:717`; same pattern in
  `loader.rs:108`. `trim_split_whitespace`: `.trim().split_whitespace()`
  → `.split_whitespace()` in `prose/src/lib.rs:2103` (since
  `split_whitespace` already ignores leading/trailing whitespace).
  `single_char_add_str`: `out.push_str("x")` → `out.push('x')` in
  `prose/src/lib.rs:383`. `collapsible_match` (2 hits): nested
  `if let Some(_) = …` collapsed to `if let Some(Some(_)) = …` in
  `mono.rs:1028` + `drop.rs:535-536`.

- **`derivable_impls`** (2 hits). `impl Default for ParamMode {
  fn default() -> Self { ParamMode::Implicit } }` in `ast.rs:731`
  → `#[derive(Default)]` + `#[default] Implicit`. Same shape for
  `AllocStrategy` in `codegen/src/lib.rs:164`. The derive form is
  strictly more explicit (the `#[default]` attribute marks which
  variant in-source rather than the impl body referencing it by
  name) so the change is also a small clarity gain.

- **`blocks_in_conditions`** (1 hit). The synth `Term::Var` arm in
  `check/src/lib.rs` had a 13-line block inside an `else if`
  condition (the mq.2 dispatch entry: `else if { let (m, q) =
  parse_method_qualifier(name); qualifier_is_class_shape(&q) &&
  env.method_to_candidate_classes.contains_key(m) }`). Extracted
  to a new helper `fn is_class_method_dispatch(name, env) -> bool`
  next to `qualifier_is_class_shape`. The helper inherits the
  block's full doc-comment so the why-each-branch reasoning is
  preserved at the call site.

- **`only_used_in_recursion`** (1 hit). `walk_pattern(p, f)` in
  `workspace.rs:1399` carries an `f: &mut F` parameter that
  Pattern walking never invokes (ct.1 left this seam unused: no
  Pattern variant carries a cross-module reference). Rather than
  delete `f` (which would break the symmetry with the five other
  `walk_*` framework functions in this file that all share the
  same `<F>(_, f: &mut F) -> Result<…>` signature), added
  `#[allow(clippy::only_used_in_recursion)]` with an inline
  comment naming the framework-uniformity rationale.

- **`if_same_then_else`** (2 hits). Both in `qualify_local_types`
  shapes (`check/src/lib.rs:3457` + `codegen/src/subst.rs:165`):
  the if-chain has two branches returning `name.clone()` for
  semantically distinct reasons (`name.contains('.')` = already
  qualified; `is_primitive_name(name)` = primitive needs no
  qualification). Combining the branches with `||` would obscure
  the reasoning. Added `#[allow(clippy::if_same_then_else)]` with
  an inline comment naming why each branch disqualifies the name.

- **`too_many_arguments`** (1 hit). `Emitter::new` takes 8 of the
  workspace-flat tables the emitter needs at construction time.
  Bundling them into a context struct would just rename the
  boilerplate without reducing it. Added
  `#[allow(clippy::too_many_arguments)]` with the rationale
  inline.

## Files touched

- `crates/ailang-core/src/ast.rs` (1 derive flip)
- `crates/ailang-core/src/desugar.rs` (1 .extend)
- `crates/ailang-core/src/workspace.rs` (1 walk_pattern allow + 8 `///`→`//` blocks)
- `crates/ailang-surface/src/lex.rs` (1 doc-list blank line)
- `crates/ailang-surface/src/parse.rs` (5 `.expect_err`)
- `crates/ailang-surface/tests/loader.rs` (1 redundant closure)
- `crates/ailang-prose/src/lib.rs` (push_str + trim removal)
- `crates/ailang-check/src/lib.rs` (helper extraction + 1 allow + 1 doc rephrase + 1 doc-list blank line + 1 vec literal)
- `crates/ailang-check/src/lift.rs` (1 .extend)
- `crates/ailang-check/src/linearity.rs` (1 redundant closure)
- `crates/ailang-codegen/src/lib.rs` (1 derive flip + 1 too_many_args allow)
- `crates/ailang-codegen/src/subst.rs` (1 if_same_then_else allow)
- `crates/ailang-codegen/src/drop.rs` (1 doc-list blank line + 1 collapsible_match)
- `crates/ailang-check/src/mono.rs` (1 collapsible_match)
- `crates/ail/tests/e2e.rs` (2 doc rephrasings)
- `crates/ail/tests/typeclass_22b3.rs` (1 doc rephrasing)
- `crates/ail/tests/eq_ord_e2e.rs` (1 doc rephrasing)

## Verification

- `cargo clippy --workspace --all-targets 2>&1 | grep -c '^warning:'`
  → `0` (was 61).
- `cargo test --workspace` → 563 passed + 3 ignored, 0 failed
  (baseline holds).
- `cargo doc --workspace --no-deps 2>&1 | grep -c '^warning:'` →
  `0` (rustdoc-sweep baseline holds — no regression).
- `bench/check.py` → exit 0.
- `bench/compile_check.py` → exit 0.
- `bench/cross_lang.py` → exit 0.

## Concerns

- (none)

## Known debt

- (none)
