Add format_trait_ref_then_update_result

This commit is contained in:
topecongiro 2017-06-10 20:37:34 +09:00
parent 88e522f921
commit bd80077be8
3 changed files with 245 additions and 70 deletions

View file

@ -678,83 +678,30 @@ fn format_impl_ref_and_type(context: &RewriteContext,
0); 0);
let mut generics_str = let mut generics_str =
try_opt!(rewrite_generics(context, generics, shape, shape.width, mk_sp(lo, hi))); 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 let Some(ref trait_ref) = *trait_ref {
if polarity != ast::ImplPolarity::Negative { let success = format_trait_ref_then_update_result(context,
generics_str.push_str(" "); &trait_ref,
} offset,
let used_space = if generics_str.contains('\n') { &generics_str,
last_line_width(&generics_str) split_at_for,
} else { &mut result);
result.len() + generics_str.len() if !success {
};
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 mut generics_str = let mut generics_str =
try_opt!(rewrite_generics(context, generics, shape, 0, mk_sp(lo, hi))); try_opt!(rewrite_generics(context, generics, shape, 0, mk_sp(lo, hi)));
if polarity == ast::ImplPolarity::Negative { add_polarity(&mut generics_str, &polarity, true);
generics_str.push_str(" !"); if !format_trait_ref_then_update_result(context,
} else { &trait_ref,
generics_str.push_str(" "); offset,
} &generics_str,
let used_space = if generics_str.contains('\n') { split_at_for,
last_line_width(&generics_str) &mut result) {
} else { // FIXME: should be unreachable
result.len() + generics_str.len() return None;
};
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");
}
} }
} }
} else { } else {
if polarity == ast::ImplPolarity::Negative {
generics_str.push_str(" ");
}
result.push_str(&generics_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, pub fn format_struct(context: &RewriteContext,
item_name: &str, item_name: &str,
ident: ast::Ident, ident: ast::Ident,

View file

@ -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() {}
}

View file

@ -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() {}
}