diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c07cbfae256d..2e85410c8960 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2647,7 +2647,15 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { // To suggest a multipart suggestion when encountering `foo(1, "")` where the def // was `fn foo(())`. let (_, expected_ty) = self.formal_and_expected_inputs[expected_idx]; - suggestions.push((*arg_span, self.ty_to_snippet(expected_ty, expected_idx))); + // Check if the new suggestion would overlap with any existing suggestion. + // This can happen when we have both removal suggestions (which may include + // adjacent commas) and type replacement suggestions for the same span. + let dominated = suggestions + .iter() + .any(|(span, _)| span.contains(*arg_span) || arg_span.overlaps(*span)); + if !dominated { + suggestions.push((*arg_span, self.ty_to_snippet(expected_ty, expected_idx))); + } } } } diff --git a/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs new file mode 100644 index 000000000000..31390faa488b --- /dev/null +++ b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs @@ -0,0 +1,16 @@ +// Regression test for #151607 +// The ICE was "all spans must be disjoint" when emitting diagnostics +// with overlapping suggestion spans. + +struct B; +struct D; +struct F; +fn foo(g: F, y: F, e: &E) { + //~^ ERROR cannot find type `E` in this scope + foo(B, g, D, E, F, G) + //~^ ERROR this function takes 3 arguments but 6 arguments were supplied + //~| ERROR cannot find value `E` in this scope + //~| ERROR cannot find value `G` in this scope +} + +fn main() {} diff --git a/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr new file mode 100644 index 000000000000..f1bda1203347 --- /dev/null +++ b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr @@ -0,0 +1,85 @@ +error[E0425]: cannot find type `E` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:8:24 + | +LL | struct B; + | --------- similarly named struct `B` defined here +... +LL | fn foo(g: F, y: F, e: &E) { + | ^ + | +help: a struct with a similar name exists + | +LL - fn foo(g: F, y: F, e: &E) { +LL + fn foo(g: F, y: F, e: &B) { + | +help: you might be missing a type parameter + | +LL | fn foo(g: F, y: F, e: &E) { + | +++ + +error[E0425]: cannot find value `E` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:10:18 + | +LL | foo(B, g, D, E, F, G) + | ^ + | +help: a local variable with a similar name exists + | +LL - foo(B, g, D, E, F, G) +LL + foo(B, g, D, e, F, G) + | +help: consider importing one of these constants + | +LL + use std::f128::consts::E; + | +LL + use std::f16::consts::E; + | +LL + use std::f32::consts::E; + | +LL + use std::f64::consts::E; + | + +error[E0425]: cannot find value `G` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:10:24 + | +LL | foo(B, g, D, E, F, G) + | ^ + | +help: a local variable with a similar name exists + | +LL - foo(B, g, D, E, F, G) +LL + foo(B, g, D, E, F, g) + | +help: you might be missing a const parameter + | +LL | fn foo(g: F, y: F, e: &E) { + | +++++++++++++++++++++ + +error[E0061]: this function takes 3 arguments but 6 arguments were supplied + --> $DIR/disjoint-spans-issue-151607.rs:10:5 + | +LL | foo(B, g, D, E, F, G) + | ^^^ - - - unexpected argument #4 + | | | + | | unexpected argument #3 of type `D` + | unexpected argument #1 of type `B` + | +note: function defined here + --> $DIR/disjoint-spans-issue-151607.rs:8:4 + | +LL | fn foo(g: F, y: F, e: &E) { + | ^^^ ----- +help: consider borrowing here + | +LL | foo(B, g, D, E, F, &G) + | + +help: remove the extra arguments + | +LL - foo(B, g, D, E, F, G) +LL + foo(, g, F, G) + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0061, E0425. +For more information about an error, try `rustc --explain E0061`.