diff --git a/tests/testsuite/fix_n_times.rs b/tests/testsuite/fix_n_times.rs index 6ba05a04bd9..dfbb611c235 100644 --- a/tests/testsuite/fix_n_times.rs +++ b/tests/testsuite/fix_n_times.rs @@ -45,6 +45,8 @@ enum Step { Error = b'e', /// Emits one suggested fix and an error. OneFixError = b'f', + /// Emits one diagnostic with two exclusive, overlapping suggestions. + TwoFixExclusive = b'x', } /// Verifies `cargo fix` behavior based on the given sequence of behaviors for @@ -139,6 +141,9 @@ fn main() { output_message("error", successful_count + 2); std::process::exit(1); } + b'x' => { + output_exclusive_suggestions(successful_count + 1); + } _ => panic!("unexpected sequence"), } } @@ -256,6 +261,112 @@ fn output_message(level: &str, count: usize) { .replace("\n", ""); eprintln!("{json}"); } + +fn output_exclusive_suggestions(count: usize) { + let json = format!( + r#"{{ + "$message_type": "diagnostic", + "message": "rustc fix shim exclusive comment {count}", + "code": null, + "level": "warning", + "spans": + [ + {{ + "file_name": "src/lib.rs", + "byte_start": 13, + "byte_end": 14, + "line_start": 1, + "line_end": 1, + "column_start": 14, + "column_end": 15, + "is_primary": true, + "text": + [ + {{ + "text": "// fix-count 0", + "highlight_start": 14, + "highlight_end": 15 + }} + ], + "label": "increase this number", + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + }} + ], + "children": + [ + {{ + "message": "try this", + "code": null, + "level": "help", + "spans": + [ + {{ + "file_name": "src/lib.rs", + "byte_start": 13, + "byte_end": 14, + "line_start": 1, + "line_end": 1, + "column_start": 14, + "column_end": 15, + "is_primary": true, + "text": + [ + {{ + "text": "// fix-count 0", + "highlight_start": 14, + "highlight_end": 15 + }} + ], + "label": null, + "suggested_replacement": "{count}a", + "suggestion_applicability": "MachineApplicable", + "expansion": null + }} + ], + "children": [], + "rendered": null + }}, + {{ + "message": "or try this", + "code": null, + "level": "help", + "spans": + [ + {{ + "file_name": "src/lib.rs", + "byte_start": 13, + "byte_end": 14, + "line_start": 1, + "line_end": 1, + "column_start": 14, + "column_end": 15, + "is_primary": true, + "text": + [ + {{ + "text": "// fix-count 0", + "highlight_start": 14, + "highlight_end": 15 + }} + ], + "label": null, + "suggested_replacement": "{count}b", + "suggestion_applicability": "MachineApplicable", + "expansion": null + }} + ], + "children": [], + "rendered": null + }} + ], + "rendered": "rustc fix shim exclusive comment {count}" + }}"#, + ) + .replace("\n", ""); + eprintln!("{json}"); +} "##, ) .build(); @@ -472,3 +583,31 @@ rustc fix shim error count=2 "// fix-count 1", ); } + +#[cargo_test] +fn fix_exclusive_suggestions() { + // One diagnostic with two exclusive suggestions for the same span. + // Currently, rustfix fails with a generic `AlreadyReplaced` error + // ("cannot replace slice of data that was already replaced") when it + // encounters this. + expect_fix_runs_rustc_n_times( + &[Step::TwoFixExclusive], + |execs| { + execs.with_status(0); + }, + str![[r#" +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[ERROR] error applying suggestions + --> src/lib.rs + = cause: cannot replace slice of data that was already replaced +[HELP] to report this as a bug, open an issue at https://github.com/rust-lang/rust/issues, quoting the full output of this command +[HELP] to possibly apply more fixes, pass in the `--broken-code` flag +[FIXED] src/lib.rs (0 fixes) +[..] +[WARNING] `foo` (lib) generated 1 warning (run `cargo fix --lib -p foo` to apply 1 suggestion) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]], + "// fix-count 0", + ); +}