Skip to content

Commit 03a8ae8

Browse files
Rollup merge of #153483 - aytey:dyn_paren_impl_fn_return, r=fmease
Preserve parentheses around `Fn` trait bounds in pretty printer The AST pretty printer was dropping parentheses around `Fn` trait bounds in `dyn`/`impl` types when additional `+` bounds were present. For example: dyn (FnMut(&mut T) -> &mut dyn ResourceLimiter) + Send + Sync was pretty-printed as: dyn FnMut(&mut T) -> &mut dyn ResourceLimiter + Send + Sync Without parens, `+ Send + Sync` binds to the inner `dyn ResourceLimiter` instead of the outer type, producing invalid Rust. The parser already tracks parentheses via `PolyTraitRef.parens`, but `print_poly_trait_ref` never checked this field. This adds `popen()` and `pclose()` calls when `parens == Parens::Yes`.
2 parents 6a00820 + cb66c85 commit 03a8ae8

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,9 @@ impl<'a> State<'a> {
14151415
}
14161416

14171417
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
1418+
if let ast::Parens::Yes = t.parens {
1419+
self.popen();
1420+
}
14181421
self.print_formal_generic_params(&t.bound_generic_params);
14191422

14201423
let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers;
@@ -1437,7 +1440,10 @@ impl<'a> State<'a> {
14371440
}
14381441
}
14391442

1440-
self.print_trait_ref(&t.trait_ref)
1443+
self.print_trait_ref(&t.trait_ref);
1444+
if let ast::Parens::Yes = t.parens {
1445+
self.pclose();
1446+
}
14411447
}
14421448

14431449
fn print_stmt(&mut self, st: &ast::Stmt) {

tests/pretty/paren-trait-bound.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ pp-exact
2+
3+
trait Dummy {}
4+
5+
// Without parens, `+ Send` would bind to `dyn Dummy` instead of the outer `dyn`.
6+
fn f1(_: Box<dyn (Fn() -> Box<dyn Dummy>) + Send>) {}
7+
8+
// Without parens, `+ Send + Sync` would bind to `dyn Dummy` instead of the outer `impl`.
9+
fn f2(_: impl (FnMut(&mut u8) -> &mut dyn Dummy) + Send + Sync) {}
10+
11+
fn main() {}

0 commit comments

Comments
 (0)