about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-21 22:18:51 +0000
committerMichael Goulet <michael@errs.io>2023-01-23 17:02:50 +0000
commit9f933b5642c08e4241cbfed0f15270df552ce8e6 (patch)
treeaf403e84ac338b87da05bc79bedbd87bdd69ac8c
parentbed3bb53d207c1bf92c26833e8d3d4280550f83e (diff)
downloadrust-9f933b5642c08e4241cbfed0f15270df552ce8e6.tar.gz
rust-9f933b5642c08e4241cbfed0f15270df552ce8e6.zip
Hack to suppress bad labels in type mismatch inference deduction code
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs36
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs8
-rw-r--r--tests/ui/typeck/bad-type-in-vec-push.rs6
-rw-r--r--tests/ui/typeck/bad-type-in-vec-push.stderr19
4 files changed, 47 insertions, 22 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index d8cca55a8f8..8e23ded3c09 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -61,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             || self.suggest_into(err, expr, expr_ty, expected)
             || self.suggest_floating_point_literal(err, expr, expected);
         if !suggested {
-            self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected);
+            self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected, expr.span);
         }
     }
 
@@ -222,6 +222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         found: Ty<'tcx>,
         expected: Ty<'tcx>,
+        mismatch_span: Span,
     ) -> bool {
         let map = self.tcx.hir();
 
@@ -281,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             },
         };
         let mut prev = eraser.fold_ty(ty);
-        let mut prev_span = None;
+        let mut prev_span: Option<Span> = None;
 
         for binding in expr_finder.uses {
             // In every expression where the binding is referenced, we will look at that
@@ -334,13 +335,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             let arg = &args[i];
                             let arg_ty = self.node_ty(arg.hir_id);
                             if !arg.span.overlaps(mismatch_span) {
-                            err.span_label(
-                                arg.span,
-                                &format!(
-                                    "this is of type `{arg_ty}`, which causes `{ident}` to be \
-                                     inferred as `{ty}`",
-                                ),
-                            );
+                                err.span_label(
+                                    arg.span,
+                                    &format!(
+                                        "this is of type `{arg_ty}`, which causes `{ident}` to be \
+                                        inferred as `{ty}`",
+                                    ),
+                                );
                             }
                             param_args.insert(param_ty, (arg, arg_ty));
                         }
@@ -384,12 +385,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && self.can_eq(self.param_env, ty, found).is_ok()
                 {
                     // We only point at the first place where the found type was inferred.
+                    if !segment.ident.span.overlaps(mismatch_span) {
                     err.span_label(
                         segment.ident.span,
                         with_forced_trimmed_paths!(format!(
                             "here the type of `{ident}` is inferred to be `{ty}`",
                         )),
-                    );
+                    );}
                     break;
                 } else if !param_args.is_empty() {
                     break;
@@ -408,12 +410,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We use the *previous* span because if the type is known *here* it means
                     // it was *evaluated earlier*. We don't do this for method calls because we
                     // evaluate the method's self type eagerly, but not in any other case.
-                    err.span_label(
-                        span,
-                        with_forced_trimmed_paths!(format!(
-                            "here the type of `{ident}` is inferred to be `{ty}`",
-                        )),
-                    );
+                    if !span.overlaps(mismatch_span) {
+                        err.span_label(
+                            span,
+                            with_forced_trimmed_paths!(format!(
+                                "here the type of `{ident}` is inferred to be `{ty}`",
+                            )),
+                        );
+                    }
                     break;
                 }
                 prev = ty;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index c9609e69439..677c80297b9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -808,7 +808,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     kind: TypeVariableOriginKind::MiscVariable,
                     span: full_call_span,
                 });
-                self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty);
+                self.point_at_expr_source_of_inferred_type(
+                    &mut err,
+                    rcvr,
+                    expected,
+                    callee_ty,
+                    provided_arg_span,
+                );
             }
             // Call out where the function is defined
             self.label_fn_like(
diff --git a/tests/ui/typeck/bad-type-in-vec-push.rs b/tests/ui/typeck/bad-type-in-vec-push.rs
index 397e07dc17b..a807f030cfc 100644
--- a/tests/ui/typeck/bad-type-in-vec-push.rs
+++ b/tests/ui/typeck/bad-type-in-vec-push.rs
@@ -12,3 +12,9 @@ fn main() {
     //~^ ERROR mismatched types
     // So it thinks that the type of `result` is constrained here.
 }
+
+fn example2() {
+    let mut x = vec![1];
+    x.push("");
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/typeck/bad-type-in-vec-push.stderr b/tests/ui/typeck/bad-type-in-vec-push.stderr
index a24c49f0e9a..e4c99ec8e70 100644
--- a/tests/ui/typeck/bad-type-in-vec-push.stderr
+++ b/tests/ui/typeck/bad-type-in-vec-push.stderr
@@ -4,10 +4,8 @@ error[E0308]: mismatched types
 LL |     vector.sort();
    |     ------ here the type of `vector` is inferred to be `Vec<_>`
 LL |     result.push(vector);
-   |            ---- ^^^^^^
-   |            |    |
-   |            |    expected integer, found struct `Vec`
-   |            |    this is of type `Vec<_>`, which causes `result` to be inferred as `Vec<{integer}>`
+   |            ---- ^^^^^^ expected integer, found struct `Vec`
+   |            |
    |            arguments to this method are incorrect
    |
    = note: expected type `{integer}`
@@ -15,6 +13,17 @@ LL |     result.push(vector);
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/bad-type-in-vec-push.rs:18:12
+   |
+LL |     x.push("");
+   |       ---- ^^ expected integer, found `&str`
+   |       |
+   |       arguments to this method are incorrect
+   |
+note: associated function defined here
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.