mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Rollup merge of #99974 - TaKO8Ki:suggest-removing-semicolon-and-boxing-the-expressions, r=compiler-errors
Suggest removing a semicolon and boxing the expressions for if-else `InferCtxt::suggest_remove_semi_or_return_binding` was not working well, so I fixed it and added a ui test.
This commit is contained in:
commit
990bce4da0
@ -712,7 +712,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
opt_suggest_box_span,
|
||||
}) => {
|
||||
let then_span = self.find_block_span_from_hir_id(then_id);
|
||||
let else_span = self.find_block_span_from_hir_id(then_id);
|
||||
let else_span = self.find_block_span_from_hir_id(else_id);
|
||||
err.span_label(then_span, "expected because of this");
|
||||
if let Some(sp) = outer_span {
|
||||
err.span_label(sp, "`if` and `else` have incompatible types");
|
||||
@ -760,11 +760,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
second_ty: Ty<'tcx>,
|
||||
second_span: Span,
|
||||
) {
|
||||
let remove_semicolon =
|
||||
[(first_id, second_ty), (second_id, first_ty)].into_iter().find_map(|(id, ty)| {
|
||||
let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None };
|
||||
self.could_remove_semicolon(blk, ty)
|
||||
});
|
||||
let remove_semicolon = [
|
||||
(first_id, self.resolve_vars_if_possible(second_ty)),
|
||||
(second_id, self.resolve_vars_if_possible(first_ty)),
|
||||
]
|
||||
.into_iter()
|
||||
.find_map(|(id, ty)| {
|
||||
let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None };
|
||||
self.could_remove_semicolon(blk, ty)
|
||||
});
|
||||
match remove_semicolon {
|
||||
Some((sp, StatementAsExpression::NeedsBoxing)) => {
|
||||
err.multipart_suggestion(
|
||||
|
70
src/test/ui/suggestions/if-then-neeing-semi.rs
Normal file
70
src/test/ui/suggestions/if-then-neeing-semi.rs
Normal file
@ -0,0 +1,70 @@
|
||||
// edition:2018
|
||||
|
||||
fn dummy() -> i32 {
|
||||
42
|
||||
}
|
||||
|
||||
fn extra_semicolon() {
|
||||
let _ = if true {
|
||||
//~^ NOTE `if` and `else` have incompatible types
|
||||
dummy(); //~ NOTE expected because of this
|
||||
//~^ HELP consider removing this semicolon
|
||||
} else {
|
||||
dummy() //~ ERROR `if` and `else` have incompatible types
|
||||
//~^ NOTE expected `()`, found `i32`
|
||||
};
|
||||
}
|
||||
|
||||
async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
|
||||
//~| NOTE while checking the return type of the `async fn`
|
||||
//~| NOTE in this expansion of desugaring of `async` block or function
|
||||
//~| NOTE checked the `Output` of this `async fn`, expected opaque type
|
||||
//~| NOTE while checking the return type of the `async fn`
|
||||
//~| NOTE in this expansion of desugaring of `async` block or function
|
||||
async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
|
||||
//~| NOTE checked the `Output` of this `async fn`, found opaque type
|
||||
//~| NOTE while checking the return type of the `async fn`
|
||||
//~| NOTE in this expansion of desugaring of `async` block or function
|
||||
//~| NOTE while checking the return type of the `async fn`
|
||||
//~| NOTE in this expansion of desugaring of `async` block or function
|
||||
|
||||
async fn async_extra_semicolon_same() {
|
||||
let _ = if true {
|
||||
//~^ NOTE `if` and `else` have incompatible types
|
||||
async_dummy(); //~ NOTE expected because of this
|
||||
//~^ HELP consider removing this semicolon
|
||||
} else {
|
||||
async_dummy() //~ ERROR `if` and `else` have incompatible types
|
||||
//~^ NOTE expected `()`, found opaque type
|
||||
//~| NOTE expected unit type `()`
|
||||
//~| HELP consider `await`ing on the `Future`
|
||||
};
|
||||
}
|
||||
|
||||
async fn async_extra_semicolon_different() {
|
||||
let _ = if true {
|
||||
//~^ NOTE `if` and `else` have incompatible types
|
||||
async_dummy(); //~ NOTE expected because of this
|
||||
//~^ HELP consider removing this semicolon
|
||||
} else {
|
||||
async_dummy2() //~ ERROR `if` and `else` have incompatible types
|
||||
//~^ NOTE expected `()`, found opaque type
|
||||
//~| NOTE expected unit type `()`
|
||||
//~| HELP consider `await`ing on the `Future`
|
||||
};
|
||||
}
|
||||
|
||||
async fn async_different_futures() {
|
||||
let _ = if true {
|
||||
//~^ NOTE `if` and `else` have incompatible types
|
||||
async_dummy() //~ NOTE expected because of this
|
||||
//~| HELP consider `await`ing on both `Future`s
|
||||
} else {
|
||||
async_dummy2() //~ ERROR `if` and `else` have incompatible types
|
||||
//~^ NOTE expected opaque type, found a different opaque type
|
||||
//~| NOTE expected opaque type `impl Future<Output = ()>`
|
||||
//~| NOTE distinct uses of `impl Trait` result in different opaque types
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
130
src/test/ui/suggestions/if-then-neeing-semi.stderr
Normal file
130
src/test/ui/suggestions/if-then-neeing-semi.stderr
Normal file
@ -0,0 +1,130 @@
|
||||
error[E0308]: `if` and `else` have incompatible types
|
||||
--> $DIR/if-then-neeing-semi.rs:37:9
|
||||
|
|
||||
LL | let _ = if true {
|
||||
| _____________-
|
||||
LL | |
|
||||
LL | | async_dummy();
|
||||
| | -------------- expected because of this
|
||||
LL | |
|
||||
LL | | } else {
|
||||
LL | | async_dummy()
|
||||
| | ^^^^^^^^^^^^^ expected `()`, found opaque type
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____- `if` and `else` have incompatible types
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/if-then-neeing-semi.rs:18:24
|
||||
|
|
||||
LL | async fn async_dummy() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected unit type `()`
|
||||
found opaque type `impl Future<Output = ()>`
|
||||
help: consider `await`ing on the `Future`
|
||||
|
|
||||
LL | async_dummy().await
|
||||
| ++++++
|
||||
help: consider removing this semicolon
|
||||
|
|
||||
LL - async_dummy();
|
||||
LL + async_dummy()
|
||||
|
|
||||
|
||||
error[E0308]: `if` and `else` have incompatible types
|
||||
--> $DIR/if-then-neeing-semi.rs:50:9
|
||||
|
|
||||
LL | let _ = if true {
|
||||
| _____________-
|
||||
LL | |
|
||||
LL | | async_dummy();
|
||||
| | -------------- expected because of this
|
||||
LL | |
|
||||
LL | | } else {
|
||||
LL | | async_dummy2()
|
||||
| | ^^^^^^^^^^^^^^ expected `()`, found opaque type
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____- `if` and `else` have incompatible types
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/if-then-neeing-semi.rs:24:25
|
||||
|
|
||||
LL | async fn async_dummy2() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected unit type `()`
|
||||
found opaque type `impl Future<Output = ()>`
|
||||
help: consider `await`ing on the `Future`
|
||||
|
|
||||
LL | async_dummy2().await
|
||||
| ++++++
|
||||
help: consider removing this semicolon and boxing the expressions
|
||||
|
|
||||
LL ~ Box::new(async_dummy())
|
||||
LL |
|
||||
LL | } else {
|
||||
LL ~ Box::new(async_dummy2())
|
||||
|
|
||||
|
||||
error[E0308]: `if` and `else` have incompatible types
|
||||
--> $DIR/if-then-neeing-semi.rs:63:9
|
||||
|
|
||||
LL | let _ = if true {
|
||||
| _____________-
|
||||
LL | |
|
||||
LL | | async_dummy()
|
||||
| | ------------- expected because of this
|
||||
LL | |
|
||||
LL | | } else {
|
||||
LL | | async_dummy2()
|
||||
| | ^^^^^^^^^^^^^^ expected opaque type, found a different opaque type
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____- `if` and `else` have incompatible types
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/if-then-neeing-semi.rs:18:24
|
||||
|
|
||||
LL | async fn async_dummy() {}
|
||||
| ^ checked the `Output` of this `async fn`, expected opaque type
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/if-then-neeing-semi.rs:24:25
|
||||
|
|
||||
LL | async fn async_dummy2() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:18:24>)
|
||||
found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/if-then-neeing-semi.rs:24:25>)
|
||||
= note: distinct uses of `impl Trait` result in different opaque types
|
||||
help: consider `await`ing on both `Future`s
|
||||
|
|
||||
LL ~ async_dummy().await
|
||||
LL |
|
||||
LL | } else {
|
||||
LL ~ async_dummy2().await
|
||||
|
|
||||
|
||||
error[E0308]: `if` and `else` have incompatible types
|
||||
--> $DIR/if-then-neeing-semi.rs:13:9
|
||||
|
|
||||
LL | let _ = if true {
|
||||
| _____________-
|
||||
LL | |
|
||||
LL | | dummy();
|
||||
| | --------
|
||||
| | | |
|
||||
| | | help: consider removing this semicolon
|
||||
| | expected because of this
|
||||
LL | |
|
||||
LL | | } else {
|
||||
LL | | dummy()
|
||||
| | ^^^^^^^ expected `()`, found `i32`
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____- `if` and `else` have incompatible types
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user