Skip to content

Commit af7b167

Browse files
committed
Avoid infinite loop in function arguments checking
1 parent 1603a70 commit af7b167

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,14 @@ impl<'tcx> ArgMatrix<'tcx> {
364364
None => {
365365
// We didn't find any issues, so we need to push the algorithm forward
366366
// First, eliminate any arguments that currently satisfy their inputs
367-
for (inp, arg) in self.eliminate_satisfied() {
367+
let eliminated = self.eliminate_satisfied();
368+
if eliminated.len() == 0 {
369+
// In every iteration, we should reduce the size of provided_indices or expected_indices
370+
// Othewise, means we meet an weird compatibility_matrix which we can not shrink the size,
371+
// we will get into infinite loop if we don't break the loop, see #100478
372+
break;
373+
}
374+
for (inp, arg) in eliminated {
368375
matched_inputs[arg] = Some(inp);
369376
}
370377
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use std::sync::Arc;
2+
macro_rules! GenT {
3+
($name:tt) => {
4+
#[derive(Default, Debug)]
5+
struct $name {
6+
#[allow(unused)]
7+
val: i32,
8+
}
9+
10+
impl $name {
11+
#[allow(unused)]
12+
fn new(val: i32) -> Self {
13+
$name { val }
14+
}
15+
}
16+
};
17+
}
18+
19+
GenT!(T1);
20+
GenT!(T2);
21+
GenT!(T3);
22+
GenT!(T4);
23+
GenT!(T5);
24+
GenT!(T6);
25+
GenT!(T7);
26+
GenT!(T8);
27+
GenT!(T9);
28+
GenT!(T10);
29+
GenT!(T11);
30+
31+
#[allow(unused)]
32+
fn foo(
33+
p1: T1,
34+
p2: Arc<T2>,
35+
p3: T3,
36+
p4: Arc<T4>,
37+
p5: T5,
38+
p6: T6,
39+
p7: T7,
40+
p8: Arc<T8>,
41+
p9: T9,
42+
p10: T10,
43+
p11: T11,
44+
) {
45+
}
46+
47+
fn main() {
48+
let p1 = T1::new(0);
49+
let p2 = Arc::new(T2::new(0));
50+
let p3 = T3::new(0);
51+
let p4 = Arc::new(T4::new(1));
52+
let p5 = T5::new(0);
53+
let p6 = T6::new(0);
54+
let p7 = T7::new(0);
55+
let p8 = Arc::default();
56+
let p9 = T9::new(0);
57+
let p10 = T10::new(0);
58+
let p11 = T11::new(0);
59+
60+
foo(
61+
//~^ ERROR 60:5: 60:8: this function takes 11 arguments but 10 arguments were supplied [E0061]
62+
p1, //p2,
63+
p3, p4, p5, p6, p7, p8, p9, p10, p11,
64+
);
65+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0061]: this function takes 11 arguments but 10 arguments were supplied
2+
--> $DIR/issue-100478.rs:60:5
3+
|
4+
LL | foo(
5+
| ^^^
6+
|
7+
note: function defined here
8+
--> $DIR/issue-100478.rs:32:4
9+
|
10+
LL | fn foo(
11+
| ^^^
12+
LL | p1: T1,
13+
| ------
14+
LL | p2: Arc<T2>,
15+
| -----------
16+
LL | p3: T3,
17+
| ------
18+
LL | p4: Arc<T4>,
19+
| -----------
20+
LL | p5: T5,
21+
| ------
22+
LL | p6: T6,
23+
| ------
24+
LL | p7: T7,
25+
| ------
26+
LL | p8: Arc<T8>,
27+
| -----------
28+
LL | p9: T9,
29+
| ------
30+
LL | p10: T10,
31+
| --------
32+
LL | p11: T11,
33+
| --------
34+
help: did you mean
35+
|
36+
LL | foo(p1, /* Arc<T2> */, /* T3 */, /* Arc<T4> */, /* T5 */, /* T6 */, /* T7 */, /* Arc<T8> */, /* T9 */, /* T10 */, /* T11 */);
37+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38+
39+
error: aborting due to previous error
40+
41+
For more information about this error, try `rustc --explain E0061`.

0 commit comments

Comments
 (0)