From af90cac0e15de4479c8880f6ab80194a8d2b7291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Fri, 16 Apr 2021 17:04:15 +0200 Subject: [PATCH] fix reporting return type in some cases --- compiler/rustc_typeck/src/check/coercion.rs | 22 ---------------- compiler/rustc_typeck/src/check/demand.rs | 29 +++++++++++++++++++++ src/test/ui/closures/issue-84128.rs | 16 ++++++++++++ src/test/ui/closures/issue-84128.stderr | 15 +++++++++++ 4 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/closures/issue-84128.rs create mode 100644 src/test/ui/closures/issue-84128.stderr diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 37538267b866a..fd7c50e978800 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1492,28 +1492,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) { self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output); } - - if let Some(sp) = fcx.ret_coercion_span.get() { - // If the closure has an explicit return type annotation, - // then a type error may occur at the first return expression we - // see in the closure (if it conflicts with the declared - // return type). Skip adding a note in this case, since it - // would be incorrect. - if !err.span.primary_spans().iter().any(|&span| span == sp) { - let hir = fcx.tcx.hir(); - let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id)); - if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) { - err.span_note( - sp, - &format!( - "return type inferred to be `{}` here", - fcx.resolve_vars_if_possible(expected) - ), - ); - } - } - } - err } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index d879b6e97dcfb..e5fcdcfa74315 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -37,6 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_missing_parentheses(err, expr); self.note_need_for_fn_pointer(err, expected, expr_ty); self.note_internal_mutation_in_method(err, expr, expected, expr_ty); + self.report_closure_infered_return_type(err, expected) } // Requires that the two types unify, and prints an error message if @@ -1061,4 +1062,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => false, } } + + // Report the type inferred by the return statement. + fn report_closure_infered_return_type( + &self, + err: &mut DiagnosticBuilder<'_>, + expected: Ty<'tcx>, + ) { + if let Some(sp) = self.ret_coercion_span.get() { + // If the closure has an explicit return type annotation, + // then a type error may occur at the first return expression we + // see in the closure (if it conflicts with the declared + // return type). Skip adding a note in this case, since it + // would be incorrect. + if !err.span.primary_spans().iter().any(|&span| span == sp) { + let hir = self.tcx.hir(); + let body_owner = hir.body_owned_by(hir.enclosing_body_owner(self.body_id)); + if self.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) { + err.span_note( + sp, + &format!( + "return type inferred to be `{}` here", + self.resolve_vars_if_possible(expected) + ), + ); + } + } + } + } } diff --git a/src/test/ui/closures/issue-84128.rs b/src/test/ui/closures/issue-84128.rs new file mode 100644 index 0000000000000..f81d7cfaa654b --- /dev/null +++ b/src/test/ui/closures/issue-84128.rs @@ -0,0 +1,16 @@ +// test for issue 84128 +// missing suggestion for similar ADT type with diffetent generic paramenter +// on closure ReturnNoExpression + +struct Foo(T); + +fn main() { + || { + if false { + return Foo(0); + } + + Foo(()) + //~^ ERROR mismatched types [E0308] + }; +} diff --git a/src/test/ui/closures/issue-84128.stderr b/src/test/ui/closures/issue-84128.stderr new file mode 100644 index 0000000000000..70d9273ddf7ce --- /dev/null +++ b/src/test/ui/closures/issue-84128.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-84128.rs:13:13 + | +LL | Foo(()) + | ^^ expected integer, found `()` + | +note: return type inferred to be `{integer}` here + --> $DIR/issue-84128.rs:10:20 + | +LL | return Foo(0); + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.