Skip to content

Commit

Permalink
Auto merge of #125051 - dtolnay:printletelse, r=compiler-errors
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
bors committed May 12, 2024
2 parents ef00278 + 94cc82c commit ecbe3fd
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,11 @@ impl<'a> State<'a> {
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);
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/macros/stringify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -685,6 +690,16 @@ fn test_stmt() {
"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;");
Expand Down
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions tests/ui/unpretty/let-else.rs
Original file line number Diff line number Diff line change
@@ -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; };
}
15 changes: 15 additions & 0 deletions tests/ui/unpretty/let-else.stdout
Original file line number Diff line number Diff line change
@@ -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; };
}

0 comments on commit ecbe3fd

Please sign in to comment.