From 90507295db1665b7567f66fc12ceb0b15e32d44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 20:26:00 -0800 Subject: [PATCH 1/7] Do not give incorrect label for return type mismatch --- src/librustc_typeck/check/coercion.rs | 28 ++++++++-- ...o-type-err-cause-on-impl-trait-return-2.rs | 17 ++++++ ...pe-err-cause-on-impl-trait-return-2.stderr | 12 +++++ ...-to-type-err-cause-on-impl-trait-return.rs | 36 +++++++++++++ ...type-err-cause-on-impl-trait-return.stderr | 52 +++++++++++++++++++ 5 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs create mode 100644 src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a82a0d3ce5232..d1c54f824fe9d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1224,9 +1224,31 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause.span, blk_id, ); - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - if !sp.overlaps(cause.span) { - db.span_label(*sp, reason_label); + // TODO: replace with navigating up the chain until hitting an fn or + // bailing if no "pass-through" Node is found, in order to provide a + // suggestion when encountering something like: + // ``` + // fn foo(a: bool) -> impl Debug { + // if a { + // bar()?; + // } + // { + // let x = unsafe { bar() }; + // x + // } + // } + // ``` + // + // Verify that this is a tail expression of a function, otherwise the + // label pointing out the cause for the type coercion will be wrong + // as prior return coercions would not be relevant (#57664). + let parent_id = fcx.tcx.hir().get_parent_node(blk_id); + let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); + if fcx.get_node_fn_decl(parent).is_some() { + if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { + if !sp.overlaps(cause.span) { + db.span_label(*sp, reason_label); + } } } } diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs new file mode 100644 index 0000000000000..50f1fe873cb5f --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.rs @@ -0,0 +1,17 @@ +fn unrelated() -> Result<(), std::string::ParseError> { // #57664 + let x = 0; + + match x { + 1 => { + let property_value_as_string = "a".parse()?; + } + 2 => { + let value: &bool = unsafe { &42 }; + //~^ ERROR mismatched types + } + }; + + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr new file mode 100644 index 0000000000000..edaa60e5b8d8b --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return-2.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return-2.rs:9:41 + | +LL | let value: &bool = unsafe { &42 }; + | ^^^ expected bool, found integer + | + = note: expected type `&bool` + found type `&{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs new file mode 100644 index 0000000000000..a27df240d0792 --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -0,0 +1,36 @@ +fn foo() -> impl std::fmt::Display { + if false { + return 0i32; + } + 1u32 + //~^ ERROR mismatched types +} + +fn bar() -> impl std::fmt::Display { + if false { + return 0i32; + } else { + return 1u32; + //~^ ERROR mismatched types + } +} + +fn baz() -> impl std::fmt::Display { + if false { + //~^ ERROR mismatched types + return 0i32; + } else { + 1u32 + } +} + +fn qux() -> impl std::fmt::Display { + if false { + //~^ ERROR if and else have incompatible types + 0i32 + } else { + 1u32 + } +} + +fn main() {} diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr new file mode 100644 index 0000000000000..54f7b108c3dd4 --- /dev/null +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -0,0 +1,52 @@ +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 + | +LL | return 0i32; + | ---- expected because of this statement +LL | } +LL | 1u32 + | ^^^^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 + | +LL | return 1u32; + | ^^^^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5 + | +LL | / if false { +LL | | //~^ ERROR mismatched types +LL | | return 0i32; +LL | | } else { +LL | | 1u32 +LL | | } + | |_____^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error[E0308]: if and else have incompatible types + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:5 + | +LL | / if false { +LL | | //~^ ERROR if and else have incompatible types +LL | | 0i32 +LL | | } else { +LL | | 1u32 +LL | | } + | |_____^ expected i32, found u32 + | + = note: expected type `i32` + found type `u32` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 19255dc2e670085a7bf6864feccb323077309325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 20:45:50 -0800 Subject: [PATCH 2/7] Point more places where expectation comes from --- src/librustc_typeck/check/coercion.rs | 4 +--- src/test/ui/diverging-tuple-parts-39485.stderr | 5 ++++- src/test/ui/issues/issue-10176.stderr | 5 ++++- .../ui/point-to-type-err-cause-on-impl-trait-return.stderr | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d1c54f824fe9d..28114b527933d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1246,9 +1246,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); if fcx.get_node_fn_decl(parent).is_some() { if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { - if !sp.overlaps(cause.span) { - db.span_label(*sp, reason_label); - } + db.span_label(*sp, reason_label); } } } diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index c399650d3258b..f8da9282f5fb7 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -15,7 +15,10 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^-^ + | | | + | | expected because of this statement + | expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/issues/issue-10176.stderr b/src/test/ui/issues/issue-10176.stderr index 45482447ebe2c..592c84bd17d0e 100644 --- a/src/test/ui/issues/issue-10176.stderr +++ b/src/test/ui/issues/issue-10176.stderr @@ -4,7 +4,10 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) - | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^-^ + | | | + | | expected because of this statement + | expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 54f7b108c3dd4..b94a9f4df4875 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -25,6 +25,7 @@ error[E0308]: mismatched types LL | / if false { LL | | //~^ ERROR mismatched types LL | | return 0i32; + | | ---- expected because of this statement LL | | } else { LL | | 1u32 LL | | } From c4318502bca669f399b7428d3e9a180b1de041bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:06:09 -0800 Subject: [PATCH 3/7] Avoid pointing at multiple places on return type error --- src/librustc_typeck/check/coercion.rs | 4 +-- src/librustc_typeck/check/mod.rs | 28 +++++++++++++------ .../ui/diverging-tuple-parts-39485.stderr | 5 +--- src/test/ui/issues/issue-10176.stderr | 5 +--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 28114b527933d..f040781e56f7c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1216,7 +1216,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> "supposed to be part of a block tail expression, but the \ expression is empty"); }); - fcx.suggest_mismatched_types_on_tail( + let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail( &mut db, expr, expected, @@ -1244,7 +1244,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> // as prior return coercions would not be relevant (#57664). let parent_id = fcx.tcx.hir().get_parent_node(blk_id); let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id)); - if fcx.get_node_fn_decl(parent).is_some() { + if fcx.get_node_fn_decl(parent).is_some() && !pointing_at_return_type { if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { db.span_label(*sp, reason_label); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1b07385d4d1f4..ce876a799644a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5089,12 +5089,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { found: Ty<'tcx>, cause_span: Span, blk_id: ast::NodeId, - ) { + ) -> bool { self.suggest_missing_semicolon(err, expression, expected, cause_span); + let mut pointing_at_return_type = false; if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { - self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); + pointing_at_return_type = self.suggest_missing_return_type( + err, &fn_decl, expected, found, can_suggest); } self.suggest_ref_or_into(err, expression, expected, found); + pointing_at_return_type } pub fn suggest_ref_or_into( @@ -5193,12 +5196,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// This routine checks if the return type is left as default, the method is not part of an /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return /// type. - fn suggest_missing_return_type(&self, - err: &mut DiagnosticBuilder<'tcx>, - fn_decl: &hir::FnDecl, - expected: Ty<'tcx>, - found: Ty<'tcx>, - can_suggest: bool) { + fn suggest_missing_return_type( + &self, + err: &mut DiagnosticBuilder<'tcx>, + fn_decl: &hir::FnDecl, + expected: Ty<'tcx>, + found: Ty<'tcx>, + can_suggest: bool, + ) -> bool { // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) { @@ -5208,16 +5213,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "try adding a return type", format!("-> {} ", self.resolve_type_vars_with_obligations(found)), Applicability::MachineApplicable); + true } (&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => { err.span_label(span, "possibly return type missing here?"); + true } (&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => { // `fn main()` must return `()`, do not suggest changing return type err.span_label(span, "expected `()` because of default return type"); + true } // expectation was caused by something else, not the default return - (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => {} + (&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false, (&hir::FunctionRetTy::Return(ref ty), _, _, _) => { // Only point to return type if the expected type is the return type, as if they // are not, the expectation must have been caused by something else. @@ -5229,7 +5237,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if ty.sty == expected.sty { err.span_label(sp, format!("expected `{}` because of return type", expected)); + return true; } + false } } } diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr index f8da9282f5fb7..c399650d3258b 100644 --- a/src/test/ui/diverging-tuple-parts-39485.stderr +++ b/src/test/ui/diverging-tuple-parts-39485.stderr @@ -15,10 +15,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^-^ - | | | - | | expected because of this statement - | expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple | = note: expected type `isize` found type `(!, !)` diff --git a/src/test/ui/issues/issue-10176.stderr b/src/test/ui/issues/issue-10176.stderr index 592c84bd17d0e..45482447ebe2c 100644 --- a/src/test/ui/issues/issue-10176.stderr +++ b/src/test/ui/issues/issue-10176.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { | ----- expected `isize` because of return type LL | (return 1, return 2) - | ^^^^^^^^^^^^^^^^^^-^ - | | | - | | expected because of this statement - | expected isize, found tuple + | ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple | = note: expected type `isize` found type `(!, !)` From 9b8243ac2450c49f95cfbee517109ce13d00f95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 21:18:51 -0800 Subject: [PATCH 4/7] Point at more cases involving return types --- src/librustc_typeck/check/mod.rs | 8 ++++++-- .../point-to-type-err-cause-on-impl-trait-return.stderr | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ce876a799644a..7b9b97ff065a6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4347,11 +4347,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { struct_span_err!(self.tcx.sess, expr.span, E0572, "return statement outside of function body").emit(); } else if let Some(ref e) = *expr_opt { - *self.ret_coercion_span.borrow_mut() = Some(e.span); + if self.ret_coercion_span.borrow().is_none() { + *self.ret_coercion_span.borrow_mut() = Some(e.span); + } self.check_return_expr(e); } else { let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut(); - *self.ret_coercion_span.borrow_mut() = Some(expr.span); + if self.ret_coercion_span.borrow().is_none() { + *self.ret_coercion_span.borrow_mut() = Some(expr.span); + } let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression); if let Some((fn_decl, _)) = self.get_fn_decl(expr.id) { coercion.coerce_forced_unit( diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index b94a9f4df4875..be3d2c0db4ca1 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -13,6 +13,9 @@ LL | 1u32 error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 | +LL | return 0i32; + | ---- expected because of this statement +LL | } else { LL | return 1u32; | ^^^^ expected i32, found u32 | From fbb072837dbbaf30a1e81674b457e5ea816dbca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 22:32:59 -0800 Subject: [PATCH 5/7] Fix tidy error --- src/librustc_typeck/check/coercion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index f040781e56f7c..7f053d6af9611 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1224,7 +1224,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause.span, blk_id, ); - // TODO: replace with navigating up the chain until hitting an fn or + // FIXME: replace with navigating up the chain until hitting an fn or // bailing if no "pass-through" Node is found, in order to provide a // suggestion when encountering something like: // ``` From 954769e2ed16a90bfda2b69395fc099b93581352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Jan 2019 22:51:01 -0800 Subject: [PATCH 6/7] Fix test after rebase --- .../ui/point-to-type-err-cause-on-impl-trait-return.rs | 2 +- .../point-to-type-err-cause-on-impl-trait-return.stderr | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs index a27df240d0792..95b40368143ef 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -26,10 +26,10 @@ fn baz() -> impl std::fmt::Display { fn qux() -> impl std::fmt::Display { if false { - //~^ ERROR if and else have incompatible types 0i32 } else { 1u32 + //~^ ERROR if and else have incompatible types } } diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index be3d2c0db4ca1..62da0787b02a9 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -38,15 +38,17 @@ LL | | } found type `u32` error[E0308]: if and else have incompatible types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:5 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 | LL | / if false { -LL | | //~^ ERROR if and else have incompatible types LL | | 0i32 + | | ---- expected because of this LL | | } else { LL | | 1u32 + | | ^^^^ expected i32, found u32 +LL | | //~^ ERROR if and else have incompatible types LL | | } - | |_____^ expected i32, found u32 + | |_____- if and else have incompatible types | = note: expected type `i32` found type `u32` From 2e06d9c91b9f0bccde4a0e445ce2014c3fe85506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 18 Jan 2019 00:12:09 -0800 Subject: [PATCH 7/7] Point at return type when appropriate --- src/librustc_typeck/check/coercion.rs | 16 ++++++++++++++-- .../fully-qualified-type-name2.stderr | 2 ++ .../fully-qualified-type-name4.stderr | 2 ++ src/test/ui/liveness/liveness-forgot-ret.stderr | 2 +- src/test/ui/proc-macro/span-preservation.stderr | 3 +++ src/test/ui/return/return-from-diverging.stderr | 2 ++ src/test/ui/tail-typeck.stderr | 4 +++- src/test/ui/wrong-ret-type.stderr | 4 +++- 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 7f053d6af9611..dd63b4f20fa55 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1250,14 +1250,26 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> } } } - _ => { + ObligationCauseCode::ReturnType(_id) => { db = fcx.report_mismatched_types(cause, expected, found, err); - if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() { + let _id = fcx.tcx.hir().get_parent_node(_id); + let mut pointing_at_return_type = false; + if let Some((fn_decl, can_suggest)) = fcx.get_fn_decl(_id) { + pointing_at_return_type = fcx.suggest_missing_return_type( + &mut db, &fn_decl, expected, found, can_suggest); + } + if let (Some(sp), false) = ( + fcx.ret_coercion_span.borrow().as_ref(), + pointing_at_return_type, + ) { if !sp.overlaps(cause.span) { db.span_label(*sp, reason_label); } } } + _ => { + db = fcx.report_mismatched_types(cause, expected, found, err); + } } if let Some(augment_error) = augment_error { diff --git a/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr b/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr index 9a33d29766fb9..47bb5e475b473 100644 --- a/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr +++ b/src/test/ui/fully-qualified-type/fully-qualified-type-name2.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/fully-qualified-type-name2.rs:12:12 | +LL | fn bar(x: x::Foo) -> y::Foo { + | ------ expected `y::Foo` because of return type LL | return x; | ^ expected enum `y::Foo`, found enum `x::Foo` | diff --git a/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr b/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr index f03aaa67edbb8..b341879ab919a 100644 --- a/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr +++ b/src/test/ui/fully-qualified-type/fully-qualified-type-name4.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/fully-qualified-type-name4.rs:6:12 | +LL | fn bar(x: usize) -> Option { + | ------------- expected `std::option::Option` because of return type LL | return x; | ^ expected enum `std::option::Option`, found usize | diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr index bbcbbdbe8dd5b..a970b80fdbbd9 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/liveness-forgot-ret.rs:3:19 | LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } - | - ^^^^^ expected isize, found () - expected because of this statement + | - ^^^^^ expected isize, found () | | | this function's body doesn't return | diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr index 1f9103a6d2ee8..db524907b656f 100644 --- a/src/test/ui/proc-macro/span-preservation.stderr +++ b/src/test/ui/proc-macro/span-preservation.stderr @@ -15,6 +15,9 @@ LL | let x: usize = "hello";;;;; //~ ERROR mismatched types error[E0308]: mismatched types --> $DIR/span-preservation.rs:19:29 | +LL | fn b(x: Option) -> usize { + | ----- expected `usize` because of return type +LL | match x { LL | Some(x) => { return x }, //~ ERROR mismatched types | ^ expected usize, found isize diff --git a/src/test/ui/return/return-from-diverging.stderr b/src/test/ui/return/return-from-diverging.stderr index c84dd1953a07b..2862ae641df15 100644 --- a/src/test/ui/return/return-from-diverging.stderr +++ b/src/test/ui/return/return-from-diverging.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/return-from-diverging.rs:4:12 | +LL | fn fail() -> ! { + | - expected `!` because of return type LL | return "wow"; //~ ERROR mismatched types | ^^^^^ expected !, found reference | diff --git a/src/test/ui/tail-typeck.stderr b/src/test/ui/tail-typeck.stderr index eadf3d6d3350e..1170f5c17c18a 100644 --- a/src/test/ui/tail-typeck.stderr +++ b/src/test/ui/tail-typeck.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/tail-typeck.rs:3:26 | LL | fn f() -> isize { return g(); } - | ^^^ expected isize, found usize + | ----- ^^^ expected isize, found usize + | | + | expected `isize` because of return type error: aborting due to previous error diff --git a/src/test/ui/wrong-ret-type.stderr b/src/test/ui/wrong-ret-type.stderr index 221806f731f60..cf59f42683d72 100644 --- a/src/test/ui/wrong-ret-type.stderr +++ b/src/test/ui/wrong-ret-type.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/wrong-ret-type.rs:2:49 | LL | fn mk_int() -> usize { let i: isize = 3; return i; } - | ^ expected usize, found isize + | ----- ^ expected usize, found isize + | | + | expected `usize` because of return type error: aborting due to previous error