{"id":"75803b5da6a10bbe","repo":"rust-lang/cargo","slug":"at-least-one-iteration","errorCode":null,"errorMessage":"at least one iteration","messagePattern":"at least one iteration","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/ops/cargo_fix/mod.rs","lineNumber":973,"sourceCode":"        debug!(\"calling rustc one last time for final results: {rustc}\");\n        last_output = rustc.output()?;\n    }\n\n    // Any errors still remaining at this point need to be reported as probably\n    // bugs in Cargo and/or rustfix.\n    for (path, file) in files.iter_mut() {\n        for error in file.errors_applying_fixes.drain(..) {\n            Message::ReplaceFailed {\n                file: path.clone(),\n                message: error,\n            }\n            .post(gctx)?;\n        }\n    }\n\n    Ok(FixedCrate {\n        files,\n        first_output: first_output.expect(\"at least one iteration\"),\n        last_output,\n    })\n}\n\n/// Executes `rustc` to apply one round of suggestions to the crate in question.\n///\n/// This will fill in the `fixes` map with original code, suggestions applied,\n/// and any errors encountered while fixing files.\nfn rustfix_and_fix(\n    files: &mut HashMap<String, FixedFile>,\n    rustc: &ProcessBuilder,\n    filename: &Path,\n    args: &FixArgs,\n    gctx: &GlobalContext,\n) -> CargoResult<(Output, bool)> {\n    // If not empty, filter by these lints.\n    // TODO: implement a way to specify this.\n    let only = HashSet::default();","sourceCodeStart":955,"sourceCodeEnd":991,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/cargo_fix/mod.rs#L955-L991","documentation":"Invariant panic in `fix_warnings`: after the iterate-until-converged loop, the code does `first_output.expect(\"at least one iteration\")`. The loop is a bare `loop { ... }` that always executes its body once and sets `first_output = Some(...)` when `current_iteration == 0` (line 930-932). So the Option is always Some unless the loop body is refactored to skip the assignment.","triggerScenarios":"Triggered only if `cargo fix`'s apply-loop exits with `first_output` still `None`. The loop unconditionally runs the body at least once, so under the shipped code this is unreachable; a future refactor that short-circuits before iteration 0 could expose it.","commonSituations":"Effectively not user-reachable in released cargo. Encountered only by cargo contributors editing `fix_warnings`/`rustfix_and_fix` and accidentally bypassing the `current_iteration == 0` assignment.","solutions":["If you hit this in released cargo, file a cargo bug — it indicates a regression in the fix loop.","If you are editing cargo source, ensure the loop body runs at least once before any `break`/`return`, or initialize `first_output` before the loop.","Reproduce with `RUST_BACKTRACE=1 cargo fix ...` and capture the trace for the bug report."],"exampleFix":"// before\nlet mut first_output = None;\nloop {\n    // ...\n    if current_iteration == 0 { first_output = Some(last_output.clone()); }\n    // ...\n}\nfirst_output.expect(\"at least one iteration\")\n\n// after (defensive: run rustc once before the loop)\nlet mut first_output = Some(rustc.output()?.clone());\nloop { /* ... */ }","handlingStrategy":"validation","validationCode":"// N/A for callers — this is an internal loop invariant. No public API pre-check helps.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use released cargo toolchains for `cargo fix` rather than custom builds.","If patching cargo, initialize `first_output` before the loop or assert the loop runs once."],"tags":["cargo","panic","invariant","fix","rustfix","rust"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}