mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #125051 - dtolnay:printletelse, r=compiler-errors
Pretty-print let-else with added parenthesization when needed
Rustc used to produce invalid syntax for the following code, which is problematic because it means we cannot apply rustfmt to the output of `-Zunpretty=expanded`.
```rust
macro_rules! expr {
($e:expr) => { $e };
}
fn main() {
let _ = expr!(loop {}) else { return; };
}
```
```console
$ rustc repro.rs -Zunpretty=expanded | rustfmt
error: `loop...else` loops are not supported
--> <stdin>:9:29
|
9 | fn main() { let _ = loop {} else { return; }; }
| ---- ^^^^^^^^^^^^^^^^
| |
| `else` is attached to this loop
|
= note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
```
This commit is contained in:
@@ -1238,7 +1238,11 @@ fn print_stmt(&mut self, st: &ast::Stmt) {
|
||||
if let Some((init, els)) = loc.kind.init_else_opt() {
|
||||
self.nbsp();
|
||||
self.word_space("=");
|
||||
self.print_expr(init, FixupContext::default());
|
||||
self.print_expr_cond_paren(
|
||||
init,
|
||||
els.is_some() && classify::expr_trailing_brace(init).is_some(),
|
||||
FixupContext::default(),
|
||||
);
|
||||
if let Some(els) = els {
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.ibox(INDENT_UNIT);
|
||||
|
||||
@@ -675,6 +675,11 @@ fn test_stmt() {
|
||||
"let (a, b): (u32, u32) = (1, 2);",
|
||||
"let (a, b): (u32, u32) = (1, 2)"
|
||||
);
|
||||
c2!(stmt,
|
||||
[ let _ = f() else { return; } ],
|
||||
"let _ = f() else { return; };",
|
||||
"let _ = f() else { return; }",
|
||||
);
|
||||
macro_rules! c2_let_expr_minus_one {
|
||||
([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => {
|
||||
c2!(stmt, [ let _ = $expr - 1 ], $stmt_expected, $tokens_expected);
|
||||
@@ -685,6 +690,16 @@ macro_rules! c2_let_expr_minus_one {
|
||||
"let _ = match void {} - 1;",
|
||||
"let _ = match void {} - 1",
|
||||
);
|
||||
macro_rules! c2_let_expr_else_return {
|
||||
([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => {
|
||||
c2!(stmt, [ let _ = $expr else { return; } ], $stmt_expected, $tokens_expected);
|
||||
};
|
||||
}
|
||||
c2_let_expr_else_return!(
|
||||
[ f() ],
|
||||
"let _ = f() else { return; };",
|
||||
"let _ = f() else { return; }",
|
||||
);
|
||||
|
||||
// StmtKind::Item
|
||||
c1!(stmt, [ struct S; ], "struct S;");
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//@ compile-flags: -Zunpretty=expanded
|
||||
//@ check-pass
|
||||
|
||||
macro_rules! expr {
|
||||
($e:expr) => { $e };
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = expr!(1 + 1) else { return; };
|
||||
let _ = expr!(loop {}) else { return; };
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#![feature(prelude_import)]
|
||||
#![no_std]
|
||||
#[prelude_import]
|
||||
use ::std::prelude::rust_2015::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
//@ compile-flags: -Zunpretty=expanded
|
||||
//@ check-pass
|
||||
|
||||
macro_rules! expr { ($e:expr) => { $e }; }
|
||||
|
||||
fn main() {
|
||||
let _ = 1 + 1 else { return; };
|
||||
let _ = (loop {}) else { return; };
|
||||
}
|
||||
Reference in New Issue
Block a user