]> git.lizzy.rs Git - rust.git/commitdiff
Point at expressions where inference refines an unexpected type
authorEsteban Küber <esteban@kuber.com.ar>
Tue, 3 Jan 2023 00:23:08 +0000 (16:23 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Thu, 5 Jan 2023 16:51:16 +0000 (16:51 +0000)
Address #106355.

24 files changed:
compiler/rustc_hir_typeck/src/demand.rs
src/test/ui/argument-suggestions/two-mismatch-notes.stderr
src/test/ui/async-await/dont-suggest-missing-await.stderr
src/test/ui/async-await/suggest-missing-await-closure.stderr
src/test/ui/async-await/suggest-missing-await.stderr
src/test/ui/closures/closure-return-type-mismatch.stderr
src/test/ui/coercion/coerce-to-bang.stderr
src/test/ui/generic-associated-types/collections-project-default.stderr
src/test/ui/issues/issue-15783.stderr
src/test/ui/let-else/let-else-ref-bindings.stderr
src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr
src/test/ui/mismatched_types/abridged.stderr
src/test/ui/parser/struct-literal-variant-in-if.stderr
src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/issue-33884.stderr
src/test/ui/structs/struct-base-wrong-type.stderr
src/test/ui/suggestions/call-boxed.stderr
src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr
src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
src/test/ui/traits/issue-52893.stderr
src/test/ui/tuple/wrong_argument_ice-3.stderr
src/test/ui/type/type-check/assignment-in-if.stderr
src/test/ui/type/type-mismatch-same-crate-name.stderr

index 9c6c53abf07488ce6d6b2c74243c0724ecd2b428..c9ee5c6cac8bd668f890447b24c0ebb86a866bb0 100644 (file)
@@ -4,6 +4,7 @@
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
+use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{is_range_literal, Node};
 use rustc_infer::infer::InferOk;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut};
+use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
+use rustc_middle::ty::{
+    self, Article, AssocItem, Ty, TyCtxt, TypeAndMut, TypeSuperFoldable, TypeVisitable,
+};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{BytePos, Span};
 use rustc_trait_selection::infer::InferCtxtExt as _;
@@ -53,7 +57,8 @@ pub fn emit_type_mismatch_suggestions(
             || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
             || self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
             || self.suggest_into(err, expr, expr_ty, expected)
-            || self.suggest_floating_point_literal(err, expr, expected);
+            || self.suggest_floating_point_literal(err, expr, expected)
+            || self.point_inference_types(err, expr);
     }
 
     pub fn emit_coerce_suggestions(
@@ -205,6 +210,157 @@ pub fn demand_coerce_diag(
         (expected, Some(err))
     }
 
+    fn point_inference_types(&self, err: &mut Diagnostic, expr: &hir::Expr<'_>) -> bool {
+        let tcx = self.tcx;
+        let map = self.tcx.hir();
+
+        // Hack to make equality checks on types with inference variables and regions useful.
+        struct TypeEraser<'tcx> {
+            tcx: TyCtxt<'tcx>,
+        }
+        impl<'tcx> TypeFolder<'tcx> for TypeEraser<'tcx> {
+            fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+                self.tcx
+            }
+            fn fold_region(&mut self, _r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+                self.tcx().lifetimes.re_erased
+            }
+            fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+                if !t.needs_infer() && !t.has_erasable_regions() {
+                    return t;
+                }
+                match *t.kind() {
+                    ty::Infer(ty::TyVar(_) | ty::FreshTy(_)) => {
+                        self.tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0)))
+                    }
+                    ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => {
+                        self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 }))
+                    }
+                    ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => {
+                        self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 }))
+                    }
+                    _ => t.super_fold_with(self),
+                }
+            }
+            fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+                ct.super_fold_with(self)
+            }
+        }
+
+        let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; };
+        let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; };
+        let hir::def::Res::Local(hir_id) = p.res else { return false; };
+        let Some(node) = map.find(hir_id) else { return false; };
+        let hir::Node::Pat(pat) = node else { return false; };
+        let parent = map.get_parent_node(pat.hir_id);
+        let Some(hir::Node::Local(hir::Local {
+            ty: None,
+            init: Some(init),
+            ..
+        })) = map.find(parent) else { return false; };
+
+        let ty = self.node_ty(init.hir_id);
+        if ty.is_closure() || init.span.overlaps(expr.span) {
+            return false;
+        }
+        let mut span_labels = vec![(
+            init.span,
+            with_forced_trimmed_paths!(format!(
+                "here the type of `{ident}` is inferred to be `{ty}`",
+            )),
+        )];
+
+        // Locate all the usages of the relevant binding.
+        struct FindExprs<'hir> {
+            hir_id: hir::HirId,
+            uses: Vec<&'hir hir::Expr<'hir>>,
+        }
+        impl<'v> Visitor<'v> for FindExprs<'v> {
+            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+                if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind
+                    && let hir::def::Res::Local(hir_id) = path.res
+                    && hir_id == self.hir_id
+                {
+                    self.uses.push(ex);
+                }
+                hir::intravisit::walk_expr(self, ex);
+            }
+        }
+
+        let mut expr_finder = FindExprs { hir_id, uses: vec![] };
+        let id = map.get_parent_item(hir_id);
+        let hir_id: hir::HirId = id.into();
+
+        if let Some(node) = map.find(hir_id) && let Some(body_id) = node.body_id() {
+            let body = map.body(body_id);
+            expr_finder.visit_expr(body.value);
+            let mut eraser = TypeEraser { tcx };
+            let mut prev = eraser.fold_ty(ty);
+
+            for ex in expr_finder.uses {
+                if ex.span.overlaps(expr.span) { break; }
+                let parent = map.get_parent_node(ex.hir_id);
+                if let Some(hir::Node::Expr(expr))
+                | Some(hir::Node::Stmt(hir::Stmt {
+                    kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr),
+                    ..
+                })) = &map.find(parent)
+                    && let hir::ExprKind::MethodCall(s, rcvr, args, span) = expr.kind
+                    && rcvr.hir_id == ex.hir_id
+                {
+                    let ty = if let Ok(m) = self.lookup_method(ty, s, span, expr, rcvr, args) {
+                        // We get the self type from `lookup_method` because the `rcvr` node
+                        // type will not have had any adjustments from the fn arguments.
+                        let ty = m.sig.inputs_and_output[0];
+                        match ty.kind() {
+                            // Remove one layer of references to account for `&mut self` and
+                            // `&self`, so that we can compare it against the binding.
+                            ty::Ref(_, ty, _) => *ty,
+                            _ => ty,
+                        }
+                    } else {
+                        self.node_ty(rcvr.hir_id)
+                    };
+                    let ty = eraser.fold_ty(ty);
+                    if ty.references_error() {
+                        break;
+                    }
+                    if ty != prev {
+                        span_labels.push((
+                            s.ident.span,
+                            with_forced_trimmed_paths!(format!(
+                                "here the type of `{ident}` is inferred to be `{ty}`",
+                            )),
+                        ));
+                        prev = ty;
+                    }
+                } else {
+                    let ty = eraser.fold_ty(self.node_ty(ex.hir_id));
+                    if ty.references_error() {
+                        break;
+                    }
+                    if ty != prev {
+                        span_labels.push((
+                            ex.span,
+                            with_forced_trimmed_paths!(format!(
+                                "here the type of `{ident}` is inferred to be `{ty}`",
+                            )),
+                        ));
+                    }
+                    prev = ty;
+                }
+                if ex.hir_id == expr.hir_id {
+                    // Stop showing spans after the error type was emitted.
+                    break;
+                }
+            }
+        }
+        for (sp, label) in span_labels {
+            err.span_label(sp, &label);
+        }
+        true
+    }
+
     fn annotate_expected_due_to_let_ty(
         &self,
         err: &mut Diagnostic,
index 7873cf964cbbc978b278bf3cf58b0a5320152d66..3ccd399863d556e2692a3b24497c5cb0196ca77b 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: arguments to this function are incorrect
   --> $DIR/two-mismatch-notes.rs:10:5
    |
+LL |     let w = Wrapper::<isize>(1isize);
+   |             ------------------------ here the type of `w` is inferred to be `Wrapper<isize>`
 LL |     foo(f, w);
    |     ^^^
    |
index 627bf05bba2d9c77110d0f7b00af849089c8b5d1..6e232dd006426fcd72381080a7feb9a4025b383e 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/dont-suggest-missing-await.rs:14:18
    |
+LL |         let x = make_u32();
+   |                 ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
 LL |         take_u32(x)
    |         -------- ^ expected `u32`, found opaque type
    |         |
index a5958baffbaf72719eb8ba87c6f3f17163c2ea4b..9f51832365b615d7170fe451da928c66e5960d89 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/suggest-missing-await-closure.rs:16:18
    |
+LL |         let x = make_u32();
+   |                 ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
 LL |         take_u32(x)
    |         -------- ^ expected `u32`, found opaque type
    |         |
index 1196601ace09087eb0433a807758f949eb2657d7..ce4c8edaf74d6d2d1e1633efdfa5c003f0f0ce2b 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/suggest-missing-await.rs:12:14
    |
+LL |     let x = make_u32();
+   |             ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
 LL |     take_u32(x)
    |     -------- ^ expected `u32`, found opaque type
    |     |
index 3a89d30a05d2042b7106730d21aabcf5b20b2306..d33cf383cbcb4ca38d5e550dd6ffccfff6faa956 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/closure-return-type-mismatch.rs:7:9
    |
+LL |         let a = true;
+   |                 ---- here the type of `a` is inferred to be `bool`
 LL |         a
    |         ^ expected `&str`, found `bool`
    |
index 1207dc7e7a2ff4415da00c5e039b3e4b16418d39..d2fd0f788384eda78315d144a2d2e469e53ba1d0 100644 (file)
@@ -33,6 +33,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:26:12
    |
+LL |     let b = 22;
+   |             -- here the type of `b` is inferred to be `{integer}`
+LL |     let c = 44;
 LL |     foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
    |     ---    ^ expected `!`, found integer
    |     |
@@ -49,6 +52,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:36:12
    |
+LL |     let b = 22;
+   |             -- here the type of `b` is inferred to be `{integer}`
+LL |     let c = 44;
 LL |     foo(a, b, c);
    |     ---    ^ expected `!`, found integer
    |     |
@@ -65,6 +71,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:45:12
    |
+LL |     let b = 22;
+   |             -- here the type of `b` is inferred to be `{integer}`
+LL |     let c = 44;
 LL |     foo(a, b, c);
    |     ---    ^ expected `!`, found integer
    |     |
index 5701017dc3471adad820c7ec5268b5725cc2f13a..c11a5acc35244fbac426d91025372eb37c9eda2a 100644 (file)
@@ -4,6 +4,9 @@ error[E0308]: mismatched types
 LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
    |                                     ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
 ...
+LL |     let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
+   |                   ------------------------------------------------------- here the type of `res` is inferred to be `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
+...
 LL |     res
    |     ^^^ expected Collection::Sibling, found CollectionFamily::Member
    |
index 660dfe9ed3d51bc7617b139fd900ba1b773f3137..74a7c5de7abe271e5eeffb5fe1b9f38b0aa1da05 100644 (file)
@@ -1,6 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/issue-15783.rs:8:19
    |
+LL |     let x = Some(&[name]);
+   |             ------------- here the type of `x` is inferred to be `Option<_>`
 LL |     let msg = foo(x);
    |               --- ^ expected slice `[&str]`, found array `[&str; 1]`
    |               |
index 56b9e073330a6237817715f5c4827f70d6f30fad..39b57ceb43d379247fb7dd840c29775bd5a56aaa 100644 (file)
@@ -19,6 +19,12 @@ LL |     let Some(ref a): Option<&[u8]> = &some else { return };
 error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:24:34
    |
+LL |     let some = Some(bytes);
+   |                ----------- here the type of `some` is inferred to be `Option<_>`
+...
+LL |     let Some(ref a): Option<&[u8]> = some else { return };
+   |                                      ---- here the type of `some` is inferred to be `Option<Vec<u8>>`
+...
 LL |     let Some(a): Option<&[u8]> = some else { return };
    |                  -------------   ^^^^ expected `&[u8]`, found struct `Vec`
    |                  |
@@ -59,6 +65,12 @@ LL |     let Some(ref mut a): Option<&mut [u8]> = &mut some else { return };
 error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:52:38
    |
+LL |     let mut some = Some(bytes);
+   |                    ----------- here the type of `some` is inferred to be `Option<_>`
+...
+LL |     let Some(ref mut a): Option<&mut [u8]> = some else { return };
+   |                                              ---- here the type of `some` is inferred to be `Option<Vec<u8>>`
+...
 LL |     let Some(a): Option<&mut [u8]> = some else { return };
    |                  -----------------   ^^^^ expected `&mut [u8]`, found struct `Vec`
    |                  |
index 82addab94792ac06c4ce8ba5c9563451d42ff514..1d836f20012720699916dabf37111d8e8c4ad960 100644 (file)
@@ -10,6 +10,9 @@ LL | #![feature(unsized_locals, unsized_fn_params)]
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24
    |
+LL |     let z = x.foo();
+   |             ------- here the type of `z` is inferred to be `u32`
+...
 LL |     let _seetype: () = z;
    |                   --   ^ expected `()`, found `u32`
    |                   |
@@ -18,6 +21,9 @@ LL |     let _seetype: () = z;
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24
    |
+LL |     let z = x.foo();
+   |             ------- here the type of `z` is inferred to be `u64`
+...
 LL |     let _seetype: () = z;
    |                   --   ^ expected `()`, found `u64`
    |                   |
@@ -60,6 +66,9 @@ LL |     let z = FinalFoo::foo(x);
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24
    |
+LL |     let z = x.foo();
+   |             ------- here the type of `z` is inferred to be `u8`
+...
 LL |     let _seetype: () = z;
    |                   --   ^ expected `()`, found `u8`
    |                   |
@@ -68,6 +77,9 @@ LL |     let _seetype: () = z;
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24
    |
+LL |     let z = x.foo();
+   |             ------- here the type of `z` is inferred to be `u32`
+...
 LL |     let _seetype: () = z;
    |                   --   ^ expected `()`, found `u32`
    |                   |
@@ -76,6 +88,9 @@ LL |     let _seetype: () = z;
 error[E0308]: mismatched types
   --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24
    |
+LL |     let z = x.foo();
+   |             ------- here the type of `z` is inferred to be `u32`
+...
 LL |     let _seetype: () = z;
    |                   --   ^ expected `()`, found `u32`
    |                   |
index ff1a836c9aec034b7e2cbd5e929b5a190a05b89a..8fd3239e8ee2c273732352035cfae38d81e2d348 100644 (file)
@@ -53,11 +53,19 @@ LL |     Ok(Foo { bar: 1 })
 error[E0308]: mismatched types
   --> $DIR/abridged.rs:39:5
    |
-LL | fn d() -> X<X<String, String>, String> {
-   |           ---------------------------- expected `X<X<String, String>, String>` because of return type
-...
-LL |     x
-   |     ^ expected struct `String`, found integer
+LL |   fn d() -> X<X<String, String>, String> {
+   |             ---------------------------- expected `X<X<String, String>, String>` because of return type
+LL |       let x = X {
+   |  _____________-
+LL | |         x: X {
+LL | |             x: "".to_string(),
+LL | |             y: 2,
+LL | |         },
+LL | |         y: 3,
+LL | |     };
+   | |_____- here the type of `x` is inferred to be `X<_, _>`
+LL |       x
+   |       ^ expected struct `String`, found integer
    |
    = note: expected struct `X<X<_, String>, String>`
               found struct `X<X<_, {integer}>, {integer}>`
@@ -65,11 +73,19 @@ LL |     x
 error[E0308]: mismatched types
   --> $DIR/abridged.rs:50:5
    |
-LL | fn e() -> X<X<String, String>, String> {
-   |           ---------------------------- expected `X<X<String, String>, String>` because of return type
-...
-LL |     x
-   |     ^ expected struct `String`, found integer
+LL |   fn e() -> X<X<String, String>, String> {
+   |             ---------------------------- expected `X<X<String, String>, String>` because of return type
+LL |       let x = X {
+   |  _____________-
+LL | |         x: X {
+LL | |             x: "".to_string(),
+LL | |             y: 2,
+LL | |         },
+LL | |         y: "".to_string(),
+LL | |     };
+   | |_____- here the type of `x` is inferred to be `X<_, _>`
+LL |       x
+   |       ^ expected struct `String`, found integer
    |
    = note: expected struct `X<X<_, String>, _>`
               found struct `X<X<_, {integer}>, _>`
index 9f0c0074d674ceac43093dc128f3cf1266f9a550..97cdd130d0bec0862a3b9b76e1dfa5b71a30ac3e 100644 (file)
@@ -51,6 +51,8 @@ LL |     if x == E::V { field } {}
 error[E0308]: mismatched types
   --> $DIR/struct-literal-variant-in-if.rs:10:20
    |
+LL |     let field = true;
+   |                 ---- here the type of `field` is inferred to be `bool`
 LL |     if x == E::V { field } {}
    |     ---------------^^^^^--
    |     |              |
index 498a112fa9bb3f7434e6031827821cf9ba38bb69..1785c31cfb94832c4a1289dae0b471649f4f841f 100644 (file)
@@ -100,6 +100,12 @@ LL |     let Some(n) = opt && let another = n else {
 error[E0308]: mismatched types
   --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19
    |
+LL |     let opt = Some(1i32);
+   |               ---------- here the type of `opt` is inferred to be `Option<_>`
+LL |
+LL |     let Some(n) = opt else {
+   |                   --- here the type of `opt` is inferred to be `Option<i32>`
+...
 LL |     let Some(n) = opt && n == 1 else {
    |                   ^^^ expected `bool`, found enum `Option`
    |
@@ -120,6 +126,12 @@ LL |     let Some(n) = opt && n == 1 else {
 error[E0308]: mismatched types
   --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
    |
+LL |     let opt = Some(1i32);
+   |               ---------- here the type of `opt` is inferred to be `Option<_>`
+LL |
+LL |     let Some(n) = opt else {
+   |                   --- here the type of `opt` is inferred to be `Option<i32>`
+...
 LL |     let Some(n) = opt && let another = n else {
    |                   ^^^ expected `bool`, found enum `Option`
    |
index db784d5fe6cfc8be856bba650d3c73e750f2b061..75d460d7d8ca9006eceb4a0072c4130ca3c22f4e 100644 (file)
@@ -63,7 +63,10 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:21:9
    |
 LL |     s = format!("foo");
-   |         ^^^^^^^^^^^^^^ expected `&mut String`, found struct `String`
+   |         ^^^^^^^^^^^^^^
+   |         |
+   |         expected `&mut String`, found struct `String`
+   |         here the type of `res` is inferred to be `String`
    |
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
index aee1530851773aaa55c7cba4061fd453b9856667..30e248f381c675e15d81d4c1ff7920cd0fbf9cf6 100644 (file)
@@ -2,7 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-33884.rs:6:22
    |
 LL |     stream.write_fmt(format!("message received"))
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Arguments`, found struct `String`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                      |
+   |                      expected struct `Arguments`, found struct `String`
+   |                      here the type of `res` is inferred to be `String`
    |
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
index b039ce2cc9209fc81f5e967dd762c032c5ec57c3..30feb9cdd70c117f86c28ee92c521bca26881d4a 100644 (file)
@@ -13,6 +13,8 @@ LL | static foo_i: Foo = Foo { a: 2, ..4 };
 error[E0308]: mismatched types
   --> $DIR/struct-base-wrong-type.rs:12:27
    |
+LL |     let b = Bar { x: 5 };
+   |             ------------ here the type of `b` is inferred to be `Bar`
 LL |     let f = Foo { a: 2, ..b };
    |                           ^ expected struct `Foo`, found struct `Bar`
 
index 9b619ac9a3f502fcc4983655dec8070c4362bd77..8295e010f400eb3e119aa95ea19e023101a65402 100644 (file)
@@ -4,7 +4,10 @@ error[E0308]: mismatched types
 LL |     let mut x = 1i32;
    |                 ---- expected due to this value
 LL |     let y = Box::new(|| 1);
-   |                      -- the found closure
+   |             --------------
+   |             |        |
+   |             |        the found closure
+   |             here the type of `y` is inferred to be `Box<_>`
 LL |     x = y;
    |         ^ expected `i32`, found struct `Box`
    |
index 5dc4e64446fb279a108c543e53d3df62dd0f1da0..2546f2515d749453b996f5b194dc8f99deef1530 100644 (file)
@@ -4,7 +4,10 @@ error[E0308]: mismatched types
 LL | /     intrinsic_match! {
 LL | |         "abc"
 LL | |     };
-   | |_____^ expected `&str`, found struct `String`
+   | |     ^
+   | |     |
+   | |_____expected `&str`, found struct `String`
+   |       here the type of `res` is inferred to be `String`
    |
    = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info)
 
index 8c9a41a202767813306bf508a328f785ad74e45c..388d8d8d895e323e4851f687e773e4b74da081a2 100644 (file)
@@ -49,6 +49,8 @@ LL |     let _s = S { _s: ("abc".to_string(),) };
 error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:23:22
    |
+LL |     let t = (1, 2);
+   |             ------ here the type of `t` is inferred to be `({integer}, {integer})`
 LL |     let _x: (i32,) = (t);
    |             ------   ^^^ expected a tuple with 1 element, found one with 2 elements
    |             |
index 7924d3db06f36efb7ce39b5e0740200fc312099e..f7b5b7fca06e87db9eca21ab204d26219a9f6bde 100644 (file)
@@ -4,6 +4,8 @@ error[E0308]: mismatched types
 LL | impl<F, Name, P> AddClass<Name, F> for Class<P>
    |      - this type parameter
 ...
+LL |         let output = builder.to_ref();
+   |                      ---------------- here the type of `output` is inferred to be `Class<P>`
 LL |         builder.push(output);
    |                 ---- ^^^^^^ expected type parameter `F`, found struct `Class`
    |                 |
index 0a503e1fe58c1a503c2e81fb136d0e70368dd24d..c83bc28d8553aae973b448c590ee3d7fc59e13e7 100644 (file)
@@ -1,6 +1,9 @@
 error[E0061]: this method takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-3.rs:9:16
    |
+LL |     let new_group = vec![String::new()];
+   |                     ------------------- here the type of `new_group` is inferred to be `Vec<_, _>`
+...
 LL |         groups.push(new_group, vec![process]);
    |                ^^^^            ------------- argument of type `Vec<&Process>` unexpected
    |
index 9f4558adab150708696dc1aba163bd6cdbacca3d..fb11d6160bbaa4978cbb8fbbba134394842e30ad 100644 (file)
@@ -67,6 +67,12 @@ LL |             x == 5
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:44:18
    |
+LL |     let x = 1;
+   |             - here the type of `x` is inferred to be `{integer}`
+...
+LL |         println!("{}", x);
+   |                        - here the type of `x` is inferred to be `usize`
+...
 LL |     if x == x && x = x && x == x {
    |        ------    ^ expected `bool`, found `usize`
    |        |
@@ -75,6 +81,12 @@ LL |     if x == x && x = x && x == x {
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:44:22
    |
+LL |     let x = 1;
+   |             - here the type of `x` is inferred to be `{integer}`
+...
+LL |         println!("{}", x);
+   |                        - here the type of `x` is inferred to be `usize`
+...
 LL |     if x == x && x = x && x == x {
    |                      ^ expected `bool`, found `usize`
 
@@ -92,6 +104,12 @@ LL |     if x == x && x == x && x == x {
 error[E0308]: mismatched types
   --> $DIR/assignment-in-if.rs:51:28
    |
+LL |     let x = 1;
+   |             - here the type of `x` is inferred to be `{integer}`
+...
+LL |         println!("{}", x);
+   |                        - here the type of `x` is inferred to be `usize`
+...
 LL |     if x == x && x == x && x = x {
    |        ----------------    ^ expected `bool`, found `usize`
    |        |
index fcafd315ebf5450e5f0ea68e6281a6d52969bf46..e99d30d33963126b5912eba980c2d6ced48e87b9 100644 (file)
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/type-mismatch-same-crate-name.rs:16:20
    |
+LL |     let foo2 = {extern crate crate_a2 as a; a::Foo};
+   |                ------------------------------------ here the type of `foo2` is inferred to be `_`
+...
 LL |         a::try_foo(foo2);
    |         ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo`
    |         |
@@ -27,6 +30,9 @@ LL | pub fn try_foo(x: Foo){}
 error[E0308]: mismatched types
   --> $DIR/type-mismatch-same-crate-name.rs:20:20
    |
+LL |     let bar2 = {extern crate crate_a2 as a; a::bar()};
+   |                -------------------------------------- here the type of `bar2` is inferred to be `_`
+...
 LL |         a::try_bar(bar2);
    |         ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
    |         |