For [E0308]: mismatched types, when expr is in an arm's body, not add… · rust-lang/rust@e8b5ba1
@@ -27,10 +27,8 @@ use rustc_middle::lint::in_external_macro;
2727use rustc_middle::middle::stability::EvalResult;
2828use rustc_middle::span_bug;
2929use rustc_middle::ty::print::with_no_trimmed_paths;
30-use rustc_middle::ty::{
31-self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt,
32-Upcast,
33-};
30+use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder};
31+use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast};
3432use rustc_session::errors::ExprParenthesesNeeded;
3533use rustc_span::source_map::Spanned;
3634use rustc_span::symbol::{sym, Ident};
@@ -1125,12 +1123,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11251123self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
11261124)
11271125{
1128- err.multipart_suggestion(
1126+// When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end.
1127+// For example:
1128+// fn mismatch_types() -> i32 {
1129+// match 1 {
1130+// x => dbg!(x),
1131+// }
1132+// todo!()
1133+// }
1134+// -------------^^^^^^^-
1135+// Don't add semicolon `;` at the end of `dbg!(x)` expr
1136+fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
1137+for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
1138+match node {
1139+ hir::Node::Block(block) => {
1140+if let Some(ret) = block.expr
1141+&& ret.hir_id == expr.hir_id
1142+{
1143+continue;
1144+}
1145+}
1146+ hir::Node::Arm(arm) => {
1147+if let hir::ExprKind::Block(block, _) = arm.body.kind
1148+&& let Some(ret) = block.expr
1149+&& ret.hir_id == expr.hir_id
1150+{
1151+return true;
1152+}
1153+}
1154+ hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => {
1155+if let Some(ret) = block.expr
1156+&& ret.hir_id == expr.hir_id
1157+{
1158+continue;
1159+}
1160+}
1161+ _ => {
1162+return false;
1163+}
1164+}
1165+}
1166+1167+false
1168+}
1169+let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())];
1170+if !is_in_arm(expr, self.tcx) {
1171+ suggs.push((span.shrink_to_hi(), ";".to_string()));
1172+}
1173+ err.multipart_suggestion_verbose(
11291174"you might have meant to return this value",
1130-vec![
1131-(span.shrink_to_lo(), "return ".to_string()),
1132-(span.shrink_to_hi(), ";".to_string()),
1133-],
1175+ suggs,
11341176Applicability::MaybeIncorrect,
11351177);
11361178}