Skip to content

Mutation gate has an architectural blind spot: mutants in cfg-gated code are vacuously MISSED on the runner's arch #421

Description

@RyanCodrai

.github/workflows/mutants.yml runs on ubuntu-latest (x86_64). cargo-mutants mutates source text, so a mutation inside a #[cfg(target_arch = "aarch64")] item still compiles there — the item is simply not built — no test can fail, and the mutant is reported MISSED. The gate then fails the PR for weak tests that are not weak.

Observed on PR #419, which touched the aarch64 None branch as part of #410:

MISSED   turbovec/src/encode.rs:935:5:  replace fused_quantize_scale_pack -> f32 with 1.0
MISSED   turbovec/src/encode.rs:1032:40: replace + with * in fused_quantize_scale_pack
15 mutants tested in 15m: 2 missed, 13 caught

fused_quantize_scale_pack is declared #[cfg(target_arch = "aarch64")] (turbovec/src/encode.rs:920).

Proof the mutants are killable, just not there. I applied the :1032 mutation (let d = offset + koffset * k) on an aarch64 host and ran the same target the gate runs:

cargo test --release -p turbovec --lib
test result: FAILED. 78 passed; 13 failed

Thirteen tests kill it. Reverted, 91 passed; 0 failed.

So the tests are fine and the gate's verdict is an artifact of where it runs. Any PR touching aarch64-only code — the NEON kernels, the aarch64 dispatch — will hit this.

Options, roughly in order of preference:

  1. Run the gate on a matrix including an aarch64 runner (macos-14 is already used elsewhere in ci.yml), so cfg-gated code is actually compiled somewhere.
  2. Have the gate detect mutants inside cfg-gated items that the runner's target excludes, and report them as unviable rather than missed. cargo-mutants has --in-place/--exclude machinery that could be pointed at this, though I have not checked whether it can express "cfg not active on this target".
  3. Failing either, document the blind spot in the gate's own failure text so the next person is not sent hunting for a missing test — the current message says "Each MISSED line above is an edit to your change that no test kills", which is misleading in this case.

The escape hatch ([skip mutants] / the skip-mutants label) works but is blunt: it drops the whole leg, including the 13 mutants that were legitimately caught in that same run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-human-decisionBlocked on a maintainer decision: scope, public claims, or dependency/release policy

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions