@@ -336,7 +336,7 @@ pub trait PrettyPrinter:
336
336
/// nested components in some larger context.
337
337
fn nest < ' a , ' gcx , ' tcx , E > (
338
338
self : PrintCx < ' a , ' gcx , ' tcx , Self > ,
339
- f : impl for < ' b > FnOnce ( PrintCx < ' b , ' gcx , ' tcx , Self > ) -> Result < Self , E > ,
339
+ f : impl FnOnce ( PrintCx < ' _ , ' gcx , ' tcx , Self > ) -> Result < Self , E > ,
340
340
) -> Result < PrintCx < ' a , ' gcx , ' tcx , Self > , E > {
341
341
let printer = f ( PrintCx {
342
342
tcx : self . tcx ,
@@ -350,6 +350,17 @@ pub trait PrettyPrinter:
350
350
} )
351
351
}
352
352
353
+ /// Print `<...>` around what `f` prints.
354
+ fn generic_delimiters < ' gcx , ' tcx > (
355
+ mut self : PrintCx < ' _ , ' gcx , ' tcx , Self > ,
356
+ f : impl FnOnce ( PrintCx < ' _ , ' gcx , ' tcx , Self > ) -> Result < Self , Self :: Error > ,
357
+ ) -> Result < Self , Self :: Error > {
358
+ write ! ( self . printer, "<" ) ?;
359
+ let mut printer = f ( self ) ?;
360
+ write ! ( printer, ">" ) ?;
361
+ Ok ( printer)
362
+ }
363
+
353
364
/// Return `true` if the region should be printed in path generic args
354
365
/// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`.
355
366
fn always_print_region_in_paths (
@@ -746,7 +757,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
746
757
}
747
758
748
759
pub fn pretty_path_qualified (
749
- mut self ,
760
+ self ,
750
761
self_ty : Ty < ' tcx > ,
751
762
trait_ref : Option < ty:: TraitRef < ' tcx > > ,
752
763
ns : Namespace ,
@@ -772,20 +783,19 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
772
783
}
773
784
}
774
785
775
- write ! ( self . printer, "<" ) ?;
776
- nest ! ( self , |cx| self_ty. print_display( cx) ) ;
777
- if let Some ( trait_ref) = trait_ref {
778
- write ! ( self . printer, " as " ) ?;
779
- nest ! ( self , |cx| cx. print_def_path(
780
- trait_ref. def_id,
781
- Some ( trait_ref. substs) ,
782
- Namespace :: TypeNS ,
783
- iter:: empty( ) ,
784
- ) ) ;
785
- }
786
- write ! ( self . printer, ">" ) ?;
787
-
788
- Ok ( self . printer )
786
+ self . generic_delimiters ( |mut cx| {
787
+ nest ! ( cx, |cx| self_ty. print_display( cx) ) ;
788
+ if let Some ( trait_ref) = trait_ref {
789
+ write ! ( cx. printer, " as " ) ?;
790
+ nest ! ( cx, |cx| cx. print_def_path(
791
+ trait_ref. def_id,
792
+ Some ( trait_ref. substs) ,
793
+ Namespace :: TypeNS ,
794
+ iter:: empty( ) ,
795
+ ) ) ;
796
+ }
797
+ Ok ( cx. printer )
798
+ } )
789
799
}
790
800
791
801
pub fn pretty_path_append_impl (
@@ -796,17 +806,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
796
806
self_ty : Ty < ' tcx > ,
797
807
trait_ref : Option < ty:: TraitRef < ' tcx > > ,
798
808
) -> Result < P :: Path , P :: Error > {
799
- // HACK(eddyb) going through `path_append` means symbol name
800
- // computation gets to handle its equivalent of `::` correctly.
801
- nest ! ( self , |cx| cx. path_append( print_prefix, "<impl " ) ) ;
802
- if let Some ( trait_ref) = trait_ref {
803
- nest ! ( self , |cx| trait_ref. print_display( cx) ) ;
804
- write ! ( self . printer, " for " ) ?;
805
- }
806
- nest ! ( self , |cx| self_ty. print_display( cx) ) ;
807
- write ! ( self . printer, ">" ) ?;
809
+ nest ! ( self , print_prefix) ;
808
810
809
- Ok ( self . printer )
811
+ self . generic_delimiters ( |mut cx| {
812
+ write ! ( cx. printer, "impl " ) ?;
813
+ if let Some ( trait_ref) = trait_ref {
814
+ nest ! ( cx, |cx| trait_ref. print_display( cx) ) ;
815
+ write ! ( cx. printer, " for " ) ?;
816
+ }
817
+ nest ! ( cx, |cx| self_ty. print_display( cx) ) ;
818
+
819
+ Ok ( cx. printer )
820
+ } )
810
821
}
811
822
812
823
pub fn pretty_path_generic_args (
@@ -821,18 +832,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
821
832
) -> Result < P :: Path , P :: Error > {
822
833
nest ! ( self , |cx| print_prefix( cx) ) ;
823
834
824
- let mut empty = true ;
825
- let mut start_or_continue = |cx : & mut Self , start : & str , cont : & str | {
826
- write ! ( cx. printer, "{}" , if empty {
827
- empty = false ;
828
- start
829
- } else {
830
- cont
831
- } )
832
- } ;
833
-
834
- let start = if ns == Namespace :: ValueNS { "::<" } else { "<" } ;
835
-
836
835
// Don't print `'_` if there's no printed region.
837
836
let print_regions = params. iter ( ) . any ( |param| {
838
837
match substs[ param. index as usize ] . unpack ( ) {
@@ -861,45 +860,75 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
861
860
} ) . count ( )
862
861
} ;
863
862
864
- for param in & params[ ..params. len ( ) - num_supplied_defaults] {
865
- match substs[ param. index as usize ] . unpack ( ) {
866
- UnpackedKind :: Lifetime ( region) => {
867
- if !print_regions {
868
- continue ;
863
+ let params = & params[ ..params. len ( ) - num_supplied_defaults] ;
864
+ let mut args = params. iter ( ) . map ( |param| {
865
+ substs[ param. index as usize ] . unpack ( )
866
+ } ) . filter ( |arg| {
867
+ match arg {
868
+ UnpackedKind :: Lifetime ( _) => print_regions,
869
+ _ => true ,
870
+ }
871
+ } ) ;
872
+ let arg0 = args. next ( ) ;
873
+
874
+ let mut projections = projections;
875
+ let projection0 = projections. next ( ) ;
876
+
877
+ if arg0. is_none ( ) && projection0. is_none ( ) {
878
+ return Ok ( self . printer ) ;
879
+ }
880
+
881
+ // FIXME(eddyb) move this into `generic_delimiters`.
882
+ if ns == Namespace :: ValueNS {
883
+ write ! ( self . printer, "::" ) ?;
884
+ }
885
+
886
+ self . generic_delimiters ( |mut cx| {
887
+ let mut empty = true ;
888
+ let mut maybe_comma = |cx : & mut Self | {
889
+ if empty {
890
+ empty = false ;
891
+ Ok ( ( ) )
892
+ } else {
893
+ write ! ( cx. printer, ", " )
894
+ }
895
+ } ;
896
+
897
+ for arg in arg0. into_iter ( ) . chain ( args) {
898
+ maybe_comma ( & mut cx) ?;
899
+
900
+ match arg {
901
+ UnpackedKind :: Lifetime ( region) => {
902
+ if !cx. print_region_outputs_anything ( region) {
903
+ // This happens when the value of the region
904
+ // parameter is not easily serialized. This may be
905
+ // because the user omitted it in the first place,
906
+ // or because it refers to some block in the code,
907
+ // etc. I'm not sure how best to serialize this.
908
+ write ! ( cx. printer, "'_" ) ?;
909
+ } else {
910
+ nest ! ( cx, |cx| region. print_display( cx) ) ;
911
+ }
869
912
}
870
- start_or_continue ( & mut self , start, ", " ) ?;
871
- if !self . print_region_outputs_anything ( region) {
872
- // This happens when the value of the region
873
- // parameter is not easily serialized. This may be
874
- // because the user omitted it in the first place,
875
- // or because it refers to some block in the code,
876
- // etc. I'm not sure how best to serialize this.
877
- write ! ( self . printer, "'_" ) ?;
878
- } else {
879
- nest ! ( self , |cx| region. print_display( cx) ) ;
913
+ UnpackedKind :: Type ( ty) => {
914
+ nest ! ( cx, |cx| ty. print_display( cx) ) ;
915
+ }
916
+ UnpackedKind :: Const ( ct) => {
917
+ nest ! ( cx, |cx| ct. print_display( cx) ) ;
880
918
}
881
- }
882
- UnpackedKind :: Type ( ty) => {
883
- start_or_continue ( & mut self , start, ", " ) ?;
884
- nest ! ( self , |cx| ty. print_display( cx) ) ;
885
- }
886
- UnpackedKind :: Const ( ct) => {
887
- start_or_continue ( & mut self , start, ", " ) ?;
888
- nest ! ( self , |cx| ct. print_display( cx) ) ;
889
919
}
890
920
}
891
- }
892
921
893
- for projection in projections {
894
- start_or_continue ( & mut self , start, ", " ) ?;
895
- write ! ( self . printer, "{}=" ,
896
- self . tcx. associated_item( projection. item_def_id) . ident) ?;
897
- nest ! ( self , |cx| projection. ty. print_display( cx) ) ;
898
- }
922
+ for projection in projection0. into_iter ( ) . chain ( projections) {
923
+ maybe_comma ( & mut cx) ?;
899
924
900
- start_or_continue ( & mut self , "" , ">" ) ?;
925
+ write ! ( cx. printer, "{}=" ,
926
+ cx. tcx. associated_item( projection. item_def_id) . ident) ?;
927
+ nest ! ( cx, |cx| projection. ty. print_display( cx) ) ;
928
+ }
901
929
902
- Ok ( self . printer )
930
+ Ok ( cx. printer )
931
+ } )
903
932
}
904
933
}
905
934
@@ -1087,7 +1116,15 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
1087
1116
self_ty : Ty < ' tcx > ,
1088
1117
trait_ref : Option < ty:: TraitRef < ' tcx > > ,
1089
1118
) -> Result < Self :: Path , Self :: Error > {
1090
- self . pretty_path_append_impl ( print_prefix, self_ty, trait_ref)
1119
+ self . pretty_path_append_impl ( |cx| {
1120
+ let mut printer = print_prefix ( cx) ?;
1121
+
1122
+ if !printer. empty {
1123
+ write ! ( printer, "::" ) ?;
1124
+ }
1125
+
1126
+ Ok ( printer)
1127
+ } , self_ty, trait_ref)
1091
1128
}
1092
1129
fn path_append < ' gcx , ' tcx > (
1093
1130
self : PrintCx < ' _ , ' gcx , ' tcx , Self > ,
@@ -1126,7 +1163,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
1126
1163
impl < F : fmt:: Write > PrettyPrinter for FmtPrinter < F > {
1127
1164
fn nest < ' a , ' gcx , ' tcx , E > (
1128
1165
mut self : PrintCx < ' a , ' gcx , ' tcx , Self > ,
1129
- f : impl for < ' b > FnOnce ( PrintCx < ' b , ' gcx , ' tcx , Self > ) -> Result < Self , E > ,
1166
+ f : impl FnOnce ( PrintCx < ' _ , ' gcx , ' tcx , Self > ) -> Result < Self , E > ,
1130
1167
) -> Result < PrintCx < ' a , ' gcx , ' tcx , Self > , E > {
1131
1168
let was_empty = std:: mem:: replace ( & mut self . printer . empty , true ) ;
1132
1169
let mut printer = f ( PrintCx {
0 commit comments