@@ -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,168 @@ pub trait PrettyPrinter<'tcx>:
817
817
}
818
818
}
819
819
820
+ {
821
+ define_scoped_cx ! ( self ) ;
822
+ p ! ( "impl " ) ;
823
+ }
824
+
820
825
let mut first = true ;
821
826
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
822
827
let paren_needed = fn_traits. len ( ) > 1 || traits. len ( ) > 0 || !is_sized;
823
828
824
- p ! ( "impl" ) ;
825
-
826
829
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
+ } ;
843
854
844
- p ! (
845
- write( "{}" , if first { " " } else { " + " } ) ,
846
- write( "{}{}(" , if paren_needed { "(" } else { "" } , name)
847
- ) ;
855
+ define_scoped_cx ! ( self_) ;
856
+ p ! ( write( "{}(" , name) ) ;
848
857
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) ) ;
852
863
}
853
- p ! ( print( ty) ) ;
854
- }
855
864
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
+ }
860
870
}
861
- }
862
- p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
871
+ p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
863
872
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 ;
879
874
}
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
+ }
882
892
}
883
893
}
884
- }
894
+
895
+ Ok ( self_)
896
+ } ) ?;
885
897
}
886
898
887
899
// Print the rest of the trait types (that aren't Fn* family of traits)
888
900
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
+ }
893
905
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( ) ) ) ;
896
909
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 ) ;
899
912
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) ) ;
906
924
}
907
- p ! ( print( trait_ref. rebind( * ty) ) ) ;
908
- }
909
925
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
+ }
921
940
} else {
922
941
continue ;
923
942
}
924
943
} else {
925
- continue ;
926
- }
927
- } else {
928
- term. skip_binder ( )
929
- } ;
944
+ term. skip_binder ( )
945
+ } ;
930
946
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
+ }
937
953
938
- p ! ( write( "{} = " , self . tcx( ) . associated_item( assoc_item_def_id) . name) ) ;
954
+ p ! ( write( "{} = " , tcx. associated_item( assoc_item_def_id) . name) ) ;
939
955
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
+ }
949
965
950
- if !first {
951
- p ! ( ">" ) ;
966
+ if !first {
967
+ p ! ( ">" ) ;
968
+ }
952
969
}
953
- }
954
970
955
- first = false ;
971
+ first = false ;
972
+ Ok ( self_)
973
+ } ) ?;
956
974
}
957
975
976
+ define_scoped_cx ! ( self ) ;
977
+
958
978
if !is_sized {
959
- p ! ( write( "{}?Sized" , if first { " " } else { " + " } ) ) ;
979
+ p ! ( write( "{}?Sized" , if first { "" } else { " + " } ) ) ;
960
980
} else if first {
961
- p ! ( " Sized" ) ;
981
+ p ! ( "Sized" ) ;
962
982
}
963
983
964
984
Ok ( self )
@@ -1869,7 +1889,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
1869
1889
self . pretty_in_binder ( value)
1870
1890
}
1871
1891
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 > > (
1873
1893
self ,
1874
1894
value : & ty:: Binder < ' tcx , T > ,
1875
1895
f : C ,
@@ -2256,7 +2276,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
2256
2276
Ok ( inner)
2257
2277
}
2258
2278
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 > > (
2260
2280
self ,
2261
2281
value : & ty:: Binder < ' tcx , T > ,
2262
2282
f : C ,
0 commit comments