@@ -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,168 @@ pub trait PrettyPrinter<'tcx>:
817817 }
818818 }
819819
820+ {
821+ define_scoped_cx ! ( self ) ;
822+ p ! ( "impl " ) ;
823+ }
824+
820825 let mut first = true ;
821826 // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
822827 let paren_needed = fn_traits. len ( ) > 1 || traits. len ( ) > 0 || !is_sized;
823828
824- p ! ( "impl" ) ;
825-
826829 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- } ;
830+ {
831+ define_scoped_cx ! ( self ) ;
832+ p ! (
833+ write( "{}" , if first { "" } else { " + " } ) ,
834+ write( "{}" , if paren_needed { "(" } else { "" } )
835+ ) ;
836+ }
837+
838+ self = self . wrap_binder ( & fn_once_trait_ref, |trait_ref, mut self_| {
839+ // Get the (single) generic ty (the args) of this FnOnce trait ref.
840+ let generics = tcx. generics_of ( trait_ref. def_id ) ;
841+ let args = generics. own_substs_no_defaults ( tcx, trait_ref. substs ) ;
842+
843+ match ( entry. return_ty , args[ 0 ] . expect_ty ( ) ) {
844+ // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
845+ // a return type.
846+ ( Some ( return_ty) , arg_tys) if matches ! ( arg_tys. kind( ) , ty:: Tuple ( _) ) => {
847+ let name = if entry. fn_trait_ref . is_some ( ) {
848+ "Fn"
849+ } else if entry. fn_mut_trait_ref . is_some ( ) {
850+ "FnMut"
851+ } else {
852+ "FnOnce"
853+ } ;
843854
844- p ! (
845- write( "{}" , if first { " " } else { " + " } ) ,
846- write( "{}{}(" , if paren_needed { "(" } else { "" } , name)
847- ) ;
855+ define_scoped_cx ! ( self_) ;
856+ p ! ( write( "{}(" , name) ) ;
848857
849- for ( idx, ty) in arg_tys. tuple_fields ( ) . iter ( ) . enumerate ( ) {
850- if idx > 0 {
851- p ! ( ", " ) ;
858+ for ( idx, ty) in arg_tys. tuple_fields ( ) . iter ( ) . enumerate ( ) {
859+ if idx > 0 {
860+ p ! ( ", " ) ;
861+ }
862+ p ! ( print( ty) ) ;
852863 }
853- p ! ( print( ty) ) ;
854- }
855864
856- p ! ( ")" ) ;
857- if let Term :: Ty ( ty) = return_ty. skip_binder ( ) {
858- if !ty. is_unit ( ) {
859- p ! ( " -> " , print( return_ty) ) ;
865+ p ! ( ")" ) ;
866+ if let Term :: Ty ( ty) = return_ty. skip_binder ( ) {
867+ if !ty. is_unit ( ) {
868+ p ! ( " -> " , print( return_ty) ) ;
869+ }
860870 }
861- }
862- p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
871+ p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863872
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 ( ) ;
873+ first = false ;
879874 }
880- if let Some ( trait_ref) = entry. fn_trait_ref {
881- traits. entry ( trait_ref) . or_default ( ) ;
875+ // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
876+ // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
877+ _ => {
878+ if entry. has_fn_once {
879+ traits. entry ( fn_once_trait_ref) . or_default ( ) . extend (
880+ // Group the return ty with its def id, if we had one.
881+ entry
882+ . return_ty
883+ . map ( |ty| ( tcx. lang_items ( ) . fn_once_output ( ) . unwrap ( ) , ty) ) ,
884+ ) ;
885+ }
886+ if let Some ( trait_ref) = entry. fn_mut_trait_ref {
887+ traits. entry ( trait_ref) . or_default ( ) ;
888+ }
889+ if let Some ( trait_ref) = entry. fn_trait_ref {
890+ traits. entry ( trait_ref) . or_default ( ) ;
891+ }
882892 }
883893 }
884- }
894+
895+ Ok ( self_)
896+ } ) ?;
885897 }
886898
887899 // Print the rest of the trait types (that aren't Fn* family of traits)
888900 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- ) ;
901+ {
902+ define_scoped_cx ! ( self ) ;
903+ p ! ( write ( "{}" , if first { "" } else { " + " } ) ) ;
904+ }
893905
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 ) ;
906+ self = self . wrap_binder ( & trait_ref, |trait_ref, mut self_| {
907+ define_scoped_cx ! ( self_) ;
908+ p ! ( print( trait_ref. print_only_trait_name( ) ) ) ;
896909
897- if !args . is_empty ( ) || !assoc_items . is_empty ( ) {
898- let mut first = true ;
910+ let generics = tcx . generics_of ( trait_ref . def_id ) ;
911+ let args = generics . own_substs_no_defaults ( tcx , trait_ref . substs ) ;
899912
900- for ty in args {
901- if first {
902- p ! ( "<" ) ;
903- first = false ;
904- } else {
905- p ! ( ", " ) ;
913+ if !args. is_empty ( ) || !assoc_items. is_empty ( ) {
914+ let mut first = true ;
915+
916+ for ty in args {
917+ if first {
918+ p ! ( "<" ) ;
919+ first = false ;
920+ } else {
921+ p ! ( ", " ) ;
922+ }
923+ p ! ( print( ty) ) ;
906924 }
907- p ! ( print( trait_ref. rebind( * ty) ) ) ;
908- }
909925
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 ( )
926+ for ( assoc_item_def_id, term) in assoc_items {
927+ // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
928+ // unless we can find out what generator return type it comes from.
929+ let term = if let Some ( ty) = term. skip_binder ( ) . ty ( )
930+ && let ty:: Projection ( ty:: ProjectionTy { item_def_id, substs } ) = ty. kind ( )
931+ && Some ( * item_def_id) == tcx. lang_items ( ) . generator_return ( )
932+ {
933+ if let ty:: Generator ( _, substs, _) = substs. type_at ( 0 ) . kind ( ) {
934+ let return_ty = substs. as_generator ( ) . return_ty ( ) ;
935+ if !return_ty. is_ty_infer ( ) {
936+ return_ty. into ( )
937+ } else {
938+ continue ;
939+ }
921940 } else {
922941 continue ;
923942 }
924943 } else {
925- continue ;
926- }
927- } else {
928- term. skip_binder ( )
929- } ;
944+ term. skip_binder ( )
945+ } ;
930946
931- if first {
932- p ! ( "<" ) ;
933- first = false ;
934- } else {
935- p ! ( ", " ) ;
936- }
947+ if first {
948+ p ! ( "<" ) ;
949+ first = false ;
950+ } else {
951+ p ! ( ", " ) ;
952+ }
937953
938- p ! ( write( "{} = " , self . tcx( ) . associated_item( assoc_item_def_id) . name) ) ;
954+ p ! ( write( "{} = " , tcx. associated_item( assoc_item_def_id) . name) ) ;
939955
940- match term {
941- Term :: Ty ( ty) => {
942- p ! ( print( ty) )
943- }
944- Term :: Const ( c) => {
945- p ! ( print( c) ) ;
946- }
947- } ;
948- }
956+ match term {
957+ Term :: Ty ( ty) => {
958+ p ! ( print( ty) )
959+ }
960+ Term :: Const ( c) => {
961+ p ! ( print( c) ) ;
962+ }
963+ } ;
964+ }
949965
950- if !first {
951- p ! ( ">" ) ;
966+ if !first {
967+ p ! ( ">" ) ;
968+ }
952969 }
953- }
954970
955- first = false ;
971+ first = false ;
972+ Ok ( self_)
973+ } ) ?;
956974 }
957975
976+ define_scoped_cx ! ( self ) ;
977+
958978 if !is_sized {
959- p ! ( write( "{}?Sized" , if first { " " } else { " + " } ) ) ;
979+ p ! ( write( "{}?Sized" , if first { "" } else { " + " } ) ) ;
960980 } else if first {
961- p ! ( " Sized" ) ;
981+ p ! ( "Sized" ) ;
962982 }
963983
964984 Ok ( self )
@@ -1869,7 +1889,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
18691889 self . pretty_in_binder ( value)
18701890 }
18711891
1872- fn wrap_binder < T , C : Fn ( & T , Self ) -> Result < Self , Self :: Error > > (
1892+ fn wrap_binder < T , C : FnOnce ( & T , Self ) -> Result < Self , Self :: Error > > (
18731893 self ,
18741894 value : & ty:: Binder < ' tcx , T > ,
18751895 f : C ,
@@ -2256,7 +2276,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22562276 Ok ( inner)
22572277 }
22582278
2259- pub fn pretty_wrap_binder < T , C : Fn ( & T , Self ) -> Result < Self , fmt:: Error > > (
2279+ pub fn pretty_wrap_binder < T , C : FnOnce ( & T , Self ) -> Result < Self , fmt:: Error > > (
22602280 self ,
22612281 value : & ty:: Binder < ' tcx , T > ,
22622282 f : C ,
0 commit comments