Skip to content

Commit be18e7a

Browse files
authored
Merge pull request #1717 from topecongiro/type-and-generics
Refactor format against types and generics
2 parents 2061f10 + 4d11faf commit be18e7a

File tree

12 files changed

+190
-108
lines changed

12 files changed

+190
-108
lines changed

src/items.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -705,16 +705,17 @@ fn format_impl_ref_and_type(
705705
Some(ref tr) => tr.path.span.lo,
706706
None => self_ty.span.lo,
707707
};
708-
let shape = generics_shape_from_config(
708+
let shape = try_opt!(generics_shape_from_config(
709709
context.config,
710710
Shape::indented(offset + last_line_width(&result), context.config),
711711
0,
712-
);
712+
));
713+
let one_line_budget = try_opt!(shape.width.checked_sub(last_line_width(&result) + 2));
713714
let generics_str = try_opt!(rewrite_generics_inner(
714715
context,
715716
generics,
716717
shape,
717-
shape.width,
718+
one_line_budget,
718719
mk_sp(lo, hi),
719720
));
720721

@@ -927,7 +928,7 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
927928
let trait_bound_str = try_opt!(rewrite_trait_bounds(
928929
context,
929930
type_param_bounds,
930-
Shape::legacy(context.config.max_width(), offset),
931+
Shape::indented(offset, context.config),
931932
));
932933
// If the trait, generics, and trait bound cannot fit on the same line,
933934
// put the trait bounds on an indented new line
@@ -1591,7 +1592,7 @@ pub fn rewrite_associated_type(
15911592
let prefix = format!("type {}", ident);
15921593

15931594
let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
1594-
let shape = Shape::legacy(context.config.max_width(), indent);
1595+
let shape = Shape::indented(indent, context.config);
15951596
let bounds: &[_] = ty_param_bounds;
15961597
let bound_str = try_opt!(
15971598
bounds
@@ -1900,7 +1901,8 @@ fn rewrite_fn_base(
19001901

19011902
if context.config.fn_args_layout() == IndentStyle::Block {
19021903
arg_indent = indent.block_indent(context.config);
1903-
multi_line_budget = context.config.max_width() - arg_indent.width();
1904+
// 1 = ","
1905+
multi_line_budget = context.config.max_width() - (arg_indent.width() + 1);
19041906
}
19051907

19061908
debug!(
@@ -2386,9 +2388,11 @@ fn rewrite_generics(
23862388
shape: Shape,
23872389
span: Span,
23882390
) -> Option<String> {
2389-
let shape = generics_shape_from_config(context.config, shape, 0);
2390-
rewrite_generics_inner(context, generics, shape, shape.width, span)
2391-
.or_else(|| rewrite_generics_inner(context, generics, shape, 0, span))
2391+
let g_shape = try_opt!(generics_shape_from_config(context.config, shape, 0));
2392+
let one_line_width = try_opt!(shape.width.checked_sub(2));
2393+
rewrite_generics_inner(context, generics, g_shape, one_line_width, span).or_else(|| {
2394+
rewrite_generics_inner(context, generics, g_shape, 0, span)
2395+
})
23922396
}
23932397

23942398
fn rewrite_generics_inner(
@@ -2435,14 +2439,17 @@ fn rewrite_generics_inner(
24352439
format_generics_item_list(context, items, shape, one_line_width)
24362440
}
24372441

2438-
pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> Shape {
2439-
Shape {
2440-
// 2 = `<>`
2441-
width: shape.width.checked_sub(offset + 2).unwrap_or(0),
2442-
..match config.generics_indent() {
2443-
IndentStyle::Visual => shape.visual_indent(1 + offset),
2444-
IndentStyle::Block => shape.block().block_indent(config.tab_spaces()),
2445-
}
2442+
pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> Option<Shape> {
2443+
match config.generics_indent() {
2444+
IndentStyle::Visual => shape.visual_indent(1 + offset).sub_width(offset + 2),
2445+
IndentStyle::Block => {
2446+
// 1 = ","
2447+
shape
2448+
.block()
2449+
.block_indent(config.tab_spaces())
2450+
.with_max_width(config)
2451+
.sub_width(1)
2452+
}
24462453
}
24472454
}
24482455

@@ -2531,7 +2538,7 @@ fn rewrite_where_clause_rfc_style(
25312538
snuggle: bool,
25322539
span_end: Option<BytePos>,
25332540
) -> Option<String> {
2534-
let block_shape = shape.block();
2541+
let block_shape = shape.block().with_max_width(context.config);
25352542

25362543
let starting_newline = if snuggle {
25372544
" ".to_owned()
@@ -2553,7 +2560,7 @@ fn rewrite_where_clause_rfc_style(
25532560
terminator,
25542561
|pred| span_for_where_pred(pred).lo,
25552562
|pred| span_for_where_pred(pred).hi,
2556-
|pred| pred.rewrite(context, shape),
2563+
|pred| pred.rewrite(context, block_shape),
25572564
span_start,
25582565
span_end,
25592566
);

src/lists.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,6 @@ pub struct ListFormatting<'a> {
6868
pub config: &'a Config,
6969
}
7070

71-
pub fn format_fn_args<I>(items: I, shape: Shape, config: &Config) -> Option<String>
72-
where
73-
I: Iterator<Item = ListItem>,
74-
{
75-
list_helper(
76-
items,
77-
shape,
78-
config,
79-
ListTactic::LimitedHorizontalVertical(config.fn_call_width()),
80-
)
81-
}
82-
8371
pub fn format_item_list<I>(items: I, shape: Shape, config: &Config) -> Option<String>
8472
where
8573
I: Iterator<Item = ListItem>,

src/types.rs

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ use syntax::symbol::keywords;
2020
use {Shape, Spanned};
2121
use codemap::SpanUtils;
2222
use items::{format_generics_item_list, generics_shape_from_config};
23-
use lists::{itemize_list, format_fn_args};
23+
use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic,
24+
definitive_tactic};
2425
use rewrite::{Rewrite, RewriteContext};
2526
use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp, last_line_width};
26-
use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple};
27-
use config::{Style, TypeDensity};
27+
use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple, wrap_args_with_parens};
28+
use config::{IndentStyle, Style, TypeDensity};
2829

2930
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
3031
pub enum PathContext {
@@ -225,8 +226,12 @@ fn rewrite_segment(
225226
""
226227
};
227228

228-
let generics_shape =
229-
generics_shape_from_config(context.config, shape, separator.len());
229+
let generics_shape = try_opt!(generics_shape_from_config(
230+
context.config,
231+
shape,
232+
separator.len(),
233+
));
234+
let one_line_width = try_opt!(shape.width.checked_sub(separator.len() + 2));
230235
let items = itemize_list(
231236
context.codemap,
232237
param_list.into_iter(),
@@ -241,7 +246,7 @@ fn rewrite_segment(
241246
context,
242247
items,
243248
generics_shape,
244-
generics_shape.width,
249+
one_line_width,
245250
));
246251

247252
// Update position of last bracket.
@@ -306,7 +311,16 @@ where
306311
// 2 for ()
307312
let budget = try_opt!(shape.width.checked_sub(2));
308313
// 1 for (
309-
let offset = shape.indent + 1;
314+
let offset = match context.config.fn_args_layout() {
315+
IndentStyle::Block => {
316+
shape
317+
.block()
318+
.block_indent(context.config.tab_spaces())
319+
.indent
320+
}
321+
IndentStyle::Visual => shape.indent + 1,
322+
};
323+
let list_shape = Shape::legacy(budget, offset);
310324
let list_lo = context.codemap.span_after(span, "(");
311325
let items = itemize_list(
312326
context.codemap,
@@ -325,39 +339,64 @@ where
325339
ArgumentKind::Variadic(start) => start + BytePos(3),
326340
},
327341
|arg| match *arg {
328-
ArgumentKind::Regular(ref ty) => ty.rewrite(context, Shape::legacy(budget, offset)),
342+
ArgumentKind::Regular(ref ty) => ty.rewrite(context, list_shape),
329343
ArgumentKind::Variadic(_) => Some("...".to_owned()),
330344
},
331345
list_lo,
332346
span.hi,
333347
);
334348

335-
let list_str = try_opt!(format_fn_args(
336-
items,
337-
Shape::legacy(budget, offset),
338-
context.config,
339-
));
349+
let item_vec: Vec<_> = items.collect();
350+
351+
let tactic = definitive_tactic(&*item_vec, ListTactic::HorizontalVertical, budget);
352+
353+
let fmt = ListFormatting {
354+
tactic: tactic,
355+
separator: ",",
356+
trailing_separator: if !context.use_block_indent() || variadic {
357+
SeparatorTactic::Never
358+
} else {
359+
context.config.trailing_comma()
360+
},
361+
shape: list_shape,
362+
ends_with_newline: false,
363+
config: context.config,
364+
};
340365

366+
let list_str = try_opt!(write_list(&item_vec, &fmt));
367+
368+
let ty_shape = match context.config.fn_args_layout() {
369+
IndentStyle::Block => shape.block().block_indent(context.config.tab_spaces()),
370+
IndentStyle::Visual => try_opt!(shape.block_left(4)),
371+
};
341372
let output = match *output {
342373
FunctionRetTy::Ty(ref ty) => {
343-
let budget = try_opt!(shape.width.checked_sub(4));
344-
let type_str = try_opt!(ty.rewrite(context, Shape::legacy(budget, offset + 4)));
374+
let type_str = try_opt!(ty.rewrite(context, ty_shape));
345375
format!(" -> {}", type_str)
346376
}
347377
FunctionRetTy::Default(..) => String::new(),
348378
};
349379

350-
let infix = if !output.is_empty() && output.len() + list_str.len() > shape.width {
351-
format!("\n{}", (offset - 1).to_string(context.config))
380+
let shape = try_opt!(shape.sub_width(output.len()));
381+
let extendable = !list_str.contains('\n') || list_str.is_empty();
382+
let args = wrap_args_with_parens(
383+
context,
384+
&list_str,
385+
extendable,
386+
shape,
387+
Shape::indented(offset, context.config),
388+
);
389+
if last_line_width(&args) + output.len() > shape.width {
390+
Some(format!(
391+
"{}\n{}{}",
392+
args,
393+
offset.to_string(context.config),
394+
output.trim_left()
395+
))
352396
} else {
353-
String::new()
354-
};
397+
Some(format!("{}{}", args, output))
398+
}
355399

356-
Some(if context.config.spaces_within_parens() {
357-
format!("( {} ){}{}", list_str, infix, output)
358-
} else {
359-
format!("({}){}{}", list_str, infix, output)
360-
})
361400
}
362401

363402
fn type_bound_colon(context: &RewriteContext) -> &'static str {
@@ -423,7 +462,9 @@ impl Rewrite for ast::WherePredicate {
423462
.map(|ty_bound| ty_bound.rewrite(context, ty_shape))
424463
.collect()
425464
);
426-
let bounds_str = join_bounds(context, ty_shape, &bounds);
465+
let overhead = type_str.len() + colon.len();
466+
let bounds_str =
467+
join_bounds(context, try_opt!(ty_shape.sub_width(overhead)), &bounds);
427468

428469
format!("{}{}{}", type_str, colon, bounds_str)
429470
}
@@ -762,16 +803,15 @@ fn rewrite_bare_fn(
762803

763804
result.push_str("fn");
764805

765-
let budget = try_opt!(shape.width.checked_sub(result.len()));
766-
let indent = shape.indent + result.len();
806+
let func_ty_shape = try_opt!(shape.offset_left(result.len()));
767807

768808
let rewrite = try_opt!(format_function_type(
769809
bare_fn.decl.inputs.iter(),
770810
&bare_fn.decl.output,
771811
bare_fn.decl.variadic,
772812
span,
773813
context,
774-
Shape::legacy(budget, indent),
814+
func_ty_shape,
775815
));
776816

777817
result.push_str(&rewrite);

tests/source/big-impl-rfc.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,17 @@ impl<
112112
> {
113113
fn foo() {}
114114
}
115+
116+
// #1689
117+
impl<M, S, F, X> SubSelectDirect<M, S, F, X>
118+
where
119+
M: select::Selector,
120+
S: event::Stream,
121+
F: for<'t> FnMut(transform::Api<
122+
't,
123+
Stream<ContentStream<S>>,
124+
>)
125+
-> transform::Api<'t, X>,
126+
X: event::Stream,
127+
{
128+
}

tests/source/type_alias.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ pub type Exactly100CharstoEqualWhereTest<T, U, PARAMET> where T: Clone + Ord + E
2828
pub type Exactly101CharstoEqualWhereTest<T, U, PARAMETE> where T: Clone + Ord + Eq + SomeOtherTrait = Option<T>;
2929

3030
type RegisterPlugin = unsafe fn(pt: *const c_char, plugin: *mut c_void, data: *mut CallbackData);
31+
32+
// #1683
33+
pub type Between<Lhs, Rhs> = super::operators::Between<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>;
34+
pub type NotBetween<Lhs, Rhs> = super::operators::NotBetween<Lhs, super::operators::And<AsExpr<Rhs, Lhs>, AsExpr<Rhs, Lhs>>>;

tests/target/big-impl-rfc.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,14 @@ impl<
7575
> {
7676
fn foo() {}
7777
}
78+
79+
// #1689
80+
impl<M, S, F, X> SubSelectDirect<M, S, F, X>
81+
where
82+
M: select::Selector,
83+
S: event::Stream,
84+
F: for<'t> FnMut(transform::Api<'t, Stream<ContentStream<S>>>)
85+
-> transform::Api<'t, X>,
86+
X: event::Stream,
87+
{
88+
}

tests/target/extern_not_explicit.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ extern {
66

77
extern fn sup() {}
88

9-
type funky_func = extern fn(unsafe extern "rust-call" fn(*const JSJitInfo,
10-
*mut JSContext,
11-
HandleObject,
12-
*mut libc::c_void,
13-
u32,
14-
*mut JSVal)
15-
-> u8);
9+
type funky_func = extern fn(
10+
unsafe extern "rust-call" fn(
11+
*const JSJitInfo,
12+
*mut JSContext,
13+
HandleObject,
14+
*mut libc::c_void,
15+
u32,
16+
*mut JSVal,
17+
) -> u8,
18+
);

0 commit comments

Comments
 (0)