@@ -874,57 +874,131 @@ fn join_bounds(
874874 items : & [ ast:: GenericBound ] ,
875875 need_indent : bool ,
876876) -> 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+ }
892879
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( ) ) ;
907888
889+ let generic_bounds_in_order = is_generic_bounds_in_order ( items) ;
908890 let is_bound_extendable = |s : & str , b : & ast:: GenericBound | match b {
909891 ast:: GenericBound :: Outlives ( ..) => true ,
910892 ast:: GenericBound :: Trait ( ..) => last_line_extendable ( s) ,
911893 } ;
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- }
926894
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+ }
9281002}
9291003
9301004pub ( crate ) fn can_be_overflowed_type (
0 commit comments