@@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>:
226226 value. as_ref ( ) . skip_binder ( ) . print ( self )
227227 }
228228
229- fn wrap_binder < T , F : Fn ( & T , Self ) -> Result < Self , fmt:: Error > > (
229+ fn wrap_binder < T , F : FnOnce ( & T , Self ) -> Result < Self , fmt:: Error > > (
230230 self ,
231231 value : & ty:: Binder < ' tcx , T > ,
232232 f : F ,
@@ -773,26 +773,26 @@ pub trait PrettyPrinter<'tcx>:
773773 def_id : DefId ,
774774 substs : & ' tcx ty:: List < ty:: GenericArg < ' tcx > > ,
775775 ) -> Result < Self :: Type , Self :: Error > {
776- define_scoped_cx ! ( self ) ;
776+ let tcx = self . tcx ( ) ;
777777
778778 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
779779 // by looking up the projections associated with the def_id.
780- let bounds = self . tcx ( ) . bound_explicit_item_bounds ( def_id) ;
780+ let bounds = tcx. bound_explicit_item_bounds ( def_id) ;
781781
782782 let mut traits = FxIndexMap :: default ( ) ;
783783 let mut fn_traits = FxIndexMap :: default ( ) ;
784784 let mut is_sized = false ;
785785
786786 for predicate in bounds. transpose_iter ( ) . map ( |e| e. map_bound ( |( p, _) | * p) ) {
787- let predicate = predicate. subst ( self . tcx ( ) , substs) ;
787+ let predicate = predicate. subst ( tcx, substs) ;
788788 let bound_predicate = predicate. kind ( ) ;
789789
790790 match bound_predicate. skip_binder ( ) {
791791 ty:: PredicateKind :: Trait ( pred) => {
792792 let trait_ref = bound_predicate. rebind ( pred. trait_ref ) ;
793793
794794 // Don't print + Sized, but rather + ?Sized if absent.
795- if Some ( trait_ref. def_id ( ) ) == self . tcx ( ) . lang_items ( ) . sized_trait ( ) {
795+ if Some ( trait_ref. def_id ( ) ) == tcx. lang_items ( ) . sized_trait ( ) {
796796 is_sized = true ;
797797 continue ;
798798 }
@@ -801,7 +801,7 @@ pub trait PrettyPrinter<'tcx>:
801801 }
802802 ty:: PredicateKind :: Projection ( pred) => {
803803 let proj_ref = bound_predicate. rebind ( pred) ;
804- let trait_ref = proj_ref. required_poly_trait_ref ( self . tcx ( ) ) ;
804+ let trait_ref = proj_ref. required_poly_trait_ref ( tcx) ;
805805
806806 // Projection type entry -- the def-id for naming, and the ty.
807807 let proj_ty = ( proj_ref. projection_def_id ( ) , proj_ref. term ( ) ) ;
@@ -817,148 +817,155 @@ pub trait PrettyPrinter<'tcx>:
817817 }
818818 }
819819
820+ write ! ( self , "impl " ) ?;
821+
820822 let mut first = true ;
821823 // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
822824 let paren_needed = fn_traits. len ( ) > 1 || traits. len ( ) > 0 || !is_sized;
823825
824- p ! ( "impl" ) ;
825-
826826 for ( fn_once_trait_ref, entry) in fn_traits {
827- // Get the (single) generic ty (the args) of this FnOnce trait ref.
828- let generics = self . tcx ( ) . generics_of ( fn_once_trait_ref. def_id ( ) ) ;
829- let args =
830- generics. own_substs_no_defaults ( self . tcx ( ) , fn_once_trait_ref. skip_binder ( ) . substs ) ;
831-
832- match ( entry. return_ty , args[ 0 ] . expect_ty ( ) ) {
833- // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
834- // a return type.
835- ( Some ( return_ty) , arg_tys) if matches ! ( arg_tys. kind( ) , ty:: Tuple ( _) ) => {
836- let name = if entry. fn_trait_ref . is_some ( ) {
837- "Fn"
838- } else if entry. fn_mut_trait_ref . is_some ( ) {
839- "FnMut"
840- } else {
841- "FnOnce"
842- } ;
827+ write ! ( self , "{}" , if first { "" } else { " + " } ) ?;
828+ write ! ( self , "{}" , if paren_needed { "(" } else { "" } ) ?;
843829
844- p ! (
845- write( "{}" , if first { " " } else { " + " } ) ,
846- write( "{}{}(" , if paren_needed { "(" } else { "" } , name)
847- ) ;
830+ self = self . wrap_binder ( & fn_once_trait_ref, |trait_ref, mut cx| {
831+ define_scoped_cx ! ( cx) ;
832+ // Get the (single) generic ty (the args) of this FnOnce trait ref.
833+ let generics = tcx. generics_of ( trait_ref. def_id ) ;
834+ let args = generics. own_substs_no_defaults ( tcx, trait_ref. substs ) ;
835+
836+ match ( entry. return_ty , args[ 0 ] . expect_ty ( ) ) {
837+ // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
838+ // a return type.
839+ ( Some ( return_ty) , arg_tys) if matches ! ( arg_tys. kind( ) , ty:: Tuple ( _) ) => {
840+ let name = if entry. fn_trait_ref . is_some ( ) {
841+ "Fn"
842+ } else if entry. fn_mut_trait_ref . is_some ( ) {
843+ "FnMut"
844+ } else {
845+ "FnOnce"
846+ } ;
848847
849- for ( idx, ty) in arg_tys. tuple_fields ( ) . iter ( ) . enumerate ( ) {
850- if idx > 0 {
851- p ! ( ", " ) ;
848+ p ! ( write( "{}(" , name) ) ;
849+
850+ for ( idx, ty) in arg_tys. tuple_fields ( ) . iter ( ) . enumerate ( ) {
851+ if idx > 0 {
852+ p ! ( ", " ) ;
853+ }
854+ p ! ( print( ty) ) ;
852855 }
853- p ! ( print( ty) ) ;
854- }
855856
856- p ! ( ")" ) ;
857- if let Term :: Ty ( ty) = return_ty. skip_binder ( ) {
858- if !ty. is_unit ( ) {
859- p ! ( " -> " , print( return_ty) ) ;
857+ p ! ( ")" ) ;
858+ if let Term :: Ty ( ty) = return_ty. skip_binder ( ) {
859+ if !ty. is_unit ( ) {
860+ p ! ( " -> " , print( return_ty) ) ;
861+ }
860862 }
861- }
862- p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863+ p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863864
864- first = false ;
865- }
866- // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
867- // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
868- _ => {
869- if entry. has_fn_once {
870- traits. entry ( fn_once_trait_ref) . or_default ( ) . extend (
871- // Group the return ty with its def id, if we had one.
872- entry
873- . return_ty
874- . map ( |ty| ( self . tcx ( ) . lang_items ( ) . fn_once_output ( ) . unwrap ( ) , ty) ) ,
875- ) ;
876- }
877- if let Some ( trait_ref) = entry. fn_mut_trait_ref {
878- traits. entry ( trait_ref) . or_default ( ) ;
865+ first = false ;
879866 }
880- if let Some ( trait_ref) = entry. fn_trait_ref {
881- traits. entry ( trait_ref) . or_default ( ) ;
867+ // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
868+ // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
869+ _ => {
870+ if entry. has_fn_once {
871+ traits. entry ( fn_once_trait_ref) . or_default ( ) . extend (
872+ // Group the return ty with its def id, if we had one.
873+ entry
874+ . return_ty
875+ . map ( |ty| ( tcx. lang_items ( ) . fn_once_output ( ) . unwrap ( ) , ty) ) ,
876+ ) ;
877+ }
878+ if let Some ( trait_ref) = entry. fn_mut_trait_ref {
879+ traits. entry ( trait_ref) . or_default ( ) ;
880+ }
881+ if let Some ( trait_ref) = entry. fn_trait_ref {
882+ traits. entry ( trait_ref) . or_default ( ) ;
883+ }
882884 }
883885 }
884- }
886+
887+ Ok ( cx)
888+ } ) ?;
885889 }
886890
887891 // Print the rest of the trait types (that aren't Fn* family of traits)
888892 for ( trait_ref, assoc_items) in traits {
889- p ! (
890- write( "{}" , if first { " " } else { " + " } ) ,
891- print( trait_ref. skip_binder( ) . print_only_trait_name( ) )
892- ) ;
893+ write ! ( self , "{}" , if first { "" } else { " + " } ) ?;
894+
895+ self = self . wrap_binder ( & trait_ref, |trait_ref, mut cx| {
896+ define_scoped_cx ! ( cx) ;
897+ p ! ( print( trait_ref. print_only_trait_name( ) ) ) ;
893898
894- let generics = self . tcx ( ) . generics_of ( trait_ref. def_id ( ) ) ;
895- let args = generics. own_substs_no_defaults ( self . tcx ( ) , trait_ref. skip_binder ( ) . substs ) ;
899+ let generics = tcx. generics_of ( trait_ref. def_id ) ;
900+ let args = generics. own_substs_no_defaults ( tcx, trait_ref. substs ) ;
896901
897- if !args. is_empty ( ) || !assoc_items. is_empty ( ) {
898- let mut first = true ;
902+ if !args. is_empty ( ) || !assoc_items. is_empty ( ) {
903+ let mut first = true ;
899904
900- for ty in args {
901- if first {
902- p ! ( "<" ) ;
903- first = false ;
904- } else {
905- p ! ( ", " ) ;
905+ for ty in args {
906+ if first {
907+ p ! ( "<" ) ;
908+ first = false ;
909+ } else {
910+ p ! ( ", " ) ;
911+ }
912+ p ! ( print( ty) ) ;
906913 }
907- p ! ( print( trait_ref. rebind( * ty) ) ) ;
908- }
909914
910- for ( assoc_item_def_id, term) in assoc_items {
911- // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
912- // unless we can find out what generator return type it comes from.
913- let term = if let Some ( ty) = term. skip_binder ( ) . ty ( )
914- && let ty:: Projection ( ty:: ProjectionTy { item_def_id, substs } ) = ty. kind ( )
915- && Some ( * item_def_id) == self . tcx ( ) . lang_items ( ) . generator_return ( )
916- {
917- if let ty:: Generator ( _, substs, _) = substs. type_at ( 0 ) . kind ( ) {
918- let return_ty = substs. as_generator ( ) . return_ty ( ) ;
919- if !return_ty. is_ty_infer ( ) {
920- return_ty. into ( )
915+ for ( assoc_item_def_id, term) in assoc_items {
916+ // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
917+ // unless we can find out what generator return type it comes from.
918+ let term = if let Some ( ty) = term. skip_binder ( ) . ty ( )
919+ && let ty:: Projection ( ty:: ProjectionTy { item_def_id, substs } ) = ty. kind ( )
920+ && Some ( * item_def_id) == tcx. lang_items ( ) . generator_return ( )
921+ {
922+ if let ty:: Generator ( _, substs, _) = substs. type_at ( 0 ) . kind ( ) {
923+ let return_ty = substs. as_generator ( ) . return_ty ( ) ;
924+ if !return_ty. is_ty_infer ( ) {
925+ return_ty. into ( )
926+ } else {
927+ continue ;
928+ }
921929 } else {
922930 continue ;
923931 }
924932 } else {
925- continue ;
926- }
927- } else {
928- term. skip_binder ( )
929- } ;
933+ term. skip_binder ( )
934+ } ;
930935
931- if first {
932- p ! ( "<" ) ;
933- first = false ;
934- } else {
935- p ! ( ", " ) ;
936- }
936+ if first {
937+ p ! ( "<" ) ;
938+ first = false ;
939+ } else {
940+ p ! ( ", " ) ;
941+ }
937942
938- p ! ( write( "{} = " , self . tcx( ) . associated_item( assoc_item_def_id) . name) ) ;
943+ p ! ( write( "{} = " , tcx. associated_item( assoc_item_def_id) . name) ) ;
939944
940- match term {
941- Term :: Ty ( ty) => {
942- p ! ( print( ty) )
943- }
944- Term :: Const ( c) => {
945- p ! ( print( c) ) ;
946- }
947- } ;
948- }
945+ match term {
946+ Term :: Ty ( ty) => {
947+ p ! ( print( ty) )
948+ }
949+ Term :: Const ( c) => {
950+ p ! ( print( c) ) ;
951+ }
952+ } ;
953+ }
949954
950- if !first {
951- p ! ( ">" ) ;
955+ if !first {
956+ p ! ( ">" ) ;
957+ }
952958 }
953- }
954959
955- first = false ;
960+ first = false ;
961+ Ok ( cx)
962+ } ) ?;
956963 }
957964
958965 if !is_sized {
959- p ! ( write ( "{}?Sized" , if first { " " } else { " + " } ) ) ;
966+ write ! ( self , "{}?Sized" , if first { "" } else { " + " } ) ? ;
960967 } else if first {
961- p ! ( " Sized") ;
968+ write ! ( self , " Sized") ? ;
962969 }
963970
964971 Ok ( self )
@@ -1869,7 +1876,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
18691876 self . pretty_in_binder ( value)
18701877 }
18711878
1872- fn wrap_binder < T , C : Fn ( & T , Self ) -> Result < Self , Self :: Error > > (
1879+ fn wrap_binder < T , C : FnOnce ( & T , Self ) -> Result < Self , Self :: Error > > (
18731880 self ,
18741881 value : & ty:: Binder < ' tcx , T > ,
18751882 f : C ,
@@ -2256,7 +2263,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22562263 Ok ( inner)
22572264 }
22582265
2259- pub fn pretty_wrap_binder < T , C : Fn ( & T , Self ) -> Result < Self , fmt:: Error > > (
2266+ pub fn pretty_wrap_binder < T , C : FnOnce ( & T , Self ) -> Result < Self , fmt:: Error > > (
22602267 self ,
22612268 value : & ty:: Binder < ' tcx , T > ,
22622269 f : C ,
0 commit comments