Skip to content

Commit c905f5e

Browse files
committed
Account for type error on method arg caused by earlier inference
```rust fn main() { let v = Vec::new(); v.push(0); v.push(0); v.push(""); } ``` now produces ``` error[E0308]: mismatched types --> $DIR/point-at-inference-3.rs:6:12 | LL | v.push(0); | - this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` ... LL | v.push(""); | ---- ^^ expected integer, found `&str` | | | arguments to this function are incorrect | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ```
1 parent ad82eed commit c905f5e

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
213213
(expected, Some(err))
214214
}
215215

216-
fn point_at_expr_source_of_inferred_type(
216+
pub fn point_at_expr_source_of_inferred_type(
217217
&self,
218218
err: &mut Diagnostic,
219219
expr: &hir::Expr<'_>,
@@ -387,6 +387,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
387387
)),
388388
);
389389
break;
390+
} else if !param_args.is_empty() {
391+
break;
390392
}
391393
prev = ty;
392394
} else {

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+12
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
798798
full_call_span,
799799
format!("arguments to this {} are incorrect", call_name),
800800
);
801+
if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) =
802+
(callee_ty, &call_expr.kind)
803+
{
804+
// Type that would have accepted this argument if it hadn't been inferred earlier.
805+
// FIXME: We leave an inference variable for now, but it'd be nice to get a more
806+
// specific type to increase the accuracy of the diagnostic.
807+
let expected = self.infcx.next_ty_var(TypeVariableOrigin {
808+
kind: TypeVariableOriginKind::MiscVariable,
809+
span: full_call_span,
810+
});
811+
self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty);
812+
}
801813
// Call out where the function is defined
802814
self.label_fn_like(
803815
&mut err,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn main() {
2+
let v = Vec::new();
3+
v.push(0);
4+
//~^ NOTE this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>`
5+
v.push(0);
6+
v.push(""); //~ ERROR mismatched types
7+
//~^ NOTE expected integer, found `&str`
8+
//~| NOTE arguments to this function are incorrect
9+
//~| NOTE associated function defined here
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/point-at-inference-3.rs:6:12
3+
|
4+
LL | v.push(0);
5+
| - this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>`
6+
...
7+
LL | v.push("");
8+
| ---- ^^ expected integer, found `&str`
9+
| |
10+
| arguments to this function are incorrect
11+
|
12+
note: associated function defined here
13+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)