Rollup merge of #126455 - surechen:fix_126222, r=estebank

For [E0308]: mismatched types, when expr is in an arm's body, not add semicolon ';' at the end of it.

For [E0308]: mismatched types, when expr is in an arm's body, and it is the end expr without a semicolon of the block, not add semicolon ';' at the end of it.

fixes #126222

<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r​? <reviewer name>
-->
This commit is contained in:
Matthias Krüger 2024-06-24 06:27:13 +02:00 committed by GitHub
commit ad0531ae0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 170 additions and 9 deletions

View File

@ -26,10 +26,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};
@ -1111,12 +1109,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 a match arm's body, we shouldn't add semicolon ';' at the end.
// For example:
// fn mismatch_types() -> i32 {
// match 1 {
// x => dbg!(x),
// }
// todo!()
// }
// -------------^^^^^^^-
// Don't add semicolon `;` at the end of `dbg!(x)` expr
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,
);
}

View File

@ -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!()
}
}

View File

@ -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!()
}
}

View File

@ -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`.