Skip to content

Commit 5bc4980

Browse files
authored
Rollup merge of #107175 - compiler-errors:bad-types-in-vec-push, r=estebank
Fix escaping inference var ICE in `point_at_expr_source_of_inferred_type` Fixes #107158 `point_at_expr_source_of_inferred_type` uses `lookup_probe` to adjust the self type of a method receiver -- but that method returns inference variables from inside a probe. That means that the ty vars are no longer valid, so we can't use any infcx methods on them. Also, pass some extra span info to hack a quick solution to bad labels, resulting in this diagnostic improvement: ```rust fn example2() { let mut x = vec![1]; x.push(""); } ``` ```diff error[E0308]: mismatched types --> src/main.rs:5:12 | 5 | x.push(""); | ---- ^^ | | | | | expected integer, found `&str` - | | this is of type `&'static str`, which causes `x` to be inferred as `Vec<{integer}>` | arguments to this method are incorrect ``` (since that "which causes `x` to be inferred as `Vec<{integer}>` part is wrong) r? `@estebank` (we really should make this code better in general, cc #106590, but that's a bit bigger issue that needs some more thinking about)
2 parents 4b51b20 + 9f933b5 commit 5bc4980

File tree

4 files changed

+79
-18
lines changed

4 files changed

+79
-18
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+23-17
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6262
|| self.suggest_floating_point_literal(err, expr, expected)
6363
|| self.note_result_coercion(err, expr, expected, expr_ty);
6464
if !suggested {
65-
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
65+
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected, expr.span);
6666
}
6767
}
6868

@@ -222,6 +222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
222222
expr: &hir::Expr<'_>,
223223
found: Ty<'tcx>,
224224
expected: Ty<'tcx>,
225+
mismatch_span: Span,
225226
) -> bool {
226227
let map = self.tcx.hir();
227228

@@ -270,7 +271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
270271
lt_op: |_| self.tcx.lifetimes.re_erased,
271272
ct_op: |c| c,
272273
ty_op: |t| match *t.kind() {
273-
ty::Infer(ty::TyVar(vid)) => self.tcx.mk_ty_infer(ty::TyVar(self.root_var(vid))),
274+
ty::Infer(ty::TyVar(_)) => self.tcx.mk_ty_var(ty::TyVid::from_u32(0)),
274275
ty::Infer(ty::IntVar(_)) => {
275276
self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 }))
276277
}
@@ -281,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
281282
},
282283
};
283284
let mut prev = eraser.fold_ty(ty);
284-
let mut prev_span = None;
285+
let mut prev_span: Option<Span> = None;
285286

286287
for binding in expr_finder.uses {
287288
// In every expression where the binding is referenced, we will look at that
@@ -333,13 +334,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
333334
// inferred in this method call.
334335
let arg = &args[i];
335336
let arg_ty = self.node_ty(arg.hir_id);
336-
err.span_label(
337-
arg.span,
338-
&format!(
339-
"this is of type `{arg_ty}`, which causes `{ident}` to be \
340-
inferred as `{ty}`",
341-
),
342-
);
337+
if !arg.span.overlaps(mismatch_span) {
338+
err.span_label(
339+
arg.span,
340+
&format!(
341+
"this is of type `{arg_ty}`, which causes `{ident}` to be \
342+
inferred as `{ty}`",
343+
),
344+
);
345+
}
343346
param_args.insert(param_ty, (arg, arg_ty));
344347
}
345348
}
@@ -382,12 +385,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
382385
&& self.can_eq(self.param_env, ty, found).is_ok()
383386
{
384387
// We only point at the first place where the found type was inferred.
388+
if !segment.ident.span.overlaps(mismatch_span) {
385389
err.span_label(
386390
segment.ident.span,
387391
with_forced_trimmed_paths!(format!(
388392
"here the type of `{ident}` is inferred to be `{ty}`",
389393
)),
390-
);
394+
);}
391395
break;
392396
} else if !param_args.is_empty() {
393397
break;
@@ -406,12 +410,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
406410
// We use the *previous* span because if the type is known *here* it means
407411
// it was *evaluated earlier*. We don't do this for method calls because we
408412
// evaluate the method's self type eagerly, but not in any other case.
409-
err.span_label(
410-
span,
411-
with_forced_trimmed_paths!(format!(
412-
"here the type of `{ident}` is inferred to be `{ty}`",
413-
)),
414-
);
413+
if !span.overlaps(mismatch_span) {
414+
err.span_label(
415+
span,
416+
with_forced_trimmed_paths!(format!(
417+
"here the type of `{ident}` is inferred to be `{ty}`",
418+
)),
419+
);
420+
}
415421
break;
416422
}
417423
prev = ty;

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
808808
kind: TypeVariableOriginKind::MiscVariable,
809809
span: full_call_span,
810810
});
811-
self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty);
811+
self.point_at_expr_source_of_inferred_type(
812+
&mut err,
813+
rcvr,
814+
expected,
815+
callee_ty,
816+
provided_arg_span,
817+
);
812818
}
813819
// Call out where the function is defined
814820
self.label_fn_like(
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// The error message here still is pretty confusing.
2+
3+
fn main() {
4+
let mut result = vec![1];
5+
// The type of `result` is constrained to be `Vec<{integer}>` here.
6+
// But the logic we use to find what expression constrains a type
7+
// is not sophisticated enough to know this.
8+
9+
let mut vector = Vec::new();
10+
vector.sort();
11+
result.push(vector);
12+
//~^ ERROR mismatched types
13+
// So it thinks that the type of `result` is constrained here.
14+
}
15+
16+
fn example2() {
17+
let mut x = vec![1];
18+
x.push("");
19+
//~^ ERROR mismatched types
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/bad-type-in-vec-push.rs:11:17
3+
|
4+
LL | vector.sort();
5+
| ------ here the type of `vector` is inferred to be `Vec<_>`
6+
LL | result.push(vector);
7+
| ---- ^^^^^^ expected integer, found struct `Vec`
8+
| |
9+
| arguments to this method are incorrect
10+
|
11+
= note: expected type `{integer}`
12+
found struct `Vec<_>`
13+
note: associated function defined here
14+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/bad-type-in-vec-push.rs:18:12
18+
|
19+
LL | x.push("");
20+
| ---- ^^ expected integer, found `&str`
21+
| |
22+
| arguments to this method are incorrect
23+
|
24+
note: associated function defined here
25+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)