Skip to content

Commit 6c5e212

Browse files
Rollup merge of rust-lang#112762 - chenyukang:yukang-fix-112507-argument-checking, r=compiler-errors
Sort the errors from arguments checking so that suggestions are handled properly Fixes rust-lang#112507 The algorithm of `find_issue` does not make sure the index comes out in order, which will make suggesting `remove` or `add` arguments broken in some cases. Modifying the algorithm to obey order involves much more trivial change, so it's better to order the `errors` after iterations.
2 parents a318824 + aba1cf1 commit 6c5e212

File tree

3 files changed

+75
-5
lines changed

3 files changed

+75
-5
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs

+36-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::cmp;
2-
1+
use core::cmp::Ordering;
32
use rustc_index::IndexVec;
43
use rustc_middle::ty::error::TypeError;
4+
use std::cmp;
55

66
rustc_index::newtype_index! {
77
#[debug_format = "ExpectedIdx({})"]
@@ -34,14 +34,14 @@ enum Issue {
3434
Permutation(Vec<Option<usize>>),
3535
}
3636

37-
#[derive(Clone, Debug)]
37+
#[derive(Clone, Debug, Eq, PartialEq)]
3838
pub(crate) enum Compatibility<'tcx> {
3939
Compatible,
4040
Incompatible(Option<TypeError<'tcx>>),
4141
}
4242

4343
/// Similar to `Issue`, but contains some extra information
44-
#[derive(Debug)]
44+
#[derive(Debug, PartialEq, Eq)]
4545
pub(crate) enum Error<'tcx> {
4646
/// The provided argument is the invalid type for the expected input
4747
Invalid(ProvidedIdx, ExpectedIdx, Compatibility<'tcx>),
@@ -55,6 +55,34 @@ pub(crate) enum Error<'tcx> {
5555
Permutation(Vec<(ExpectedIdx, ProvidedIdx)>),
5656
}
5757

58+
impl Ord for Error<'_> {
59+
fn cmp(&self, other: &Self) -> Ordering {
60+
let key = |error: &Error<'_>| -> usize {
61+
match error {
62+
Error::Invalid(..) => 0,
63+
Error::Extra(_) => 1,
64+
Error::Missing(_) => 2,
65+
Error::Swap(..) => 3,
66+
Error::Permutation(..) => 4,
67+
}
68+
};
69+
match (self, other) {
70+
(Error::Invalid(a, _, _), Error::Invalid(b, _, _)) => a.cmp(b),
71+
(Error::Extra(a), Error::Extra(b)) => a.cmp(b),
72+
(Error::Missing(a), Error::Missing(b)) => a.cmp(b),
73+
(Error::Swap(a, b, ..), Error::Swap(c, d, ..)) => a.cmp(c).then(b.cmp(d)),
74+
(Error::Permutation(a), Error::Permutation(b)) => a.cmp(b),
75+
_ => key(self).cmp(&key(other)),
76+
}
77+
}
78+
}
79+
80+
impl PartialOrd for Error<'_> {
81+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
82+
Some(self.cmp(other))
83+
}
84+
}
85+
5886
pub(crate) struct ArgMatrix<'tcx> {
5987
/// Maps the indices in the `compatibility_matrix` rows to the indices of
6088
/// the *user provided* inputs
@@ -177,7 +205,7 @@ impl<'tcx> ArgMatrix<'tcx> {
177205
// If an argument is unsatisfied, and the input in its position is useless
178206
// then the most likely explanation is that we just got the types wrong
179207
(true, true, true, true) => return Some(Issue::Invalid(i)),
180-
// Otherwise, if an input is useless, then indicate that this is an extra argument
208+
// Otherwise, if an input is useless then indicate that this is an extra input
181209
(true, _, true, _) => return Some(Issue::Extra(i)),
182210
// Otherwise, if an argument is unsatisfiable, indicate that it's missing
183211
(_, true, _, true) => return Some(Issue::Missing(i)),
@@ -376,6 +404,9 @@ impl<'tcx> ArgMatrix<'tcx> {
376404
};
377405
}
378406

407+
// sort errors with same type by the order they appear in the source
408+
// so that suggestion will be handled properly, see #112507
409+
errors.sort();
379410
return (errors, matched_inputs);
380411
}
381412
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pub enum Value {
2+
Float(Option<f64>),
3+
}
4+
5+
fn main() {
6+
let _a = Value::Float( //~ ERROR this enum variant takes 1 argument but 4 arguments were supplied
7+
0,
8+
None,
9+
None,
10+
0,
11+
);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0061]: this enum variant takes 1 argument but 4 arguments were supplied
2+
--> $DIR/issue-112507.rs:6:14
3+
|
4+
LL | let _a = Value::Float(
5+
| ^^^^^^^^^^^^
6+
LL | 0,
7+
| - unexpected argument of type `{integer}`
8+
LL | None,
9+
LL | None,
10+
| ---- unexpected argument of type `Option<_>`
11+
LL | 0,
12+
| - unexpected argument of type `{integer}`
13+
|
14+
note: tuple variant defined here
15+
--> $DIR/issue-112507.rs:2:5
16+
|
17+
LL | Float(Option<f64>),
18+
| ^^^^^
19+
help: remove the extra arguments
20+
|
21+
LL ~ ,
22+
LL ~ None);
23+
|
24+
25+
error: aborting due to previous error
26+
27+
For more information about this error, try `rustc --explain E0061`.

0 commit comments

Comments
 (0)