diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index d45e3d395e4..e535d244c89 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -1,7 +1,7 @@ -use std::cmp; - +use core::cmp::Ordering; use rustc_index::IndexVec; use rustc_middle::ty::error::TypeError; +use std::cmp; rustc_index::newtype_index! { #[debug_format = "ExpectedIdx({})"] @@ -177,7 +177,7 @@ impl<'tcx> ArgMatrix<'tcx> { // If an argument is unsatisfied, and the input in its position is useless // then the most likely explanation is that we just got the types wrong (true, true, true, true) => return Some(Issue::Invalid(i)), - // Otherwise, if an input is useless, then indicate that this is an extra argument + // Otherwise, if an input is useless then indicate that this is an extra input (true, _, true, _) => return Some(Issue::Extra(i)), // Otherwise, if an argument is unsatisfiable, indicate that it's missing (_, true, _, true) => return Some(Issue::Missing(i)), @@ -376,6 +376,13 @@ impl<'tcx> ArgMatrix<'tcx> { }; } + // sort errors with same type by the order they appear in the source + // so that suggestion will be handled properly, see #112507 + errors.sort_by(|a, b| match (a, b) { + (Error::Missing(i), Error::Missing(j)) => i.cmp(j), + (Error::Extra(i), Error::Extra(j)) => i.cmp(j), + _ => Ordering::Equal, + }); return (errors, matched_inputs); } } diff --git a/tests/ui/argument-suggestions/issue-112507.rs b/tests/ui/argument-suggestions/issue-112507.rs new file mode 100644 index 00000000000..61743c59a4a --- /dev/null +++ b/tests/ui/argument-suggestions/issue-112507.rs @@ -0,0 +1,12 @@ +pub enum Value { + Float(Option), +} + +fn main() { + let _a = Value::Float( //~ ERROR this enum variant takes 1 argument but 4 arguments were supplied + 0, + None, + None, + 0, + ); +} diff --git a/tests/ui/argument-suggestions/issue-112507.stderr b/tests/ui/argument-suggestions/issue-112507.stderr new file mode 100644 index 00000000000..dfb47e010e4 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-112507.stderr @@ -0,0 +1,27 @@ +error[E0061]: this enum variant takes 1 argument but 4 arguments were supplied + --> $DIR/issue-112507.rs:6:14 + | +LL | let _a = Value::Float( + | ^^^^^^^^^^^^ +LL | 0, + | - unexpected argument of type `{integer}` +LL | None, +LL | None, + | ---- unexpected argument of type `Option<_>` +LL | 0, + | - unexpected argument of type `{integer}` + | +note: tuple variant defined here + --> $DIR/issue-112507.rs:2:5 + | +LL | Float(Option), + | ^^^^^ +help: remove the extra arguments + | +LL ~ , +LL ~ None); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`.