@@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>:
226
226
value. as_ref ( ) . skip_binder ( ) . print ( self )
227
227
}
228
228
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 > > (
230
230
self ,
231
231
value : & ty:: Binder < ' tcx , T > ,
232
232
f : F ,
@@ -773,26 +773,26 @@ pub trait PrettyPrinter<'tcx>:
773
773
def_id : DefId ,
774
774
substs : & ' tcx ty:: List < ty:: GenericArg < ' tcx > > ,
775
775
) -> Result < Self :: Type , Self :: Error > {
776
- define_scoped_cx ! ( self ) ;
776
+ let tcx = self . tcx ( ) ;
777
777
778
778
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
779
779
// 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) ;
781
781
782
782
let mut traits = FxIndexMap :: default ( ) ;
783
783
let mut fn_traits = FxIndexMap :: default ( ) ;
784
784
let mut is_sized = false ;
785
785
786
786
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) ;
788
788
let bound_predicate = predicate. kind ( ) ;
789
789
790
790
match bound_predicate. skip_binder ( ) {
791
791
ty:: PredicateKind :: Trait ( pred) => {
792
792
let trait_ref = bound_predicate. rebind ( pred. trait_ref ) ;
793
793
794
794
// 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 ( ) {
796
796
is_sized = true ;
797
797
continue ;
798
798
}
@@ -801,7 +801,7 @@ pub trait PrettyPrinter<'tcx>:
801
801
}
802
802
ty:: PredicateKind :: Projection ( pred) => {
803
803
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) ;
805
805
806
806
// Projection type entry -- the def-id for naming, and the ty.
807
807
let proj_ty = ( proj_ref. projection_def_id ( ) , proj_ref. term ( ) ) ;
@@ -817,148 +817,155 @@ pub trait PrettyPrinter<'tcx>:
817
817
}
818
818
}
819
819
820
+ write ! ( self , "impl " ) ?;
821
+
820
822
let mut first = true ;
821
823
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
822
824
let paren_needed = fn_traits. len ( ) > 1 || traits. len ( ) > 0 || !is_sized;
823
825
824
- p ! ( "impl" ) ;
825
-
826
826
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 { "" } ) ?;
843
829
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
+ } ;
848
847
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) ) ;
852
855
}
853
- p ! ( print( ty) ) ;
854
- }
855
856
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
+ }
860
862
}
861
- }
862
- p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863
+ p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863
864
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 ;
879
866
}
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
+ }
882
884
}
883
885
}
884
- }
886
+
887
+ Ok ( cx)
888
+ } ) ?;
885
889
}
886
890
887
891
// Print the rest of the trait types (that aren't Fn* family of traits)
888
892
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( ) ) ) ;
893
898
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 ) ;
896
901
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 ;
899
904
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) ) ;
906
913
}
907
- p ! ( print( trait_ref. rebind( * ty) ) ) ;
908
- }
909
914
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
+ }
921
929
} else {
922
930
continue ;
923
931
}
924
932
} else {
925
- continue ;
926
- }
927
- } else {
928
- term. skip_binder ( )
929
- } ;
933
+ term. skip_binder ( )
934
+ } ;
930
935
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
+ }
937
942
938
- p ! ( write( "{} = " , self . tcx( ) . associated_item( assoc_item_def_id) . name) ) ;
943
+ p ! ( write( "{} = " , tcx. associated_item( assoc_item_def_id) . name) ) ;
939
944
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
+ }
949
954
950
- if !first {
951
- p ! ( ">" ) ;
955
+ if !first {
956
+ p ! ( ">" ) ;
957
+ }
952
958
}
953
- }
954
959
955
- first = false ;
960
+ first = false ;
961
+ Ok ( cx)
962
+ } ) ?;
956
963
}
957
964
958
965
if !is_sized {
959
- p ! ( write ( "{}?Sized" , if first { " " } else { " + " } ) ) ;
966
+ write ! ( self , "{}?Sized" , if first { "" } else { " + " } ) ? ;
960
967
} else if first {
961
- p ! ( " Sized") ;
968
+ write ! ( self , " Sized") ? ;
962
969
}
963
970
964
971
Ok ( self )
@@ -1869,7 +1876,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
1869
1876
self . pretty_in_binder ( value)
1870
1877
}
1871
1878
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 > > (
1873
1880
self ,
1874
1881
value : & ty:: Binder < ' tcx , T > ,
1875
1882
f : C ,
@@ -2256,7 +2263,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
2256
2263
Ok ( inner)
2257
2264
}
2258
2265
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 > > (
2260
2267
self ,
2261
2268
value : & ty:: Binder < ' tcx , T > ,
2262
2269
f : C ,
0 commit comments