@@ -353,11 +353,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
353353 fn should_print_optional_region ( & self , region : ty:: Region < ' tcx > ) -> bool ;
354354
355355 /// Whether `pretty_print_type` should wrap a multi-bound `impl` / `dyn`
356- /// inner in parens after a prefix type constructor (`&`, `&mut`, `*const`,
357- /// `*mut`), so the output is `&(impl A + B)` rather than the parser-
358- /// ambiguous `&impl A + B`. Byte-stable printers (mangling, `type_name`)
359- /// override this to `false`.
360- fn add_disambiguating_parens_in_prefix_position ( & self ) -> bool {
356+ /// inner in parens at positions where the bare form would be parser-
357+ /// ambiguous: after a prefix type constructor (`&`, `&mut`, `*const`,
358+ /// `*mut`) where `&T + B` parses as `(&T) + B`, and in the function-
359+ /// pointer / `Fn(..) -> T` return position where `-> T + B` parses as
360+ /// the outer signature picking up an extra bound. Byte-stable printers
361+ /// (mangling, etc.) override this to `false`.
362+ fn add_disambiguating_parens ( & self ) -> bool {
361363 true
362364 }
363365
@@ -817,16 +819,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
817819 }
818820 ty:: Adt ( def, args) => self . print_def_path ( def. did ( ) , args) ?,
819821 ty:: Dynamic ( data, r) => {
820- let print_r = self . should_print_optional_region ( r) ;
821- if print_r {
822- write ! ( self , "(" ) ?;
823- }
824822 write ! ( self , "dyn " ) ?;
825823 data. print ( self ) ?;
826- if print_r {
824+ if self . should_print_optional_region ( r ) {
827825 write ! ( self , " + " ) ?;
828826 r. print ( self ) ?;
829- write ! ( self , ")" ) ?;
830827 }
831828 }
832829 ty:: Foreign ( def_id) => self . print_def_path ( def_id, & [ ] ) ?,
@@ -1100,7 +1097,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11001097 /// print with a top-level `+`. Without the wrap, `&impl A + B` parses as
11011098 /// the ambiguous `(&impl A) + B`.
11021099 fn inner_needs_disambiguating_parens ( & self , ty : Ty < ' tcx > ) -> bool {
1103- if !self . add_disambiguating_parens_in_prefix_position ( ) || self . should_print_verbose ( ) {
1100+ if !self . add_disambiguating_parens ( ) || self . should_print_verbose ( ) {
11041101 return false ;
11051102 }
11061103 match ty. kind ( ) {
@@ -1114,24 +1111,21 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11141111 self . opaque_has_multiple_bounds ( * def_id)
11151112 }
11161113 ty:: Dynamic ( predicates, region) => {
1117- if self . should_print_optional_region ( * region) {
1118- // `ty::Dynamic` self-wraps when it has an explicit region.
1119- false
1120- } else {
1121- // Projections inline into the principal as `<Item = X>`;
1122- // only principal/auto traits produce a top-level `+`.
1123- predicates
1124- . iter ( )
1125- . filter ( |pred| {
1126- matches ! (
1127- pred. skip_binder( ) ,
1128- ty:: ExistentialPredicate :: Trait ( _)
1129- | ty:: ExistentialPredicate :: AutoTrait ( _)
1130- )
1131- } )
1132- . count ( )
1133- > 1
1134- }
1114+ // Projections inline into the principal as `<Item = X>`;
1115+ // only principal/auto traits produce a top-level `+`. An
1116+ // explicit (printable) region adds one more `+`-joined part.
1117+ let trait_count = predicates
1118+ . iter ( )
1119+ . filter ( |pred| {
1120+ matches ! (
1121+ pred. skip_binder( ) ,
1122+ ty:: ExistentialPredicate :: Trait ( _)
1123+ | ty:: ExistentialPredicate :: AutoTrait ( _)
1124+ )
1125+ } )
1126+ . count ( ) ;
1127+ let region_count = usize:: from ( self . should_print_optional_region ( * region) ) ;
1128+ trait_count + region_count > 1
11351129 }
11361130 _ => false ,
11371131 }
@@ -1150,7 +1144,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11501144 // Mirror `pretty_print_opaque_impl_type`'s sized-bound handling:
11511145 // positive `Sized` and `MetaSized` are absorbed into the synthetic
11521146 // suffix below; negative `Sized` (`?Sized`) falls through and is
1153- // printed inline. Only clause *kinds* are inspected here, so the
1147+ // printed inline. We only ever look at clause *kinds* here, so the
11541148 // identity-instantiated bounds carry all the information we need.
11551149 let mut trait_emits = 0usize ;
11561150 let mut lifetimes_count = 0usize ;
@@ -1669,7 +1663,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
16691663 write ! ( self , ")" ) ?;
16701664 if !output. is_unit ( ) {
16711665 write ! ( self , " -> " ) ?;
1672- output. print ( self ) ?;
1666+ // `Fn(..) -> X + B` parses as if `+ B` extended the outer signature,
1667+ // so wrap if `X` would print with `+`-joined bounds. Same machinery
1668+ // as the `&T`, `*const T`, `*mut T` prefix arms.
1669+ self . print_inner_with_disambiguating_parens ( output) ?;
16731670 }
16741671
16751672 Ok ( ( ) )
0 commit comments