diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index a0465ca6aef07..909b84e7aa808 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -393,12 +393,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Block(..) => { - err.span_suggestion( - cause_span.shrink_to_hi(), - "try adding a semicolon", - ";".to_string(), - Applicability::MachineApplicable, - ); + self.suggest_return_or_semicolon(err, expression, cause_span); } _ => (), } @@ -475,4 +470,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None); } } + + pub(in super::super) fn suggest_return_or_semicolon( + &self, + err: &mut DiagnosticBuilder<'_>, + expression: &'tcx hir::Expr<'tcx>, + cause_span: Span, + ) { + if let Some(ref ret_coercion) = self.ret_coercion { + let ret_ty = ret_coercion.borrow().expected_ty(); + let return_expr_ty = self.check_expr_with_hint(expression, ret_ty.clone()); + if self.can_coerce(return_expr_ty, ret_ty) { + err.span_suggestion_short( + cause_span.shrink_to_lo(), + "try adding return", + "return ".to_string(), + Applicability::MachineApplicable, + ); + return; + } + } + err.span_suggestion( + cause_span.shrink_to_hi(), + "try adding a semicolon", + ";".to_string(), + Applicability::MachineApplicable, + ); + } } diff --git a/src/test/ui/typeck/issue-52284.rs b/src/test/ui/typeck/issue-52284.rs new file mode 100644 index 0000000000000..1623282278d93 --- /dev/null +++ b/src/test/ui/typeck/issue-52284.rs @@ -0,0 +1,14 @@ +struct Alef(); +struct Bet(); +fn gimel() -> Alef { + if true { + Alef() //~ERROR + } + if true { + Bet() //~ERROR + } + Alef() +} +fn main() { + gimel(); +} diff --git a/src/test/ui/typeck/issue-52284.stderr b/src/test/ui/typeck/issue-52284.stderr new file mode 100644 index 0000000000000..724c8e388b979 --- /dev/null +++ b/src/test/ui/typeck/issue-52284.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/issue-52284.rs:5:5 + | +LL | / if true { +LL | | Alef() + | | ^^^^^^ expected `()`, found struct `Alef` +LL | | } + | |___- expected this to be `()` + | +help: try adding return + | +LL | return Alef() + | ^^^^^^ +help: consider using a semicolon here + | +LL | }; + | ^ + +error[E0308]: mismatched types + --> $DIR/issue-52284.rs:8:5 + | +LL | / if true { +LL | | Bet() + | | ^^^^^ expected `()`, found struct `Bet` +LL | | } + | |___- expected this to be `()` + | +help: try adding a semicolon + | +LL | Bet(); + | ^ +help: consider using a semicolon here + | +LL | }; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.