Skip to content

Commit

Permalink
Rollup merge of rust-lang#87061 - FabianWolff:issue-87051, r=oli-obk
Browse files Browse the repository at this point in the history
Do not suggest adding a semicolon after `?`

Fixes rust-lang#87051. I have only modified `report_return_mismatched_types()`, i.e. my changes only affect suggestions to add `;` for return type mismatches, but this never makes sense after `?`, because the function cannot return `()` if `?` is used (it has to return a `Result` or an `Option`), and a semicolon won't help if the expected and actual `Err` types differ, even if the expected one is `()`.
  • Loading branch information
JohnTitor authored Jul 11, 2021
2 parents f3d5fde + 9946ff2 commit 5fcefb1
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
10 changes: 7 additions & 3 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1456,11 +1456,15 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
expected.is_unit(),
pointing_at_return_type,
) {
// If the block is from an external macro, then do not suggest
// adding a semicolon, because there's nowhere to put it.
// See issue #81943.
// If the block is from an external macro or try (`?`) desugaring, then
// do not suggest adding a semicolon, because there's nowhere to put it.
// See issues #81943 and #87051.
if cond_expr.span.desugaring_kind().is_none()
&& !in_external_macro(fcx.tcx.sess, cond_expr.span)
&& !matches!(
cond_expr.kind,
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
)
{
err.span_label(cond_expr.span, "expected this to be `()`");
if expr.can_have_side_effects() {
Expand Down
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/try-operator-dont-suggest-semicolon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Regression test for #87051, where a double semicolon was erroneously
// suggested after a `?` operator.

fn main() -> Result<(), ()> {
a(|| {
b()
//~^ ERROR: mismatched types [E0308]
//~| NOTE: expected `()`, found `i32`
//~| HELP: consider using a semicolon here
})?;

// Here, we do want to suggest a semicolon:
let x = Ok(42);
if true {
//~^ NOTE: expected this to be `()`
x?
//~^ ERROR: mismatched types [E0308]
//~| NOTE: expected `()`, found integer
//~| HELP: consider using a semicolon here
}
//~^ HELP: consider using a semicolon here

Ok(())
}

fn a<F>(f: F) -> Result<(), ()> where F: FnMut() { Ok(()) }
fn b() -> i32 { 42 }
33 changes: 33 additions & 0 deletions src/test/ui/suggestions/try-operator-dont-suggest-semicolon.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0308]: mismatched types
--> $DIR/try-operator-dont-suggest-semicolon.rs:6:9
|
LL | b()
| ^^^- help: consider using a semicolon here: `;`
| |
| expected `()`, found `i32`

error[E0308]: mismatched types
--> $DIR/try-operator-dont-suggest-semicolon.rs:16:9
|
LL | / if true {
LL | |
LL | | x?
| | ^^ expected `()`, found integer
LL | |
LL | |
LL | |
LL | | }
| |_____- expected this to be `()`
|
help: consider using a semicolon here
|
LL | x?;
| ^
help: consider using a semicolon here
|
LL | };
| ^

error: aborting due to 2 previous errors

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

0 comments on commit 5fcefb1

Please sign in to comment.