about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Bar-On <61089727+davidBar-On@users.noreply.github.com>2022-08-09 16:30:49 +0300
committerGitHub <noreply@github.com>2022-08-09 09:30:49 -0400
commitea017d7f84e218c4a8048d2ecd9d63bbda014209 (patch)
tree5c3a626cb18bc6949ddfb488517252689968fa35 /src
parenta67d909627b7ec93e315bfe1c66895904055c75c (diff)
downloadrust-ea017d7f84e218c4a8048d2ecd9d63bbda014209.tar.gz
rust-ea017d7f84e218c4a8048d2ecd9d63bbda014209.zip
Backport PR #4730 (#5390)
* Backport PR #4730 that fix issue #4689

* Test files for each Verion One and Two

* Simplify per review comment - use defer and matches!

* Changes per reviewer comments for reducing indentations
Diffstat (limited to 'src')
-rw-r--r--src/types.rs43
1 files changed, 39 insertions, 4 deletions
diff --git a/src/types.rs b/src/types.rs
index 2627886db10..25ad587ba85 100644
--- a/src/types.rs
+++ b/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,23 @@ fn join_bounds_inner(
         },
     )?;
 
-    if !force_newline
-        && items.len() > 1
-        && (result.0.contains('\n') || result.0.len() > shape.width)
-    {
+    // Whether retry the function with forced newline is needed:
+    //   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 =
+        if force_newline || (!result.0.contains('\n') && result.0.len() <= shape.width) {
+            false
+        } else {
+            if items.len() > 1 {
+                true
+            } else {
+                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)