Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two consecutive if lets cannot be used as function result #54186

Closed
hellow554 opened this issue Sep 13, 2018 · 4 comments · Fixed by #60188 or #74650
Closed

Two consecutive if lets cannot be used as function result #54186

hellow554 opened this issue Sep 13, 2018 · 4 comments · Fixed by #60188 or #74650
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@hellow554
Copy link
Contributor

hellow554 commented Sep 13, 2018

MCVE

fn nowork(a: Option<u32>, b: Option<u32>) -> bool {
    if let Some(x) = a { true } else { false }
    &&
    if let Some(y) = a { true } else { false }
}

fn work(a: Option<u32>, b: Option<u32>) -> bool {
    let z = if let Some(x) = a { true } else { false }
    &&
    if let Some(y) = a { true } else { false };
    z
}

Error:

error[E0308]: mismatched types
 --> src/main.rs:2:26
  |
2 |     if let Some(x) = a { true } else { false }
  |                          ^^^^ expected (), found bool
  |
  = note: expected type `()`
             found type `bool`

error[E0308]: mismatched types
 --> src/main.rs:2:40
  |
2 |     if let Some(x) = a { true } else { false }
  |                                        ^^^^^ expected (), found bool
  |
  = note: expected type `()`
             found type `bool`

error[E0308]: mismatched types
 --> src/main.rs:3:5
  |
1 |   fn nowork(a: Option<u32>, b: Option<u32>) -> bool {
  |                                                ---- expected `bool` because of return type
2 |       if let Some(x) = a { true } else { false }
3 | /     &&
4 | |     if let Some(y) = a { true } else { false }
  | |______________________________________________^ expected bool, found &&bool
  |
  = note: expected type `bool`
             found type `&&bool`

Am I missing something? Why is the first one not allowed, but the second one?

@Havvy
Copy link
Contributor

Havvy commented Sep 13, 2018

The key thing to note here is ^ expected bool, found &&bool. It's not anding your if-lets together, but instead ending the statement at the close of the else. You can fix this by using parenthesis:

https://play.rust-lang.org/?gist=419f4506d17902132dfbe048d88712f4&version=stable&mode=debug&edition=2015

https://doc.rust-lang.org/reference/statements.html#expression-statements for the reason.

@estebank estebank added the A-diagnostics Area: Messages for errors, warnings, and lints label Sep 13, 2018
@hellow554
Copy link
Contributor Author

Interesting. Thanks for the two links. So it is intended and also wanted, but not gonna be "fixed"?

@Havvy
Copy link
Contributor

Havvy commented Sep 14, 2018

We can add a diagnostic for when its followed by a bin-op like that, but we're not changing the language to accept the code.

@estebank estebank added the A-parser Area: The parsing of Rust source code to an AST. label Mar 26, 2019
Centril added a commit to Centril/rust that referenced this issue May 9, 2019
Identify when a stmt could have been parsed as an expr

There are some expressions that can be parsed as a statement without
a trailing semicolon depending on the context, which can lead to
confusing errors due to the same looking code being accepted in some
places and not others. Identify these cases and suggest enclosing in
parenthesis making the parse non-ambiguous without changing the
accepted grammar.

Fix rust-lang#54186, cc rust-lang#54482, fix rust-lang#59975, fix rust-lang#47287.
@estebank estebank added D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 22, 2020
@estebank
Copy link
Contributor

Reopening because I'm reverting the change that fixed it because of #74233.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
3 participants