Skip to content

Commit

Permalink
For [E0308]: mismatched types, when expr is in an arm's body, not add…
Browse files Browse the repository at this point in the history
… semicolon ';' at the end of it.

fixes #126222
  • Loading branch information
surechen committed Jun 14, 2024
1 parent f3ff2f1 commit c10b1ac
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 9 deletions.
60 changes: 51 additions & 9 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::span_bug;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{
self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt,
Upcast,
};
use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder};
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
Expand Down Expand Up @@ -1125,12 +1123,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
)
{
err.multipart_suggestion(
// When the expr is in an `arm node`'s body, we shouldn't add semicolon ';' at the end.
// For example:
// fn mismatch_types() -> i32 {
// match 1 {
// x => dbg!(x),
// }
// todo!()
// }
// -------------^^^^^^^-
// Not add semicolon ';' at the end of expr 'dbg!(x)'
fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
match node {
hir::Node::Block(block) => {
if let Some(ret) = block.expr
&& ret.hir_id == expr.hir_id
{
continue;
}
}
hir::Node::Arm(arm) => {
if let hir::ExprKind::Block(block, _) = arm.body.kind
&& let Some(ret) = block.expr
&& ret.hir_id == expr.hir_id
{
return true;
}
}
hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => {
if let Some(ret) = block.expr
&& ret.hir_id == expr.hir_id
{
continue;
}
}
_ => {
return false;
}
}
}

false
}
let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())];
if !is_in_arm(expr, self.tcx) {
suggs.push((span.shrink_to_hi(), ";".to_string()));
}
err.multipart_suggestion_verbose(
"you might have meant to return this value",
vec![
(span.shrink_to_lo(), "return ".to_string()),
(span.shrink_to_hi(), ";".to_string()),
],
suggs,
Applicability::MaybeIncorrect,
);
}
Expand Down
34 changes: 34 additions & 0 deletions tests/ui/mismatched_types/mismatched-types-issue-126222.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//@ run-rustfix
#![allow(unreachable_code, dead_code)]

fn main() {
fn mismatch_types1() -> i32 {
match 1 {
x => return dbg!(x), //~ ERROR mismatched types
}
todo!()
}

fn mismatch_types2() -> i32 {
match 2 {
x => {
return dbg!(x) //~ ERROR mismatched types
}
}
todo!()
}

fn mismatch_types3() -> i32 {
match 1 {
_ => return dbg!(1) //~ ERROR mismatched types
}
todo!()
}

fn mismatch_types4() -> i32 {
match 1 {
_ => {return dbg!(1)} //~ ERROR mismatched types
}
todo!()
}
}
34 changes: 34 additions & 0 deletions tests/ui/mismatched_types/mismatched-types-issue-126222.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//@ run-rustfix
#![allow(unreachable_code, dead_code)]

fn main() {
fn mismatch_types1() -> i32 {
match 1 {
x => dbg!(x), //~ ERROR mismatched types
}
todo!()
}

fn mismatch_types2() -> i32 {
match 2 {
x => {
dbg!(x) //~ ERROR mismatched types
}
}
todo!()
}

fn mismatch_types3() -> i32 {
match 1 {
_ => dbg!(1) //~ ERROR mismatched types
}
todo!()
}

fn mismatch_types4() -> i32 {
match 1 {
_ => {dbg!(1)} //~ ERROR mismatched types
}
todo!()
}
}
51 changes: 51 additions & 0 deletions tests/ui/mismatched_types/mismatched-types-issue-126222.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
error[E0308]: mismatched types
--> $DIR/mismatched-types-issue-126222.rs:7:18
|
LL | x => dbg!(x),
| ^^^^^^^ expected `()`, found integer
|
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have meant to return this value
|
LL | x => return dbg!(x),
| ++++++

error[E0308]: mismatched types
--> $DIR/mismatched-types-issue-126222.rs:15:17
|
LL | dbg!(x)
| ^^^^^^^ expected `()`, found integer
|
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have meant to return this value
|
LL | return dbg!(x)
| ++++++

error[E0308]: mismatched types
--> $DIR/mismatched-types-issue-126222.rs:23:18
|
LL | _ => dbg!(1)
| ^^^^^^^ expected `()`, found integer
|
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have meant to return this value
|
LL | _ => return dbg!(1)
| ++++++

error[E0308]: mismatched types
--> $DIR/mismatched-types-issue-126222.rs:30:19
|
LL | _ => {dbg!(1)}
| ^^^^^^^ expected `()`, found integer
|
= note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have meant to return this value
|
LL | _ => {return dbg!(1)}
| ++++++

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0308`.

0 comments on commit c10b1ac

Please sign in to comment.