]> git.lizzy.rs Git - rust.git/commitdiff
Account for type error on method arg caused by earlier inference
authorEsteban Küber <esteban@kuber.com.ar>
Thu, 5 Jan 2023 00:18:57 +0000 (00:18 +0000)
committerEsteban Küber <esteban@kuber.com.ar>
Thu, 5 Jan 2023 16:51:17 +0000 (16:51 +0000)
```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
```

compiler/rustc_hir_typeck/src/demand.rs
compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
src/test/ui/type/type-check/point-at-inference-3.rs [new file with mode: 0644]
src/test/ui/type/type-check/point-at-inference-3.stderr [new file with mode: 0644]

index abff2637519160ca8194804e5d48f822b3cdc181..cff74cd9693dc21685aafb0466b53ccada58c99c 100644 (file)
@@ -213,7 +213,7 @@ pub fn demand_coerce_diag(
         (expected, Some(err))
     }
 
-    fn point_at_expr_source_of_inferred_type(
+    pub fn point_at_expr_source_of_inferred_type(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -387,6 +387,8 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
                         )),
                     );
                     break;
+                } else if !param_args.is_empty() {
+                    break;
                 }
                 prev = ty;
             } else {
index 55280487adda42b38eca2b05e7dd78b9801737a6..7d6b4aaebf4ea93c4313699c7d0208c065273088 100644 (file)
@@ -798,6 +798,18 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
                 full_call_span,
                 format!("arguments to this {} are incorrect", call_name),
             );
+            if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) =
+                (callee_ty, &call_expr.kind)
+            {
+                // Type that would have accepted this argument if it hadn't been inferred earlier.
+                // FIXME: We leave an inference variable for now, but it'd be nice to get a more
+                // specific type to increase the accuracy of the diagnostic.
+                let expected = self.infcx.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span: full_call_span,
+                });
+                self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty);
+            }
             // Call out where the function is defined
             self.label_fn_like(
                 &mut err,
diff --git a/src/test/ui/type/type-check/point-at-inference-3.rs b/src/test/ui/type/type-check/point-at-inference-3.rs
new file mode 100644 (file)
index 0000000..893306d
--- /dev/null
@@ -0,0 +1,10 @@
+fn main() {
+    let v = Vec::new();
+    v.push(0);
+    //~^ NOTE this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>`
+    v.push(0);
+    v.push(""); //~ ERROR mismatched types
+    //~^ NOTE expected integer, found `&str`
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE associated function defined here
+}
diff --git a/src/test/ui/type/type-check/point-at-inference-3.stderr b/src/test/ui/type/type-check/point-at-inference-3.stderr
new file mode 100644 (file)
index 0000000..01264ed
--- /dev/null
@@ -0,0 +1,17 @@
+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
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.