]> git.lizzy.rs Git - rust.git/commitdiff
Add format_trait_ref_then_update_result
authortopecongiro <seuchida@gmail.com>
Sat, 10 Jun 2017 11:37:34 +0000 (20:37 +0900)
committertopecongiro <seuchida@gmail.com>
Sat, 10 Jun 2017 12:07:38 +0000 (21:07 +0900)
src/items.rs
tests/source/big-impl-rfc.rs [new file with mode: 0644]
tests/target/big-impl-rfc.rs [new file with mode: 0644]

index f228bdf9d08ea54a97e74289eb530727ac719d60..a0b50bd50b71cba4db1f0e8dea57da4c108ee348 100644 (file)
@@ -678,83 +678,30 @@ fn format_impl_ref_and_type(context: &RewriteContext,
                                                0);
         let mut generics_str =
             try_opt!(rewrite_generics(context, generics, shape, shape.width, mk_sp(lo, hi)));
+        add_polarity(&mut generics_str, &polarity, trait_ref.is_some());
 
-        if polarity == ast::ImplPolarity::Negative {
-            generics_str.push_str(" !");
-        }
-
-        let mut retry_with_multiline = true;
         if let Some(ref trait_ref) = *trait_ref {
-            if polarity != ast::ImplPolarity::Negative {
-                generics_str.push_str(" ");
-            }
-            let used_space = if generics_str.contains('\n') {
-                last_line_width(&generics_str)
-            } else {
-                result.len() + generics_str.len()
-            };
-            let budget = context
-                .config
-                .max_width()
-                .checked_sub(used_space)
-                .unwrap_or(0);
-            let indent = offset + used_space;
-            if let Some(trait_ref_str) = trait_ref.rewrite(context, Shape::legacy(budget, indent)) {
-                if !trait_ref_str.contains('\n') {
-                    result.push_str(&generics_str);
-                    result.push_str(&trait_ref_str);
-                    if split_at_for {
-                        result.push('\n');
-                        // Add indentation of one additional tab.
-                        result.push_str(&offset
-                                            .block_indent(context.config)
-                                            .to_string(context.config));
-                        result.push_str("for");
-                    } else {
-                        result.push_str(" for");
-                    }
-                    retry_with_multiline = false;
-                }
-            }
-            if retry_with_multiline {
+            let success = format_trait_ref_then_update_result(context,
+                                                              &trait_ref,
+                                                              offset,
+                                                              &generics_str,
+                                                              split_at_for,
+                                                              &mut result);
+            if !success {
                 let mut generics_str =
                     try_opt!(rewrite_generics(context, generics, shape, 0, mk_sp(lo, hi)));
-                if polarity == ast::ImplPolarity::Negative {
-                    generics_str.push_str(" !");
-                } else {
-                    generics_str.push_str(" ");
-                }
-                let used_space = if generics_str.contains('\n') {
-                    last_line_width(&generics_str)
-                } else {
-                    result.len() + generics_str.len()
-                };
-                let budget = context
-                    .config
-                    .max_width()
-                    .checked_sub(used_space)
-                    .unwrap_or(0);
-                let indent = offset + used_space;
-                if let Some(trait_ref_str) =
-                    trait_ref.rewrite(context, Shape::legacy(budget, indent)) {
-                    result.push_str(&generics_str);
-                    result.push_str(&trait_ref_str);
-                    if split_at_for {
-                        result.push('\n');
-                        // Add indentation of one additional tab.
-                        result.push_str(&offset
-                                            .block_indent(context.config)
-                                            .to_string(context.config));
-                        result.push_str("for");
-                    } else {
-                        result.push_str(" for");
-                    }
+                add_polarity(&mut generics_str, &polarity, true);
+                if !format_trait_ref_then_update_result(context,
+                                                        &trait_ref,
+                                                        offset,
+                                                        &generics_str,
+                                                        split_at_for,
+                                                        &mut result) {
+                    // FIXME: should be unreachable
+                    return None;
                 }
             }
         } else {
-            if polarity == ast::ImplPolarity::Negative {
-                generics_str.push_str(" ");
-            }
             result.push_str(&generics_str);
         }
 
@@ -790,6 +737,55 @@ fn format_impl_ref_and_type(context: &RewriteContext,
     }
 }
 
+// Returns false if failed to update result: then, try using multiline.
+fn format_trait_ref_then_update_result(context: &RewriteContext,
+                                       trait_ref: &ast::TraitRef,
+                                       offset: Indent,
+                                       generics_str: &str,
+                                       split_at_for: bool,
+                                       result: &mut String)
+                                       -> bool {
+    let used_space = if generics_str.contains('\n') {
+        last_line_width(&generics_str)
+    } else {
+        result.len() + generics_str.len()
+    };
+    let budget = context
+        .config
+        .max_width()
+        .checked_sub(used_space)
+        .unwrap_or(0);
+    let indent = offset + used_space;
+    if let Some(trait_ref_str) = trait_ref.rewrite(context, Shape::legacy(budget, indent)) {
+        if !trait_ref_str.contains('\n') {
+            result.push_str(&generics_str);
+            result.push_str(&trait_ref_str);
+            if split_at_for {
+                result.push('\n');
+                // Add indentation of one additional tab.
+                let for_offset = match context.config.where_style() {
+                    Style::Legacy => offset.block_indent(context.config),
+                    Style::Rfc => offset,
+                };
+                result.push_str(&for_offset.to_string(context.config));
+                result.push_str("for");
+            } else {
+                result.push_str(" for");
+            }
+            return true;
+        }
+    }
+    false
+}
+
+fn add_polarity(s: &mut String, polarity: &ast::ImplPolarity, has_trait_ref: bool) {
+    if polarity == &ast::ImplPolarity::Negative {
+        s.push_str(" !")
+    } else if has_trait_ref {
+        s.push(' ')
+    }
+}
+
 pub fn format_struct(context: &RewriteContext,
                      item_name: &str,
                      ident: ast::Ident,
diff --git a/tests/source/big-impl-rfc.rs b/tests/source/big-impl-rfc.rs
new file mode 100644 (file)
index 0000000..167f654
--- /dev/null
@@ -0,0 +1,114 @@
+// rustfmt-fn_args_layout: Block
+// rustfmt-fn_call_style: Block
+// rustfmt-generics_indent: Block
+// rustfmt-where_style: Rfc
+
+// #1357
+impl<
+    'a,
+    Select,
+    From,
+    Distinct,
+    Where,
+    Order,
+    Limit,
+    Offset,
+    Groupby,
+    DB,
+> InternalBoxedDsl<'a, DB>
+    for SelectStatement<
+        Select,
+        From,
+        Distinct,
+        Where,
+        Order,
+        Limit,
+        Offset,
+        GroupBy,
+    > where
+        DB: Backend,
+        Select: QueryFragment<DB> + SelectableExpression<From> + 'a,
+        Distinct: QueryFragment<DB> + 'a,
+        Where: Into<Option<Box<QueryFragment<DB> + 'a>>>,
+        Order: QueryFragment<DB> + 'a,
+        Limit: QueryFragment<DB> + 'a,
+        Offset: QueryFragment<DB> + 'a,
+{
+    type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>;
+
+    fn internal_into_boxed(self) -> Self::Output {
+        BoxedSelectStatement::new(
+            Box::new(self.select),
+            self.from,
+            Box::new(self.distinct),
+            self.where_clause.into(),
+            Box::new(self.order),
+            Box::new(self.limit),
+            Box::new(self.offset),
+        )
+    }
+}
+
+// #1369
+impl<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo for Bar {
+    fn foo() {}
+}
+impl Foo<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> for Bar {
+    fn foo() {}
+}
+impl<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> for Bar {
+    fn foo() {}
+}
+impl<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo for Bar<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> {
+    fn foo() {}
+}
+impl Foo<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> for Bar<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> {
+    fn foo() {}
+}
+impl<
+    ExcessivelyLongGenericName,
+      ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> for Bar<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> {
+    fn foo() {}
+}
diff --git a/tests/target/big-impl-rfc.rs b/tests/target/big-impl-rfc.rs
new file mode 100644 (file)
index 0000000..18fa59c
--- /dev/null
@@ -0,0 +1,65 @@
+// rustfmt-fn_args_layout: Block
+// rustfmt-fn_call_style: Block
+// rustfmt-generics_indent: Block
+// rustfmt-where_style: Rfc
+
+// #1357
+impl<'a, Select, From, Distinct, Where, Order, Limit, Offset, Groupby, DB> InternalBoxedDsl<'a, DB>
+for SelectStatement<Select, From, Distinct, Where, Order, Limit, Offset, GroupBy>
+where
+    DB: Backend,
+    Select: QueryFragment<DB> + SelectableExpression<From> + 'a,
+    Distinct: QueryFragment<DB> + 'a,
+    Where: Into<Option<Box<QueryFragment<DB> + 'a>>>,
+    Order: QueryFragment<DB> + 'a,
+    Limit: QueryFragment<DB> + 'a,
+    Offset: QueryFragment<DB> + 'a,
+{
+    type Output = BoxedSelectStatement<'a, Select::SqlTypeForSelect, From, DB>;
+
+    fn internal_into_boxed(self) -> Self::Output {
+        BoxedSelectStatement::new(
+            Box::new(self.select),
+            self.from,
+            Box::new(self.distinct),
+            self.where_clause.into(),
+            Box::new(self.order),
+            Box::new(self.limit),
+            Box::new(self.offset),
+        )
+    }
+}
+
+// #1369
+impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo
+for Bar {
+    fn foo() {}
+}
+impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName>
+for Bar {
+    fn foo() {}
+}
+impl<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName>
+for Bar {
+    fn foo() {}
+}
+impl<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> Foo
+for Bar<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> {
+    fn foo() {}
+}
+impl Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName>
+for Bar<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> {
+    fn foo() {}
+}
+impl<
+    ExcessivelyLongGenericName,
+    ExcessivelyLongGenericName,
+    AnotherExcessivelyLongGenericName,
+> Foo<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName>
+for Bar<ExcessivelyLongGenericName, ExcessivelyLongGenericName, AnotherExcessivelyLongGenericName> {
+    fn foo() {}
+}