For [E0308]: mismatched types, when expr is in an arm's body, not add… · rust-lang/rust@e8b5ba1 (original) (raw)
`@@ -27,10 +27,8 @@ use rustc_middle::lint::in_external_macro;
`
27
27
`use rustc_middle::middle::stability::EvalResult;
`
28
28
`use rustc_middle::span_bug;
`
29
29
`use 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};
`
34
32
`use rustc_session::errors::ExprParenthesesNeeded;
`
35
33
`use rustc_span::source_map::Spanned;
`
36
34
`use rustc_span::symbol::{sym, Ident};
`
`@@ -1125,12 +1123,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
`
1125
1123
`self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
`
1126
1124
`)
`
1127
1125
`{
`
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(
`
1129
1174
`"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,
`
1134
1176
`Applicability::MaybeIncorrect,
`
1135
1177
`);
`
1136
1178
`}
`