diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index 703e118e9d3c..b373a6201416 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -738,7 +738,17 @@ fn rustfix_and_fix( // As mentioned above in `rustfix_crate`, we don't immediately warn // about suggestions that fail to apply here, and instead we save them // off for later processing. + let mut already_applied = HashSet::new(); for suggestion in suggestions.iter().rev() { + // Skip seemly duplicate suggestions. + if suggestion + .solutions + .iter() + .any(|sol| !already_applied.insert(sol)) + { + // already applied + break; + } match fixed.apply(suggestion) { Ok(()) => fixed_file.fixes_applied += 1, Err(e) => fixed_file.errors_applying_fixes.push(e.to_string()), diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index d8fb9861677a..4a2468dcca39 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -1924,18 +1924,18 @@ fn fix_only_once_for_duplicates() { .build(); p.cargo("fix --allow-no-vcs") - .with_stderr_contains( + .with_stderr( "\ [CHECKING] foo v0.0.1 ([CWD]) -[FIXED] src/lib.rs (2 fixes) +[FIXED] src/lib.rs (1 fix) +[FINISHED] `dev` profile [..] ", ) - .with_stderr_contains("[WARNING] unnecessary `unsafe` block[..]") .run(); assert_eq!( p.read_file("src/lib.rs").matches("unsafe").count(), - 5, - "2 in lint name, 1 from original unsafe fn, 2 from newly-applied unsafe blocks" + 4, + "2 in lint name, 1 from original unsafe fn, 1 from newly-applied unsafe blocks" ); }