From 03dcd99aa322a0d5c9b5f203b1222798bbabf941 Mon Sep 17 00:00:00 2001 From: ia0 Date: Sat, 7 Feb 2026 15:39:42 +0100 Subject: [PATCH 1/2] Format heterogeneous try blocks --- src/tools/rustfmt/src/expr.rs | 29 +++++++++++++-- .../tests/source/try_blocks_heterogeneous.rs | 34 ++++++++++++++++++ .../tests/target/try_blocks_heterogeneous.rs | 36 +++++++++++++++++++ 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs create mode 100644 src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index de96f004dc873..70bce1920047f 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -385,8 +385,33 @@ pub(crate) fn format_expr( )) } } - // FIXME: heterogeneous try blocks, which include a type so are harder to format - ast::ExprKind::TryBlock(_, Some(_)) => Err(RewriteError::Unknown), + ast::ExprKind::TryBlock(ref block, Some(ref ty)) => { + let keyword = "try bikeshed "; + // 2 = " {".len() + let ty_shape = shape + .shrink_left(keyword.len()) + .and_then(|shape| shape.sub_width(2)) + .max_width_error(shape.width, expr.span)?; + let ty_str = ty.rewrite_result(context, ty_shape)?; + let prefix = format!("{keyword}{ty_str} "); + if let rw @ Ok(_) = + rewrite_single_line_block(context, &prefix, block, Some(&expr.attrs), None, shape) + { + rw + } else { + let budget = shape.width.saturating_sub(prefix.len()); + Ok(format!( + "{prefix}{}", + rewrite_block( + block, + Some(&expr.attrs), + None, + context, + Shape::legacy(budget, shape.indent) + )? + )) + } + } ast::ExprKind::Gen(capture_by, ref block, ref kind, _) => { let mover = if matches!(capture_by, ast::CaptureBy::Value { .. }) { "move " diff --git a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs new file mode 100644 index 0000000000000..bae0060374d88 --- /dev/null +++ b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs @@ -0,0 +1,34 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x = try bikeshed Option<_> { + 4 + }; + + try bikeshed Result<_, _> {} +} + +fn baz() -> Option { + if (1 == 1) { + return try bikeshed Option { + 5 + }; + } + + // test + let x = try bikeshed Option<()> { + // try blocks are great + }; + + let y = try bikeshed Option { + 6 + }; // comment + + let x = try bikeshed Option { baz()?; baz()?; baz()?; 7 }; + + let x = try bikeshed Foo { 1 + 1 + 1 }; + + let x = try bikeshed Foo {}; + + return None; +} diff --git a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs new file mode 100644 index 0000000000000..6f910ed5d0519 --- /dev/null +++ b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs @@ -0,0 +1,36 @@ +// rustfmt-edition: 2018 + +fn main() -> Result<(), !> { + let _x = try bikeshed Option<_> { 4 }; + + try bikeshed Result<_, _> {} +} + +fn baz() -> Option { + if (1 == 1) { + return try bikeshed Option { 5 }; + } + + // test + let x = try bikeshed Option<()> { + // try blocks are great + }; + + let y = try bikeshed Option { 6 }; // comment + + let x = try bikeshed Option { + baz()?; + baz()?; + baz()?; + 7 + }; + + let x = try bikeshed Foo { + 1 + 1 + 1 + }; + + let x = + try bikeshed Foo {}; + + return None; +} From d5c6866dbadbf4c410faf6ab8b01c0f88631e171 Mon Sep 17 00:00:00 2001 From: ia0 Date: Sat, 7 Feb 2026 22:06:55 +0100 Subject: [PATCH 2/2] improve tests --- src/tools/rustfmt/tests/source/try_block.rs | 1 + src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs | 5 +++++ src/tools/rustfmt/tests/target/try_block.rs | 1 + src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/src/tools/rustfmt/tests/source/try_block.rs b/src/tools/rustfmt/tests/source/try_block.rs index 2e8d61f7e66a5..e324a13317584 100644 --- a/src/tools/rustfmt/tests/source/try_block.rs +++ b/src/tools/rustfmt/tests/source/try_block.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks)] fn main() -> Result<(), !> { let _x: Option<_> = try { diff --git a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs index bae0060374d88..7a1135cfbc764 100644 --- a/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs +++ b/src/tools/rustfmt/tests/source/try_blocks_heterogeneous.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks_heterogeneous)] fn main() -> Result<(), !> { let _x = try bikeshed Option<_> { @@ -24,6 +25,10 @@ fn baz() -> Option { 6 }; // comment + let x = try /* Invisible comment */ bikeshed Option<()> {}; + let x = try bikeshed /* Invisible comment */ Option<()> {}; + let x = try bikeshed Option<()> /* Invisible comment */ {}; + let x = try bikeshed Option { baz()?; baz()?; baz()?; 7 }; let x = try bikeshed Foo { 1 + 1 + 1 }; diff --git a/src/tools/rustfmt/tests/target/try_block.rs b/src/tools/rustfmt/tests/target/try_block.rs index 19a3f3e148769..61da123b735d8 100644 --- a/src/tools/rustfmt/tests/target/try_block.rs +++ b/src/tools/rustfmt/tests/target/try_block.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks)] fn main() -> Result<(), !> { let _x: Option<_> = try { 4 }; diff --git a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs index 6f910ed5d0519..018d53ed35e41 100644 --- a/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs +++ b/src/tools/rustfmt/tests/target/try_blocks_heterogeneous.rs @@ -1,4 +1,5 @@ // rustfmt-edition: 2018 +#![feature(try_blocks_heterogeneous)] fn main() -> Result<(), !> { let _x = try bikeshed Option<_> { 4 }; @@ -18,6 +19,10 @@ fn baz() -> Option { let y = try bikeshed Option { 6 }; // comment + let x = try /* Invisible comment */ bikeshed Option<()> {}; + let x = try bikeshed /* Invisible comment */ Option<()> {}; + let x = try bikeshed Option<()> /* Invisible comment */ {}; + let x = try bikeshed Option { baz()?; baz()?;