about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-06-18 18:44:14 +0800
committeryukang <moorekang@gmail.com>2023-06-18 18:44:14 +0800
commit0b20096eff0e12690e63be97647b50383402e57c (patch)
treeed4dc5435f458beb4fce4b0b7fb7ff3d780e85a0
parented7281e784423249ab85c094aaba81e3b949a65f (diff)
downloadrust-0b20096eff0e12690e63be97647b50383402e57c.tar.gz
rust-0b20096eff0e12690e63be97647b50383402e57c.zip
sort the errors from arguments checking so that suggestions are handled properly
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs13
-rw-r--r--tests/ui/argument-suggestions/issue-112507.rs12
-rw-r--r--tests/ui/argument-suggestions/issue-112507.stderr27
3 files changed, 49 insertions, 3 deletions
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<f64>),
+}
+
+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<f64>),
+   |     ^^^^^
+help: remove the extra arguments
+   |
+LL ~         ,
+LL ~         None);
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.