Change:
The following code fails to compile (): The compiler error is: Adding parentheses or braces, it will compile fine: The same issue happens with other constructs such as:
cc
I believe the error is expected here, the same as with : Which also needs to be 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: as does this: So maybe the parser restriction is only for struct literals, not for keyword-introduced expressions.
Yeah I think is the better comparison here so it's probably a bug.
This is exactly what a thought. I didn't know that this:
For , hmmm... well, I can't come up with a truly devastating example, but eliminating the parentheses could hurt diagnostics.

Discussion:
fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { followed_by_block && match inner.kind { <del> ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, </del> <ins> ExprKind::Ret(_) | ExprKind::Break(..) => true, </ins> _ => parser::contains_exterior_struct_lit(&inner), } }

} fn is_try_block(&self) -> bool { <del> self.token.is_keyword(kw::Try) && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && self.token.uninterpolated_span().rust_2018() && // Prevent `while try {} {}`, `if try {} {} else {}`, etc. !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) </del> <ins> self.token.is_keyword(kw::Try) && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && self.token.uninterpolated_span().rust_2018() </ins> } /// Parses an `async move? {...}` expression.

<ins> // run-pass </ins> // compile-flags: --edition 2018 #![feature(try_blocks)] fn main() { <del> match try { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `try` </del> <ins> match try { } { Err(()) => (), Ok(()) => (), } </ins> }

<del> error: expected expression, found reserved keyword `try` --> $DIR/try-block-in-match.rs:6:11 | LL |     match try { false } { _ => {} } |     ----- ^^^ expected expression |     | |     while parsing this match expression error: aborting due to previous error </del>

#![feature(try_blocks)] fn main() { <del> while try { false } {} //~ ERROR expected expression, found reserved keyword `try` </del> <ins> while try { false } {} //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied </ins> }

<del> error: expected expression, found reserved keyword `try` --> $DIR/try-block-in-while.rs:6:11 </del> <ins> error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied --> $DIR/try-block-in-while.rs:6:15 </ins> | LL |     while try { false } {} <del> |           ^^^ expected expression </del> <ins> |               ^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool` | = note: required by `std::ops::Try::from_ok` </ins> error: aborting due to previous error <ins> For more information about this error, try `rustc --explain E0277`. </ins>

<ins> // check-pass // compile-flags: --edition 2018 #![feature(try_blocks)] #![warn(unused_parens, unused_braces)] fn consume<T>(_: Result<T, T>) -> T { todo!() } fn main() { consume((try {})); //~^ WARN unnecessary parentheses consume({ try {} }); //~^ WARN unnecessary braces match (try {}) { //~^ WARN unnecessary parentheses Ok(()) | Err(()) => (), } if let Err(()) = (try {}) {} //~^ WARN unnecessary parentheses match (try {}) { //~^ WARN unnecessary parentheses Ok(()) | Err(()) => (), } } </ins>

<ins> warning: unnecessary parentheses around function argument --> $DIR/try-block-unused-delims.rs:10:13 | LL |     consume((try {})); |             ^^^^^^^^ help: remove these parentheses | note: the lint level is defined here --> $DIR/try-block-unused-delims.rs:5:9 | LL | #![warn(unused_parens, unused_braces)] |         ^^^^^^^^^^^^^ warning: unnecessary braces around function argument --> $DIR/try-block-unused-delims.rs:13:13 | LL |     consume({ try {} }); |             ^^^^^^^^^^ help: remove these braces | note: the lint level is defined here --> $DIR/try-block-unused-delims.rs:5:24 | LL | #![warn(unused_parens, unused_braces)] |                        ^^^^^^^^^^^^^ warning: unnecessary parentheses around `match` scrutinee expression --> $DIR/try-block-unused-delims.rs:16:11 | LL |     match (try {}) { |           ^^^^^^^^ help: remove these parentheses warning: unnecessary parentheses around `let` scrutinee expression --> $DIR/try-block-unused-delims.rs:21:22 | LL |     if let Err(()) = (try {}) {} |                      ^^^^^^^^ help: remove these parentheses warning: unnecessary parentheses around `match` scrutinee expression --> $DIR/try-block-unused-delims.rs:24:11 | LL |     match (try {}) { |           ^^^^^^^^ help: remove these parentheses warning: 5 warnings emitted </ins>