@@ -874,57 +874,131 @@ fn join_bounds(
874
874
items : & [ ast:: GenericBound ] ,
875
875
need_indent : bool ,
876
876
) -> Option < String > {
877
- debug_assert ! ( !items. is_empty( ) ) ;
878
-
879
- // Try to join types in a single line
880
- let joiner = match context. config . type_punctuation_density ( ) {
881
- TypeDensity :: Compressed => "+" ,
882
- TypeDensity :: Wide => " + " ,
883
- } ;
884
- let type_strs = items
885
- . iter ( )
886
- . map ( |item| item. rewrite ( context, shape) )
887
- . collect :: < Option < Vec < _ > > > ( ) ?;
888
- let result = type_strs. join ( joiner) ;
889
- if items. len ( ) <= 1 || ( !result. contains ( '\n' ) && result. len ( ) <= shape. width ) {
890
- return Some ( result) ;
891
- }
877
+ join_bounds_inner ( context, shape, items, need_indent, false )
878
+ }
892
879
893
- // We need to use multiple lines.
894
- let ( type_strs, offset) = if need_indent {
895
- // Rewrite with additional indentation.
896
- let nested_shape = shape
897
- . block_indent ( context. config . tab_spaces ( ) )
898
- . with_max_width ( context. config ) ;
899
- let type_strs = items
900
- . iter ( )
901
- . map ( |item| item. rewrite ( context, nested_shape) )
902
- . collect :: < Option < Vec < _ > > > ( ) ?;
903
- ( type_strs, nested_shape. indent )
904
- } else {
905
- ( type_strs, shape. indent )
906
- } ;
880
+ fn join_bounds_inner (
881
+ context : & RewriteContext < ' _ > ,
882
+ shape : Shape ,
883
+ items : & [ ast:: GenericBound ] ,
884
+ need_indent : bool ,
885
+ force_newline : bool ,
886
+ ) -> Option < String > {
887
+ debug_assert ! ( !items. is_empty( ) ) ;
907
888
889
+ let generic_bounds_in_order = is_generic_bounds_in_order ( items) ;
908
890
let is_bound_extendable = |s : & str , b : & ast:: GenericBound | match b {
909
891
ast:: GenericBound :: Outlives ( ..) => true ,
910
892
ast:: GenericBound :: Trait ( ..) => last_line_extendable ( s) ,
911
893
} ;
912
- let mut result = String :: with_capacity ( 128 ) ;
913
- result. push_str ( & type_strs[ 0 ] ) ;
914
- let mut can_be_put_on_the_same_line = is_bound_extendable ( & result, & items[ 0 ] ) ;
915
- let generic_bounds_in_order = is_generic_bounds_in_order ( items) ;
916
- for ( bound, bound_str) in items[ 1 ..] . iter ( ) . zip ( type_strs[ 1 ..] . iter ( ) ) {
917
- if generic_bounds_in_order && can_be_put_on_the_same_line {
918
- result. push_str ( joiner) ;
919
- } else {
920
- result. push_str ( & offset. to_string_with_newline ( context. config ) ) ;
921
- result. push_str ( "+ " ) ;
922
- }
923
- result. push_str ( bound_str) ;
924
- can_be_put_on_the_same_line = is_bound_extendable ( bound_str, bound) ;
925
- }
926
894
927
- Some ( result)
895
+ let result = items. iter ( ) . enumerate ( ) . try_fold (
896
+ ( String :: new ( ) , None , false ) ,
897
+ |( strs, prev_trailing_span, prev_extendable) , ( i, item) | {
898
+ let trailing_span = if i < items. len ( ) - 1 {
899
+ let hi = context
900
+ . snippet_provider
901
+ . span_before ( mk_sp ( items[ i + 1 ] . span ( ) . lo ( ) , item. span ( ) . hi ( ) ) , "+" ) ;
902
+
903
+ Some ( mk_sp ( item. span ( ) . hi ( ) , hi) )
904
+ } else {
905
+ None
906
+ } ;
907
+ let ( leading_span, has_leading_comment) = if i > 0 {
908
+ let lo = context
909
+ . snippet_provider
910
+ . span_after ( mk_sp ( items[ i - 1 ] . span ( ) . hi ( ) , item. span ( ) . lo ( ) ) , "+" ) ;
911
+
912
+ let span = mk_sp ( lo, item. span ( ) . lo ( ) ) ;
913
+
914
+ let has_comments = contains_comment ( context. snippet ( span) ) ;
915
+
916
+ ( Some ( mk_sp ( lo, item. span ( ) . lo ( ) ) ) , has_comments)
917
+ } else {
918
+ ( None , false )
919
+ } ;
920
+ let prev_has_trailing_comment = match prev_trailing_span {
921
+ Some ( ts) => contains_comment ( context. snippet ( ts) ) ,
922
+ _ => false ,
923
+ } ;
924
+
925
+ let shape = if i > 0 && need_indent && force_newline {
926
+ shape
927
+ . block_indent ( context. config . tab_spaces ( ) )
928
+ . with_max_width ( context. config )
929
+ } else {
930
+ shape
931
+ } ;
932
+ let whitespace = if force_newline && ( !prev_extendable || !generic_bounds_in_order) {
933
+ shape
934
+ . indent
935
+ . to_string_with_newline ( context. config )
936
+ . to_string ( )
937
+ } else {
938
+ String :: from ( " " )
939
+ } ;
940
+
941
+ let joiner = match context. config . type_punctuation_density ( ) {
942
+ TypeDensity :: Compressed => String :: from ( "+" ) ,
943
+ TypeDensity :: Wide => whitespace + "+ " ,
944
+ } ;
945
+ let joiner = if has_leading_comment {
946
+ joiner. trim_end ( )
947
+ } else {
948
+ & joiner
949
+ } ;
950
+ let joiner = if prev_has_trailing_comment {
951
+ joiner. trim_start ( )
952
+ } else {
953
+ joiner
954
+ } ;
955
+
956
+ let ( trailing_str, extendable) = if i == 0 {
957
+ let bound_str = item. rewrite ( context, shape) ?;
958
+ let bound_str_clone = bound_str. clone ( ) ;
959
+ ( bound_str, is_bound_extendable ( & bound_str_clone, item) )
960
+ } else {
961
+ let bound_str = & item. rewrite ( context, shape) ?;
962
+ match leading_span {
963
+ Some ( ls) if has_leading_comment => (
964
+ combine_strs_with_missing_comments (
965
+ context, joiner, bound_str, ls, shape, true ,
966
+ ) ?,
967
+ is_bound_extendable ( bound_str, item) ,
968
+ ) ,
969
+ _ => (
970
+ String :: from ( joiner) + bound_str,
971
+ is_bound_extendable ( bound_str, item) ,
972
+ ) ,
973
+ }
974
+ } ;
975
+ match prev_trailing_span {
976
+ Some ( ts) if prev_has_trailing_comment => combine_strs_with_missing_comments (
977
+ context,
978
+ & strs,
979
+ & trailing_str,
980
+ ts,
981
+ shape,
982
+ true ,
983
+ )
984
+ . map ( |v| ( v, trailing_span, extendable) ) ,
985
+ _ => Some ( (
986
+ String :: from ( strs) + & trailing_str,
987
+ trailing_span,
988
+ extendable,
989
+ ) ) ,
990
+ }
991
+ } ,
992
+ ) ?;
993
+
994
+ if !force_newline
995
+ && items. len ( ) > 1
996
+ && ( result. 0 . contains ( '\n' ) || result. 0 . len ( ) > shape. width )
997
+ {
998
+ join_bounds_inner ( context, shape, items, need_indent, true )
999
+ } else {
1000
+ Some ( result. 0 )
1001
+ }
928
1002
}
929
1003
930
1004
pub ( crate ) fn can_be_overflowed_type (
0 commit comments