Skip to content

Commit 5fac20f

Browse files
authored
Rollup merge of rust-lang#108050 - martingms:issue-108042-fix, r=compiler-errors
Fix index out of bounds ICE in `point_at_expr_source_of_inferred_type` There might be more type params than args to a method call, which leads to an index out of bounds panic. I'm not familiar with this code at all, so unsure whether this is the right fix, but at least this patch fixes rust-lang#108042 for me (I hit the same issue with similar code)
2 parents 0c5bbca + e159c1e commit 5fac20f

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
298298
// call's arguments and we can provide a more explicit span.
299299
let sig = self.tcx.fn_sig(def_id).subst_identity();
300300
let def_self_ty = sig.input(0).skip_binder();
301+
let param_tys = sig.inputs().skip_binder().iter().skip(1);
302+
// If there's an arity mismatch, pointing out the call as the source of an inference
303+
// can be misleading, so we skip it.
304+
if param_tys.len() != args.len() {
305+
continue;
306+
}
301307
let rcvr_ty = self.node_ty(rcvr.hir_id);
302308
// Get the evaluated type *after* calling the method call, so that the influence
303309
// of the arguments can be reflected in the receiver type. The receiver
@@ -323,13 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
323329
let mut param_found = FxHashMap::default();
324330
if self.can_eq(self.param_env, ty, found) {
325331
// We only point at the first place where the found type was inferred.
326-
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
332+
for (param_ty, arg) in param_tys.zip(args) {
327333
if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
328334
// We found an argument that references a type parameter in `Self`,
329335
// so we assume that this is the argument that caused the found
330336
// type, which we know already because of `can_eq` above was first
331337
// inferred in this method call.
332-
let arg = &args[i];
333338
let arg_ty = self.node_ty(arg.hir_id);
334339
if !arg.span.overlaps(mismatch_span) {
335340
err.span_label(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
struct S<A, B>(Option<(A, B)>);
2+
3+
impl<A, B> S<A, B> {
4+
fn infer(&self, a: A, b: B) {}
5+
//~^ NOTE associated function defined here
6+
//~| NOTE
7+
//~| NOTE
8+
}
9+
10+
fn main() {
11+
let s = S(None);
12+
s.infer(0i32);
13+
//~^ ERROR this method takes 2 arguments but 1 argument was supplied
14+
//~| NOTE an argument is missing
15+
//~| HELP provide the argument
16+
let t: S<u32, _> = s;
17+
//~^ ERROR mismatched types
18+
//~| NOTE expected `S<u32, _>`, found `S<i32, _>`
19+
//~| NOTE expected due to this
20+
//~| NOTE expected struct `S<u32, _>`
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0061]: this method takes 2 arguments but 1 argument was supplied
2+
--> $DIR/point-at-inference-4.rs:12:7
3+
|
4+
LL | s.infer(0i32);
5+
| ^^^^^------ an argument is missing
6+
|
7+
note: associated function defined here
8+
--> $DIR/point-at-inference-4.rs:4:8
9+
|
10+
LL | fn infer(&self, a: A, b: B) {}
11+
| ^^^^^ ---- ----
12+
help: provide the argument
13+
|
14+
LL | s.infer(0i32, /* b */);
15+
| ~~~~~~~~~~~~~~~
16+
17+
error[E0308]: mismatched types
18+
--> $DIR/point-at-inference-4.rs:16:24
19+
|
20+
LL | let t: S<u32, _> = s;
21+
| --------- ^ expected `S<u32, _>`, found `S<i32, _>`
22+
| |
23+
| expected due to this
24+
|
25+
= note: expected struct `S<u32, _>`
26+
found struct `S<i32, _>`
27+
28+
error: aborting due to 2 previous errors
29+
30+
Some errors have detailed explanations: E0061, E0308.
31+
For more information about an error, try `rustc --explain E0061`.

0 commit comments

Comments
 (0)