Improve HIR pretty-printing of if/else some more.

In the AST the "then" block is represented as a `Block`. In HIR the
"then" block is represented as an `Expr` that happens to always be.
`ExprKind::Block`. By deconstructing the `ExprKind::Block` to extract
the block within, things print properly.

For `issue-82392.rs`, note that we no longer print a type after the
"then" block. This is good, it now matches how we don't print a type for
the "else" block. (Well, we do print a type after the "else" block, but
it's for the whole if/else.)

Also tighten up some of the pattern matching -- these block expressions
within if/else will never have labels.
This commit is contained in:
Nicholas Nethercote
2025-04-25 19:12:15 +10:00
parent e37c367482
commit 7ac2d1f1bd
4 changed files with 37 additions and 41 deletions

View File

@@ -30,7 +30,7 @@ impl<'a> State<'a> {
self.print_else(e.as_deref())
}
// Final `else` block.
ast::ExprKind::Block(b, _) => {
ast::ExprKind::Block(b, None) => {
self.cbox(0);
self.ibox(0);
self.word(" else ");

View File

@@ -1064,17 +1064,17 @@ impl<'a> State<'a> {
if let Some(els_inner) = els {
match els_inner.kind {
// Another `else if` block.
hir::ExprKind::If(i, then, e) => {
hir::ExprKind::If(i, hir::Expr { kind: hir::ExprKind::Block(t, None), .. }, e) => {
self.cbox(0);
self.ibox(0);
self.word(" else if ");
self.print_expr_as_cond(i);
self.space();
self.print_expr(then);
self.print_block(t);
self.print_else(e);
}
// Final `else` block.
hir::ExprKind::Block(b, _) => {
hir::ExprKind::Block(b, None) => {
self.cbox(0);
self.ibox(0);
self.word(" else ");
@@ -1099,8 +1099,13 @@ impl<'a> State<'a> {
self.word_nbsp("if");
self.print_expr_as_cond(test);
self.space();
self.print_expr(blk);
self.print_else(elseopt)
match blk.kind {
hir::ExprKind::Block(blk, None) => {
self.print_block(blk);
self.print_else(elseopt)
}
_ => panic!("non-block then expr"),
}
}
fn print_anon_const(&mut self, constant: &hir::AnonConst) {

View File

@@ -12,37 +12,28 @@ fn f(x: u32,
let mut a = 0;
if x > y { a = 1; } else { a = 2; }
if x < 1
{
a = 1;
} else if x < 2
{
a = 2;
} else if x < 3
{
a = 3;
} else if x < 4 { a = 4; } else { a = 5; }
if x < 1 {
a = 1;
} else if x < 2 {
a = 2;
} else if x < 3 { a = 3; } else if x < 4 { a = 4; } else { a = 5; }
if x < y
{
a += 1;
a += 1;
a += 1;
a += 1;
a += 1;
a += 1;
} else { a += 1; a += 1; a += 1; a += 1; a += 1; a += 1; }
if x < y {
a += 1;
a += 1;
a += 1;
a += 1;
a += 1;
a += 1;
} else { a += 1; a += 1; a += 1; a += 1; a += 1; a += 1; }
if x < 1
{
if x < 2
{
if x < 3
{
a += 1;
} else if x < 4
{ a += 1; if x < 5 { a += 1; } }
} else if x < 6 { a += 1; } }
}
if x < 1 {
if x < 2 {
if x < 3 {
a += 1;
} else if x < 4 { a += 1; if x < 5 { a += 1; } }
} else if x < 6 { a += 1; }
}
}
fn main() { f(3, 4); }
fn main() { f(3, 4); }

View File

@@ -8,10 +8,10 @@ extern crate std;
//@ edition:2015
fn main() ({
(if (true as bool)
({ } as
()) else if (let Some(a) =
(if (true as bool) {
} else if (let Some(a) =
((Some as
fn(i32) -> Option<i32> {Option::<i32>::Some})((3 as i32)) as
Option<i32>) as bool) ({ } as ()) as ())
Option<i32>) as bool) {
} as ())
} as ())