diff options
Diffstat (limited to 'src/tools/rustfmt/src/types.rs')
-rw-r--r-- | src/tools/rustfmt/src/types.rs | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index c1991e8d2..01e2fb6e6 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -941,6 +941,28 @@ fn join_bounds_inner( ast::GenericBound::Trait(..) => last_line_extendable(s), }; + // Whether a GenericBound item is a PathSegment segment that includes internal array + // that contains more than one item + let is_item_with_multi_items_array = |item: &ast::GenericBound| match item { + ast::GenericBound::Trait(ref poly_trait_ref, ..) => { + let segments = &poly_trait_ref.trait_ref.path.segments; + if segments.len() > 1 { + true + } else { + if let Some(args_in) = &segments[0].args { + matches!( + args_in.deref(), + ast::GenericArgs::AngleBracketed(bracket_args) + if bracket_args.args.len() > 1 + ) + } else { + false + } + } + } + _ => false, + }; + let result = items.iter().enumerate().try_fold( (String::new(), None, false), |(strs, prev_trailing_span, prev_extendable), (i, item)| { @@ -1035,10 +1057,24 @@ fn join_bounds_inner( }, )?; - if !force_newline - && items.len() > 1 - && (result.0.contains('\n') || result.0.len() > shape.width) - { + // Whether to retry with a forced newline: + // Only if result is not already multiline and did not exceed line width, + // and either there is more than one item; + // or the single item is of type `Trait`, + // and any of the internal arrays contains more than one item; + let retry_with_force_newline = match context.config.version() { + Version::One => { + !force_newline + && items.len() > 1 + && (result.0.contains('\n') || result.0.len() > shape.width) + } + Version::Two if force_newline => false, + Version::Two if (!result.0.contains('\n') && result.0.len() <= shape.width) => false, + Version::Two if items.len() > 1 => true, + Version::Two => is_item_with_multi_items_array(&items[0]), + }; + + if retry_with_force_newline { join_bounds_inner(context, shape, items, need_indent, true) } else { Some(result.0) |