Rollup merge of #126455 - surechen:fix_126222, r=estebank · rust-lang/rust@ad0531a
@@ -26,10 +26,8 @@ use rustc_middle::lint::in_external_macro;
2626use rustc_middle::middle::stability::EvalResult;
2727use rustc_middle::span_bug;
2828use rustc_middle::ty::print::with_no_trimmed_paths;
29-use rustc_middle::ty::{
30-self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt,
31-Upcast,
32-};
29+use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder};
30+use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast};
3331use rustc_session::errors::ExprParenthesesNeeded;
3432use rustc_span::source_map::Spanned;
3533use rustc_span::symbol::{sym, Ident};
@@ -1111,12 +1109,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11111109self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
11121110)
11131111{
1114- err.multipart_suggestion(
1112+// When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end.
1113+// For example:
1114+// fn mismatch_types() -> i32 {
1115+// match 1 {
1116+// x => dbg!(x),
1117+// }
1118+// todo!()
1119+// }
1120+// -------------^^^^^^^-
1121+// Don't add semicolon `;` at the end of `dbg!(x)` expr
1122+fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
1123+for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
1124+match node {
1125+ hir::Node::Block(block) => {
1126+if let Some(ret) = block.expr
1127+&& ret.hir_id == expr.hir_id
1128+{
1129+continue;
1130+}
1131+}
1132+ hir::Node::Arm(arm) => {
1133+if let hir::ExprKind::Block(block, _) = arm.body.kind
1134+&& let Some(ret) = block.expr
1135+&& ret.hir_id == expr.hir_id
1136+{
1137+return true;
1138+}
1139+}
1140+ hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => {
1141+if let Some(ret) = block.expr
1142+&& ret.hir_id == expr.hir_id
1143+{
1144+continue;
1145+}
1146+}
1147+ _ => {
1148+return false;
1149+}
1150+}
1151+}
1152+1153+false
1154+}
1155+let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())];
1156+if !is_in_arm(expr, self.tcx) {
1157+ suggs.push((span.shrink_to_hi(), ";".to_string()));
1158+}
1159+ err.multipart_suggestion_verbose(
11151160"you might have meant to return this value",
1116-vec![
1117-(span.shrink_to_lo(), "return ".to_string()),
1118-(span.shrink_to_hi(), ";".to_string()),
1119-],
1161+ suggs,
11201162Applicability::MaybeIncorrect,
11211163);
11221164}