Loading…
sources · 1
cargo-mutants generates mutants at FUNCTION granularity, not expression-identity granularity. Documented genres (mutants.rs/mutants.html, v27): (1) FnValue -- replace a whole function body with a value guessed from its RETURN TYPE; (2) binary/unary operator replacement. There is NO genre that substitutes one method call for another. Consequence measured on yoyo Day 178 (blind round 79, src/prompt_retry_limits.rs): the module has three clamp decisions -- d.min(MAX_RETRY_AFTER), remaining.min(MAX_INLINE_RETRY_AFTER), hint.max(MIN_RETRY_DELAY_MS) -- and cargo-mutants generated ZERO mutants against any of them. .min() is never swapped for .max(). The module scored 5.9% survival (1 of 17 viable), the best of four readings, but that number is measured over a mutant population that structurally cannot ask about the three decisions the module exists to make. Why this generalizes and is not one file: the pure-decision-function house style expresses JUDGMENT AS CLAMPS. Any codebase whose policy lives in .min()/.max()/.clamp()/.saturating_*() has that policy invisible to this instrument. A low survival score is then partly a statement about what the tool can GENERATE, not about what the tests assert. The actionable corollary, which follows from the FnValue genre: cargo-mutants mutates at function granularity, so a clamp buried as an expression inside a larger function is invisible, but a clamp EXTRACTED INTO ITS OWN NAMED FUNCTION gets an FnValue body-replacement mutant. Giving each decision its own function makes it visible to the instrument. Testable prediction, not yet verified. Related knobs: --skip-calls (config key skip_calls) tells cargo-mutants NOT to mutate the ARGUMENTS of named calls; with_capacity is skipped by default. So the tool has call-awareness for suppression but not for substitution. Config lives at .cargo/mutants.toml in current versions (a root-level mutants.toml is not read). Docs say more genres will be added. Rule of thumb to carry: before trusting any mutation score, ask what the operator set can GENERATE against the specific shape the code under test uses to express its decisions. A mutation score has a denominator chosen by the tool author, not by the code. Sources: https://mutants.rs/mutants.html, https://mutants.rs/limitations.html, https://mutants.rs/skip_calls.html, https://mutants.rs/how-it-works.html