diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 1360383a75a95..ab232be36a075 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -4,6 +4,7 @@ use rustc_errors::MultiSpan; 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; @@ -11,8 +12,11 @@ use rustc_middle::lint::in_external_macro; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (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, diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr index 7873cf964cbbc..3ccd399863d55 100644 --- a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr +++ b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr @@ -1,6 +1,8 @@ error[E0308]: arguments to this function are incorrect --> $DIR/two-mismatch-notes.rs:10:5 | +LL | let w = Wrapper::(1isize); + | ------------------------ here the type of `w` is inferred to be `Wrapper` LL | foo(f, w); | ^^^ | diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 627bf05bba2d9..6e232dd006426 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -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` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index a5958baffbaf7..9f51832365b61 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -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` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 1196601ace090..ce4c8edaf74d6 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -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` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/closures/closure-return-type-mismatch.stderr b/src/test/ui/closures/closure-return-type-mismatch.stderr index 3a89d30a05d20..d33cf383cbcb4 100644 --- a/src/test/ui/closures/closure-return-type-mismatch.stderr +++ b/src/test/ui/closures/closure-return-type-mismatch.stderr @@ -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` | diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr index 1207dc7e7a2ff..d2fd0f788384e 100644 --- a/src/test/ui/coercion/coerce-to-bang.stderr +++ b/src/test/ui/coercion/coerce-to-bang.stderr @@ -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 | | diff --git a/src/test/ui/generic-associated-types/collections-project-default.stderr b/src/test/ui/generic-associated-types/collections-project-default.stderr index 5701017dc3471..c11a5acc35244 100644 --- a/src/test/ui/generic-associated-types/collections-project-default.stderr +++ b/src/test/ui/generic-associated-types/collections-project-default.stderr @@ -4,6 +4,9 @@ error[E0308]: mismatched types LL | fn floatify_sibling(ints: &C) -> >::Sibling | ------------------------------------ expected `>::Sibling` because of return type ... +LL | let mut res = ::Member::::empty(); + | ------------------------------------------------------- here the type of `res` is inferred to be `<>::Family as CollectionFamily>::Member` +... LL | res | ^^^ expected Collection::Sibling, found CollectionFamily::Member | diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr index 660dfe9ed3d51..74a7c5de7abe2 100644 --- a/src/test/ui/issues/issue-15783.stderr +++ b/src/test/ui/issues/issue-15783.stderr @@ -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]` | | diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr index 56b9e073330a6..39b57ceb43d37 100644 --- a/src/test/ui/let-else/let-else-ref-bindings.stderr +++ b/src/test/ui/let-else/let-else-ref-bindings.stderr @@ -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>` +... 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>` +... LL | let Some(a): Option<&mut [u8]> = some else { return }; | ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec` | | diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 82addab94792a..1d836f2001272 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -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` | | diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index ff1a836c9aec0..8fd3239e8ee2c 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -53,11 +53,19 @@ LL | Ok(Foo { bar: 1 }) error[E0308]: mismatched types --> $DIR/abridged.rs:39:5 | -LL | fn d() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -... -LL | x - | ^ expected struct `String`, found integer +LL | fn d() -> X, String> { + | ---------------------------- expected `X, 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, String>` found struct `X, {integer}>` @@ -65,11 +73,19 @@ LL | x error[E0308]: mismatched types --> $DIR/abridged.rs:50:5 | -LL | fn e() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -... -LL | x - | ^ expected struct `String`, found integer +LL | fn e() -> X, String> { + | ---------------------------- expected `X, 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, _>` found struct `X, _>` diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr index 9f0c0074d674c..97cdd130d0bec 100644 --- a/src/test/ui/parser/struct-literal-variant-in-if.stderr +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -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 } {} | ---------------^^^^^-- | | | diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index 498a112fa9bb3..1785c31cfb948 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -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` +... 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` +... LL | let Some(n) = opt && let another = n else { | ^^^ expected `bool`, found enum `Option` | diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index db784d5fe6cfc..75d460d7d8ca9 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -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) diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index aee1530851773..30e248f381c67 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -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) diff --git a/src/test/ui/structs/struct-base-wrong-type.stderr b/src/test/ui/structs/struct-base-wrong-type.stderr index b039ce2cc9209..30feb9cdd70c1 100644 --- a/src/test/ui/structs/struct-base-wrong-type.stderr +++ b/src/test/ui/structs/struct-base-wrong-type.stderr @@ -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` diff --git a/src/test/ui/suggestions/call-boxed.stderr b/src/test/ui/suggestions/call-boxed.stderr index 9b619ac9a3f50..8295e010f400e 100644 --- a/src/test/ui/suggestions/call-boxed.stderr +++ b/src/test/ui/suggestions/call-boxed.stderr @@ -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` | diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 5dc4e64446fb2..2546f2515d749 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -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) diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr index 8c9a41a202767..388d8d8d895e3 100644 --- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr +++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr @@ -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 | | diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr index 0ee44921bf5f8..cfeaa00d1ec98 100644 --- a/src/test/ui/traits/issue-52893.stderr +++ b/src/test/ui/traits/issue-52893.stderr @@ -4,6 +4,8 @@ error[E0308]: mismatched types LL | impl AddClass for Class

| - this type parameter ... +LL | let output = builder.to_ref(); + | ---------------- here the type of `output` is inferred to be `Class

` LL | builder.push(output); | ---- ^^^^^^ expected type parameter `F`, found struct `Class` | | diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr index fe3712ef83917..ccffb600d472c 100644 --- a/src/test/ui/tuple/wrong_argument_ice-3.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr @@ -1,6 +1,9 @@ error[E0061]: this function 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 | diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index 9f4558adab150..fb11d6160bbaa 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -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` | | diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index fcafd315ebf54..e99d30d339631 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -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` | |