Skip to content

try_block cannot be used everywhere an expression can #56828

New issue

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

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

Already on GitHub? # to your account

Closed
rodrigorc opened this issue Dec 14, 2018 · 5 comments · Fixed by #70657
Closed

try_block cannot be used everywhere an expression can #56828

rodrigorc opened this issue Dec 14, 2018 · 5 comments · Fixed by #70657
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST C-bug Category: This is a bug. F-try_blocks `#![feature(try_blocks)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@rodrigorc
Copy link

The following code fails to compile (rustc --edition=2018):

#![feature(try_blocks)]
fn main() {
    match try { 0 } {
        None => (),
        Some(_) => ()
    };
}

The compiler error is:

error: expected expression, found reserved keyword `try`
 --> test.rs:3:11
  |
3 |     match try { 0 } {
  |     ----- ^^^ expected expression
  |     |
  |     while parsing this match expression

Adding parentheses or braces, it will compile fine:

    match ( try { 0 } ) { ... } //warning: unnecessary parentheses around `match` head expression
    match { try { 0 } } { ... }

The same issue happens with other constructs such as:

    if let Some(_) = try { 0 } { }
    for _ in try { 0 } { } //should fail because of "cannot infer type", not "expected expression"
@estebank estebank added the A-parser Area: The lexing & parsing of Rust source code to an AST label Dec 14, 2018
@Centril
Copy link
Contributor

Centril commented Dec 15, 2018

cc @scottmcm

@scottmcm
Copy link
Member

scottmcm commented Dec 15, 2018

I believe the error is expected here, the same as with the following struct literal match in 2015:

struct try { x: i32 }
fn main() {
    let x = 1;
    match try { x } {
        try { .. } => {}
    }
}

Which also needs to be match (try { x }) { to compile.

That said, the warning to remove the necessary parens is definitely wrong.

EDIT: Hmm, I might be wrong, actually. The following compiles, which surprised me:

for _ in if true { [1].iter() } else { [0].iter() } { }

as does this:

match loop { break } {

So maybe the parser restriction is only for struct literals, not for keyword-introduced expressions.

@Centril
Copy link
Contributor

Centril commented Dec 15, 2018

Yeah I think match loop { ... } { is the better comparison here so it's probably a bug.

@rodrigorc
Copy link
Author

match loop { break } {

This is exactly what a thought. I didn't know that this:

struct try { x: i32 }
fn main() {
    let x = 1;
    match try { x } {
        try { .. } => {}
    }
}

was not allowed, so in my head the parentheses were always redundant. Is there any reason for why we need parentheses around a struct literal? A parser ambiguity, maybe? Because I would expect that to work, too.

@ExpHP
Copy link
Contributor

ExpHP commented Dec 15, 2018

Is there any reason for why we need parentheses around a struct literal? A parser ambiguity, maybe? Because I would expect that to work, too.

for x in (Thing { x })
{
    println!("This is the loop body.");
}

for x in Thing { x }
{
    println!("This is a block expression.");
}

For match, hmmm... well, I can't come up with a truly devastating example, but eliminating the parentheses could hurt diagnostics.

match (Thing {})
{} // Parsed as the match block.  ERROR: Missing `_` branch


let thing: ! = panic!();

match thing {}
{} // Parsed as a block expression statement

@Centril Centril added the C-bug Category: This is a bug. label Dec 16, 2018
@jonas-schievink jonas-schievink added F-try_blocks `#![feature(try_blocks)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. requires-nightly This issue requires a nightly compiler in some way. labels Aug 6, 2019
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 14, 2020
Allow `try`-blocks in places where an open delim is expected

Closes rust-lang#70490
Closes rust-lang#56828

r? @Centril
@bors bors closed this as completed in 15ab586 Apr 15, 2020
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST C-bug Category: This is a bug. F-try_blocks `#![feature(try_blocks)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants