]> git.lizzy.rs Git - rust.git/commitdiff
Use multi line when type bounds does not fit in a single line
authortopecongiro <seuchida@gmail.com>
Sun, 11 Jun 2017 14:26:49 +0000 (23:26 +0900)
committertopecongiro <seuchida@gmail.com>
Sun, 11 Jun 2017 14:26:49 +0000 (23:26 +0900)
src/expr.rs
src/items.rs
src/types.rs

index aa5913e5f0fa9bb613558f67400b2de9f49eb99c..04778b6ddcab1dae55848ca83539be70fe1e86b5 100644 (file)
@@ -2063,12 +2063,12 @@ enum StructLitField<'a> {
     // FIXME if context.config.struct_lit_style() == Visual, but we run out
     // of space, we should fall back to BlockIndent.
 }
+
 pub fn struct_lit_field_separator(config: &Config) -> &str {
     colon_spaces(config.space_before_struct_lit_field_colon(),
                  config.space_after_struct_lit_field_colon())
 }
 
-
 fn rewrite_field(context: &RewriteContext, field: &ast::Field, shape: Shape) -> Option<String> {
     let name = &field.ident.node.to_string();
     if field.is_shorthand {
index 10ab6fe72dfefee17731925fecaa41272a5377be..78226624c4f0f073b8ff613aa9b0704117112ba1 100644 (file)
@@ -21,7 +21,8 @@
 use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed};
 use visitor::FmtVisitor;
 use rewrite::{Rewrite, RewriteContext};
-use config::{Config, IndentStyle, Density, ReturnIndent, BraceStyle, Style, TypeDensity};
+use config::{Config, IndentStyle, Density, ReturnIndent, BraceStyle, Style};
+use types::join_bounds;
 
 use syntax::{ast, abi, ptr, symbol};
 use syntax::codemap::{Span, BytePos};
@@ -666,7 +667,7 @@ fn format_impl_ref_and_type(context: &RewriteContext,
                                                                context.config),
                                                0);
         let generics_str =
-            try_opt!(rewrite_generics(context, generics, shape, shape.width, mk_sp(lo, hi)));
+            try_opt!(rewrite_generics_inner(context, generics, shape, shape.width, mk_sp(lo, hi)));
 
         let polarity_str = if polarity == ast::ImplPolarity::Negative {
             "!"
@@ -684,7 +685,7 @@ fn format_impl_ref_and_type(context: &RewriteContext,
                                                               &mut result);
             if !success {
                 let generics_str =
-                    try_opt!(rewrite_generics(context, generics, shape, 0, mk_sp(lo, hi)));
+                    try_opt!(rewrite_generics_inner(context, generics, shape, 0, mk_sp(lo, hi)));
                 if !format_trait_ref_then_update_result(context,
                                                         &trait_ref,
                                                         offset,
@@ -839,15 +840,9 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
 
         let body_lo = context.codemap.span_after(item.span, "{");
 
-        let generics_indent = offset + last_line_width(&result);
-        let shape = generics_shape_from_config(context.config,
-                                               Shape::indented(generics_indent, context.config),
-                                               0);
-        let generics_str = try_opt!(rewrite_generics(context,
-                                                     generics,
-                                                     shape,
-                                                     shape.width,
-                                                     mk_sp(item.span.lo, body_lo)));
+        let shape = Shape::indented(offset + last_line_width(&result), context.config);
+        let generics_str =
+            try_opt!(rewrite_generics(context, generics, shape, mk_sp(item.span.lo, body_lo)));
         result.push_str(&generics_str);
 
         let trait_bound_str =
@@ -1091,16 +1086,9 @@ fn format_tuple_struct(context: &RewriteContext,
 
     let where_clause_str = match generics {
         Some(generics) => {
-            let generics_indent = offset + last_line_width(&header_str);
-            let shape = generics_shape_from_config(context.config,
-                                                   Shape::indented(generics_indent,
-                                                                   context.config),
-                                                   0);
-            let generics_str = try_opt!(rewrite_generics(context,
-                                                         generics,
-                                                         shape,
-                                                         shape.width,
-                                                         mk_sp(span.lo, body_lo)));
+            let shape = Shape::indented(offset + last_line_width(&header_str), context.config);
+            let g_span = mk_sp(span.lo, body_lo);
+            let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
             result.push_str(&generics_str);
 
             let where_budget = try_opt!(context
@@ -1227,16 +1215,10 @@ pub fn rewrite_type_alias(context: &RewriteContext,
     result.push_str("type ");
     result.push_str(&ident.to_string());
 
-    let generics_indent = indent + result.len();
-    let generics_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo);
-    let shape = generics_shape_from_config(context.config,
-                                           try_opt!(Shape::indented(generics_indent,
-                                                                    context.config)
-                                                        .sub_width(" =".len())),
-                                           0);
-    let generics_str =
-        try_opt!(rewrite_generics(context, generics, shape, shape.width, generics_span));
-
+    // 2 = `= `
+    let shape = try_opt!(Shape::indented(indent + result.len(), context.config).sub_width(2));
+    let g_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo);
+    let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
     result.push_str(&generics_str);
 
     let where_budget = try_opt!(context
@@ -1470,23 +1452,14 @@ pub fn rewrite_associated_type(ident: ast::Ident,
     let prefix = format!("type {}", ident);
 
     let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
-        let joiner = match context.config.type_punctuation_density() {
-            TypeDensity::Compressed => "+",
-            TypeDensity::Wide => " + ",
-        };
+        let shape = Shape::legacy(context.config.max_width(), indent);
         let bounds: &[_] = ty_param_bounds;
-        let bound_str =
-            try_opt!(bounds
-                         .iter()
-                         .map(|ty_bound| {
-                                  ty_bound.rewrite(context,
-                                                   Shape::legacy(context.config.max_width(),
-                                                                 indent))
-                              })
-                         .collect::<Option<Vec<_>>>())
-                .join(joiner);
+        let bound_str = try_opt!(bounds
+                                     .iter()
+                                     .map(|ty_bound| ty_bound.rewrite(context, shape))
+                                     .collect::<Option<Vec<_>>>());
         if bounds.len() > 0 {
-            format!(": {}", bound_str)
+            format!(": {}", join_bounds(context, shape, &bound_str))
         } else {
             String::new()
         }
@@ -1711,13 +1684,9 @@ fn rewrite_fn_base(context: &RewriteContext,
     result.push_str(&ident.to_string());
 
     // Generics.
-    let generics_indent = indent + last_line_width(&result);
-    let generics_span = mk_sp(span.lo, span_for_return(&fd.output).lo);
-    let shape = generics_shape_from_config(context.config,
-                                           Shape::indented(generics_indent, context.config),
-                                           0);
-    let generics_str =
-        try_opt!(rewrite_generics(context, generics, shape, shape.width, generics_span));
+    let shape = Shape::indented(indent + last_line_width(&result), context.config);
+    let g_span = mk_sp(span.lo, span_for_return(&fd.output).lo);
+    let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
     result.push_str(&generics_str);
 
     let snuggle_angle_bracket = generics_str
@@ -2182,9 +2151,19 @@ fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
 fn rewrite_generics(context: &RewriteContext,
                     generics: &ast::Generics,
                     shape: Shape,
-                    one_line_width: usize,
                     span: Span)
                     -> Option<String> {
+    let shape = generics_shape_from_config(context.config, shape, 0);
+    rewrite_generics_inner(context, generics, shape, shape.width, span)
+        .or_else(|| rewrite_generics_inner(context, generics, shape, 0, span))
+}
+
+fn rewrite_generics_inner(context: &RewriteContext,
+                          generics: &ast::Generics,
+                          shape: Shape,
+                          one_line_width: usize,
+                          span: Span)
+                          -> Option<String> {
     // FIXME: convert bounds to where clauses where they get too big or if
     // there is a where clause at all.
     let lifetimes: &[_] = &generics.lifetimes;
@@ -2286,20 +2265,11 @@ fn rewrite_trait_bounds(context: &RewriteContext,
     if bounds.is_empty() {
         return Some(String::new());
     }
-    let joiner = match context.config.type_punctuation_density() {
-        TypeDensity::Compressed => "+",
-        TypeDensity::Wide => " + ",
-    };
     let bound_str = try_opt!(bounds
                                  .iter()
                                  .map(|ty_bound| ty_bound.rewrite(&context, shape))
-                                 .collect::<Option<Vec<_>>>())
-        .join(joiner);
-
-    let mut result = String::new();
-    result.push_str(": ");
-    result.push_str(&bound_str);
-    Some(result)
+                                 .collect::<Option<Vec<_>>>());
+    Some(format!(": {}", join_bounds(context, shape, &bound_str)))
 }
 
 fn rewrite_where_clause_rfc_style(context: &RewriteContext,
@@ -2463,9 +2433,8 @@ fn format_generics(context: &RewriteContext,
                    offset: Indent,
                    span: Span)
                    -> Option<String> {
-    let shape =
-        generics_shape_from_config(context.config, Shape::indented(offset, context.config), 0);
-    let mut result = try_opt!(rewrite_generics(context, generics, shape, shape.width, span));
+    let shape = Shape::indented(offset, context.config);
+    let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
 
     if !generics.where_clause.predicates.is_empty() || result.contains('\n') {
         let budget = try_opt!(context
index 4e74ea8213f10e4179f778aba43cd696d2ac1d9d..d2405f390f1d2e0d93a9fc07793c9d1b030c49e3 100644 (file)
@@ -22,7 +22,7 @@
 use items::{format_generics_item_list, generics_shape_from_config};
 use lists::{itemize_list, format_fn_args};
 use rewrite::{Rewrite, RewriteContext};
-use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp};
+use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp, last_line_width};
 use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple_type};
 use config::TypeDensity;
 
@@ -362,22 +362,15 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                                                             .collect::<Option<Vec<_>>>())
                         .join(", ");
 
-                    let joiner = match context.config.type_punctuation_density() {
-                        TypeDensity::Compressed => "+",
-                        TypeDensity::Wide => " + ",
-                    };
                     // 6 = "for<> ".len()
                     let used_width = lifetime_str.len() + type_str.len() + colon.len() + 6;
-                    let budget = try_opt!(shape.width.checked_sub(used_width));
-                    let bounds_str: String = try_opt!(
-                        bounds
-                            .iter()
-                            .map(|ty_bound| {
-                                ty_bound.rewrite(context,
-                                                 Shape::legacy(budget, shape.indent + used_width))
-                            })
-                            .collect::<Option<Vec<_>>>()
-                    ).join(joiner);
+                    let ty_shape = try_opt!(shape.block_left(used_width));
+                    let bounds: Vec<_> =
+                        try_opt!(bounds
+                                     .iter()
+                                     .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
+                                     .collect());
+                    let bounds_str = join_bounds(context, ty_shape, &bounds);
 
                     if context.config.spaces_within_angle_brackets() && lifetime_str.len() > 0 {
                         format!("for< {} > {}{}{}",
@@ -389,21 +382,14 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                         format!("for<{}> {}{}{}", lifetime_str, type_str, colon, bounds_str)
                     }
                 } else {
-                    let joiner = match context.config.type_punctuation_density() {
-                        TypeDensity::Compressed => "+",
-                        TypeDensity::Wide => " + ",
-                    };
                     let used_width = type_str.len() + colon.len();
-                    let budget = try_opt!(shape.width.checked_sub(used_width));
-                    let bounds_str: String = try_opt!(
-                        bounds
-                            .iter()
-                            .map(|ty_bound| {
-                                ty_bound.rewrite(context,
-                                                 Shape::legacy(budget, shape.indent + used_width))
-                            })
-                            .collect::<Option<Vec<_>>>()
-                    ).join(joiner);
+                    let ty_shape = try_opt!(shape.block_left(used_width));
+                    let bounds: Vec<_> =
+                        try_opt!(bounds
+                                     .iter()
+                                     .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
+                                     .collect());
+                    let bounds_str = join_bounds(context, ty_shape, &bounds);
 
                     format!("{}{}{}", type_str, colon, bounds_str)
                 }
@@ -458,11 +444,11 @@ fn rewrite_bounded_lifetime<'b, I>(lt: &ast::Lifetime,
                                             .map(|b| b.rewrite(context, shape))
                                             .collect());
         let colon = type_bound_colon(context);
-        let joiner = match context.config.type_punctuation_density() {
-            TypeDensity::Compressed => "+",
-            TypeDensity::Wide => " + ",
-        };
-        let result = format!("{}{}{}", result, colon, appendix.join(joiner));
+        let overhead = last_line_width(&result) + colon.len();
+        let result = format!("{}{}{}",
+                             result,
+                             colon,
+                             join_bounds(context, try_opt!(shape.sub_width(overhead)), &appendix));
         wrap_str(result, context.config.max_width(), shape)
     }
 }
@@ -494,12 +480,8 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
 
 impl Rewrite for ast::TyParamBounds {
     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let joiner = match context.config.type_punctuation_density() {
-            TypeDensity::Compressed => "+",
-            TypeDensity::Wide => " + ",
-        };
         let strs: Vec<_> = try_opt!(self.iter().map(|b| b.rewrite(context, shape)).collect());
-        wrap_str(strs.join(joiner), context.config.max_width(), shape)
+        join_bounds(context, shape, &strs).rewrite(context, shape)
     }
 }
 
@@ -514,24 +496,12 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
         result.push_str(&attr_str);
         result.push_str(&self.ident.to_string());
         if !self.bounds.is_empty() {
-            if context.config.space_before_bound() {
-                result.push_str(" ");
-            }
-            result.push_str(":");
-            if context.config.space_after_bound_colon() {
-                result.push_str(" ");
-            }
-            let joiner = match context.config.type_punctuation_density() {
-                TypeDensity::Compressed => "+",
-                TypeDensity::Wide => " + ",
-            };
-            let bounds: String = try_opt!(self.bounds
-                                              .iter()
-                                              .map(|ty_bound| ty_bound.rewrite(context, shape))
-                                              .collect::<Option<Vec<_>>>())
-                .join(joiner);
-
-            result.push_str(&bounds);
+            result.push_str(type_bound_colon(context));
+            let strs: Vec<_> = try_opt!(self.bounds
+                                            .iter()
+                                            .map(|ty_bound| ty_bound.rewrite(context, shape))
+                                            .collect());
+            result.push_str(&join_bounds(context, shape, &strs));
         }
         if let Some(ref def) = self.default {
 
@@ -732,3 +702,19 @@ fn rewrite_bare_fn(bare_fn: &ast::BareFnTy,
 
     Some(result)
 }
+
+pub fn join_bounds(context: &RewriteContext, shape: Shape, type_strs: &Vec<String>) -> String {
+    // Try to join types in a single line
+    let joiner = match context.config.type_punctuation_density() {
+        TypeDensity::Compressed => "+",
+        TypeDensity::Wide => " + ",
+    };
+    let result = type_strs.join(joiner);
+    if result.contains('\n') || result.len() > shape.width {
+        let joiner_indent = shape.indent.block_indent(context.config);
+        let joiner = format!("\n{}+ ", joiner_indent.to_string(context.config));
+        type_strs.join(&joiner)
+    } else {
+        result
+    }
+}