use codemap::{LineRangeUtils, SpanUtils};
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
recover_missing_comment_in_span, rewrite_missing_comment, FindUncommented};
-use config::{BraceStyle, Config, Density, IndentStyle, ReturnIndent, Style};
-use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
+use config::{BraceStyle, Config, Density, IndentStyle};
+use expr::{choose_rhs, format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
rewrite_call_inner, ExprType};
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
use visitor::FmtVisitor;
fn type_annotation_separator(config: &Config) -> &str {
- colon_spaces(
- config.space_before_type_annotation(),
- config.space_after_type_annotation_colon(),
- )
+ colon_spaces(config.space_before_colon(), config.space_after_colon())
}
// Statements of the form
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
debug!(
"Local::rewrite {:?} {} {:?}",
- self,
- shape.width,
- shape.indent
+ self, shape.width, shape.indent
);
skip_out_of_file_lines_range!(context, self.span);
// 1 = trailing semicolon;
let nested_shape = shape.sub_width(1)?;
- result = rewrite_assign_rhs(context, result, ex, nested_shape)?;
+ result = rewrite_assign_rhs(context, result, &**ex, nested_shape)?;
}
result.push(';');
unsafety: unsafety,
visibility: visibility.clone(),
},
- visit::FnKind::Method(_, ref method_sig, vis, _) => {
+ visit::FnKind::Method(_, method_sig, vis, _) => {
let mut fn_sig = FnSig::from_method_sig(method_sig, generics);
fn_sig.defaultness = defualtness;
if let Some(vis) = vis {
}
impl<'a> FmtVisitor<'a> {
- fn format_item(&mut self, item: Item) {
+ fn format_item(&mut self, item: &Item) {
self.buffer.push_str(&item.abi);
let snippet = self.snippet(item.span);
let brace_pos = snippet.find_uncommented("{").unwrap();
- self.buffer.push_str("{");
+ self.push_str("{");
if !item.body.is_empty() || contains_comment(&snippet[brace_pos..]) {
// FIXME: this skips comments between the extern keyword and the opening
// brace.
if item.body.is_empty() {
self.format_missing_no_indent(item.span.hi() - BytePos(1));
self.block_indent = self.block_indent.block_unindent(self.config);
-
- self.buffer
- .push_str(&self.block_indent.to_string(self.config));
+ let indent_str = self.block_indent.to_string(self.config);
+ self.push_str(&indent_str);
} else {
for item in &item.body {
self.format_body_element(item);
}
}
- self.buffer.push_str("}");
+ self.push_str("}");
self.last_pos = item.span.hi();
}
pub fn format_foreign_mod(&mut self, fm: &ast::ForeignMod, span: Span) {
let item = Item::from_foreign_mod(fm, span, self.config);
- self.format_item(item);
+ self.format_item(&item);
}
-
fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
let rewrite = item.rewrite(&self.get_context(), self.shape());
self.push_rewrite(item.span(), rewrite);
) -> Option<String> {
let context = self.get_context();
- let has_body =
- !is_empty_block(block, self.codemap) || !context.config.fn_empty_single_line();
- let mut newline_brace =
- newline_for_brace(self.config, &fn_sig.generics.where_clause, has_body);
+ let mut newline_brace = newline_for_brace(self.config, &fn_sig.generics.where_clause);
let (mut result, force_newline_brace) =
rewrite_fn_base(&context, indent, ident, fn_sig, span, newline_brace, true)?;
- if self.config.fn_brace_style() == BraceStyle::AlwaysNextLine || force_newline_brace {
- newline_brace = true;
- } else if last_line_width(&result) + 2 > self.shape().width {
- // 2 = ` {`
+ // 2 = ` {`
+ if self.config.brace_style() == BraceStyle::AlwaysNextLine || force_newline_brace
+ || last_line_width(&result) + 2 > self.shape().width
+ {
newline_brace = true;
} else if !result.contains('\n') {
newline_brace = false;
let codemap = self.get_context().codemap;
- if self.config.fn_empty_single_line() && is_empty_block(block, codemap)
+ if self.config.empty_item_single_line() && is_empty_block(block, codemap)
&& self.block_indent.width() + fn_str.len() + 2 <= self.config.max_width()
{
return Some(format!("{}{{}}", fn_str));
format_expr(e, ExprType::Statement, &self.get_context(), self.shape())
.map(|s| s + suffix)
- .or_else(|| Some(self.snippet(e.span)))
+ .or_else(|| Some(self.snippet(e.span).to_owned()))
}
None => stmt.rewrite(&self.get_context(), self.shape()),
}
None
}
+ pub fn visit_static(&mut self, static_parts: &StaticParts) {
+ let rewrite = rewrite_static(&self.get_context(), static_parts, self.block_indent);
+ self.push_rewrite(static_parts.span, rewrite);
+ }
+
+ pub fn visit_struct(&mut self, struct_parts: &StructParts) {
+ let is_tuple = struct_parts.def.is_tuple();
+ let rewrite = format_struct(&self.get_context(), struct_parts, self.block_indent, None)
+ .map(|s| if is_tuple { s + ";" } else { s });
+ self.push_rewrite(struct_parts.span, rewrite);
+ }
+
pub fn visit_enum(
&mut self,
ident: ast::Ident,
span: Span,
) {
let enum_header = format_header("enum ", ident, vis);
- self.buffer.push_str(&enum_header);
+ self.push_str(&enum_header);
let enum_snippet = self.snippet(span);
let brace_pos = enum_snippet.find_uncommented("{").unwrap();
let generics_str = format_generics(
&self.get_context(),
generics,
- "{",
- "{",
- self.config.item_brace_style(),
- enum_def.variants.is_empty(),
+ self.config.brace_style(),
+ if enum_def.variants.is_empty() {
+ BracePos::ForceSameLine
+ } else {
+ BracePos::Auto
+ },
self.block_indent,
mk_sp(span.lo(), body_start),
last_line_width(&enum_header),
).unwrap();
- self.buffer.push_str(&generics_str);
+ self.push_str(&generics_str);
self.last_pos = body_start;
self.block_indent = self.block_indent.block_indent(self.config);
let variant_list = self.format_variant_list(enum_def, body_start, span.hi() - BytePos(1));
match variant_list {
- Some(ref body_str) => self.buffer.push_str(body_str),
- None => if contains_comment(&enum_snippet[brace_pos..]) {
- self.format_missing_no_indent(span.hi() - BytePos(1))
- },
+ Some(ref body_str) => self.push_str(body_str),
+ None => self.format_missing_no_indent(span.hi() - BytePos(1)),
}
self.block_indent = self.block_indent.block_unindent(self.config);
if variant_list.is_some() || contains_comment(&enum_snippet[brace_pos..]) {
- self.buffer
- .push_str(&self.block_indent.to_string(self.config));
+ let indent_str = self.block_indent.to_string(self.config);
+ self.push_str(&indent_str);
}
- self.buffer.push_str("}");
+ self.push_str("}");
self.last_pos = span.hi();
}
let indentation = self.block_indent.to_string(self.config);
result.push_str(&indentation);
- let items = itemize_list(
- self.codemap,
- enum_def.variants.iter(),
- "}",
- |f| if !f.node.attrs.is_empty() {
- f.node.attrs[0].span.lo()
- } else {
- f.span.lo()
- },
- |f| f.span.hi(),
- |f| self.format_variant(f),
- body_lo,
- body_hi,
- false,
- );
+ let itemize_list_with = |one_line_width: usize| {
+ itemize_list(
+ self.codemap,
+ enum_def.variants.iter(),
+ "}",
+ ",",
+ |f| {
+ if !f.node.attrs.is_empty() {
+ f.node.attrs[0].span.lo()
+ } else {
+ f.span.lo()
+ }
+ },
+ |f| f.span.hi(),
+ |f| self.format_variant(f, one_line_width),
+ body_lo,
+ body_hi,
+ false,
+ ).collect()
+ };
+ let mut items: Vec<_> =
+ itemize_list_with(self.config.width_heuristics().struct_variant_width);
+ // If one of the variants use multiple lines, use multi-lined formatting for all variants.
+ let has_multiline_variant = items.iter().any(|item| item.inner_as_ref().contains('\n'));
+ let has_single_line_variant = items.iter().any(|item| !item.inner_as_ref().contains('\n'));
+ if has_multiline_variant && has_single_line_variant {
+ items = itemize_list_with(0);
+ }
let shape = self.shape().sub_width(2).unwrap();
let fmt = ListFormatting {
config: self.config,
};
- let list = write_list(&items.collect::<Vec<_>>(), &fmt)?;
+ let list = write_list(&items, &fmt)?;
result.push_str(&list);
result.push('\n');
Some(result)
}
// Variant of an enum.
- fn format_variant(&self, field: &ast::Variant) -> Option<String> {
+ fn format_variant(&self, field: &ast::Variant, one_line_width: usize) -> Option<String> {
if contains_skip(&field.node.attrs) {
let lo = field.node.attrs[0].span.lo();
let span = mk_sp(lo, field.span.hi());
- return Some(self.snippet(span));
+ return Some(self.snippet(span).to_owned());
}
let context = self.get_context();
- let indent = self.block_indent;
- let shape = self.shape();
+ // 1 = ','
+ let shape = self.shape().sub_width(1)?;
let attrs_str = field.node.attrs.rewrite(&context, shape)?;
let lo = field
.node
let span = mk_sp(lo, field.span.lo());
let variant_body = match field.node.data {
- ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => {
- // FIXME: Should limit the width, as we have a trailing comma
- format_struct(
- &context,
- "",
- field.node.name,
- &ast::Visibility::Inherited,
- &field.node.data,
- None,
- field.span,
- indent,
- Some(self.config.struct_variant_width()),
- )?
+ ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => format_struct(
+ &context,
+ &StructParts::from_variant(field),
+ self.block_indent,
+ Some(one_line_width),
+ )?,
+ ast::VariantData::Unit(..) => {
+ if let Some(ref expr) = field.node.disr_expr {
+ let lhs = format!("{} =", field.node.name);
+ rewrite_assign_rhs(&context, lhs, &**expr, shape)?
+ } else {
+ field.node.name.to_string()
+ }
}
- ast::VariantData::Unit(..) => if let Some(ref expr) = field.node.disr_expr {
- let lhs = format!("{} =", field.node.name);
- // 1 = ','
- rewrite_assign_rhs(&context, lhs, expr, shape.sub_width(1)?)?
- } else {
- String::from(field.node.name.to_string())
- },
};
let attrs_extendable = attrs_str.is_empty()
- || (context.config.attributes_on_same_line_as_variant()
- && is_attributes_extendable(&attrs_str));
+ || (context.config.same_line_attributes() && is_attributes_extendable(&attrs_str));
combine_strs_with_missing_comments(
&context,
&attrs_str,
let where_clause_str = rewrite_where_clause(
context,
&generics.where_clause,
- context.config.item_brace_style(),
+ context.config.brace_style(),
Shape::legacy(where_budget, offset.block_only()),
- context.config.where_density(),
+ Density::Vertical,
"{",
where_span_end,
self_ty.span.hi(),
}
result.push_str(&where_clause_str);
- match context.config.item_brace_style() {
+ match context.config.brace_style() {
_ if last_line_contains_single_line_comment(&result) => result.push_str(&sep),
BraceStyle::AlwaysNextLine => result.push_str(&sep),
BraceStyle::PreferSameLine => result.push(' '),
- BraceStyle::SameLineWhere => if !where_clause_str.is_empty() {
- result.push_str(&sep);
- } else {
- result.push(' ');
- },
+ BraceStyle::SameLineWhere => {
+ if !where_clause_str.is_empty() {
+ result.push_str(&sep);
+ } else {
+ result.push(' ');
+ }
+ }
}
result.push('{');
let open_pos = snippet.find_uncommented("{")? + 1;
if !items.is_empty() || contains_comment(&snippet[open_pos..]) {
- let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
+ let mut visitor = FmtVisitor::from_context(context);
visitor.block_indent = offset.block_only().block_indent(context.config);
visitor.last_pos = item.span.lo() + BytePos(open_pos as u32);
result.push_str(&outer_indent_str);
}
- if result.chars().last().unwrap() == '{' {
+ if result.ends_with('{') {
result.push_str(&sep);
}
result.push('}');
let open_pos = snippet.find_uncommented("{")? + 1;
Some(
- context.config.impl_empty_single_line() && items.is_empty() && !result.contains('\n')
+ context.config.empty_item_single_line() && items.is_empty() && !result.contains('\n')
&& result.len() + where_clause_str.len() <= context.config.max_width()
&& !contains_comment(&snippet[open_pos..]),
)
let curly_brace_overhead = if generics.where_clause.predicates.is_empty() {
// If there is no where clause adapt budget for type formatting to take space and curly
// brace into account.
- match context.config.item_brace_style() {
+ match context.config.brace_style() {
BraceStyle::AlwaysNextLine => 0,
_ => 2,
}
result.push_str("for ");
}
let budget = context.budget(last_line_width(&result));
- let type_offset = match context.config.where_style() {
- Style::Legacy => new_line_offset + trait_ref_overhead,
- Style::Rfc => new_line_offset,
+ let type_offset = match context.config.indent_style() {
+ IndentStyle::Visual => new_line_offset + trait_ref_overhead,
+ IndentStyle::Block => new_line_offset,
};
- result.push_str(&*self_ty
- .rewrite(context, Shape::legacy(budget, type_offset))?);
+ result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?);
Some(result)
} else {
unreachable!();
if !(retry && trait_ref_str.contains('\n')) {
return Some(format!(
"{} {}{}",
- generics_str,
- polarity_str,
- &trait_ref_str
+ generics_str, polarity_str, &trait_ref_str
));
}
}
}
}
-pub fn format_struct(
- context: &RewriteContext,
- item_name: &str,
+pub struct StructParts<'a> {
+ prefix: &'a str,
ident: ast::Ident,
- vis: &ast::Visibility,
- struct_def: &ast::VariantData,
- generics: Option<&ast::Generics>,
+ vis: &'a ast::Visibility,
+ def: &'a ast::VariantData,
+ generics: Option<&'a ast::Generics>,
span: Span,
+}
+
+impl<'a> StructParts<'a> {
+ fn format_header(&self) -> String {
+ format_header(self.prefix, self.ident, self.vis)
+ }
+
+ fn from_variant(variant: &'a ast::Variant) -> Self {
+ StructParts {
+ prefix: "",
+ ident: variant.node.name,
+ vis: &ast::Visibility::Inherited,
+ def: &variant.node.data,
+ generics: None,
+ span: variant.span,
+ }
+ }
+
+ pub fn from_item(item: &'a ast::Item) -> Self {
+ let (prefix, def, generics) = match item.node {
+ ast::ItemKind::Struct(ref def, ref generics) => ("struct ", def, generics),
+ ast::ItemKind::Union(ref def, ref generics) => ("union ", def, generics),
+ _ => unreachable!(),
+ };
+ StructParts {
+ prefix: prefix,
+ ident: item.ident,
+ vis: &item.vis,
+ def: def,
+ generics: Some(generics),
+ span: item.span,
+ }
+ }
+}
+
+fn format_struct(
+ context: &RewriteContext,
+ struct_parts: &StructParts,
offset: Indent,
one_line_width: Option<usize>,
) -> Option<String> {
- match *struct_def {
- ast::VariantData::Unit(..) => Some(format_unit_struct(item_name, ident, vis)),
- ast::VariantData::Tuple(ref fields, _) => format_tuple_struct(
- context,
- item_name,
- ident,
- vis,
- fields,
- generics,
- span,
- offset,
- ),
- ast::VariantData::Struct(ref fields, _) => format_struct_struct(
- context,
- item_name,
- ident,
- vis,
- fields,
- generics,
- span,
- offset,
- one_line_width,
- ),
+ match *struct_parts.def {
+ ast::VariantData::Unit(..) => format_unit_struct(context, struct_parts, offset),
+ ast::VariantData::Tuple(ref fields, _) => {
+ format_tuple_struct(context, struct_parts, fields, offset)
+ }
+ ast::VariantData::Struct(ref fields, _) => {
+ format_struct_struct(context, struct_parts, fields, offset, one_line_width)
+ }
}
}
let body_lo = context.codemap.span_after(item.span, "{");
- let shape = Shape::indented(offset + last_line_width(&result), context.config);
+ let shape = Shape::indented(offset, context.config);
let generics_str =
rewrite_generics(context, generics, shape, mk_sp(item.span.lo(), body_lo))?;
result.push_str(&generics_str);
+ // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
+ if !type_param_bounds.is_empty() {
+ let ident_hi = context
+ .codemap
+ .span_after(item.span, &format!("{}", item.ident));
+ let bound_hi = type_param_bounds.last().unwrap().span().hi();
+ let snippet = context.snippet(mk_sp(ident_hi, bound_hi));
+ if contains_comment(snippet) {
+ return None;
+ }
+ }
let trait_bound_str = rewrite_trait_bounds(
context,
type_param_bounds,
}
result.push_str(&trait_bound_str);
- let has_body = !trait_items.is_empty();
-
- let where_density = if (context.config.where_density() == Density::Compressed
- && (!result.contains('\n') || context.config.fn_args_indent() == IndentStyle::Block))
- || (context.config.fn_args_indent() == IndentStyle::Block && result.is_empty())
- || (context.config.where_density() == Density::CompressedIfEmpty && !has_body
- && !result.contains('\n'))
- {
- Density::Compressed
- } else {
- Density::Tall
- };
+ let where_density =
+ if context.config.indent_style() == IndentStyle::Block && result.is_empty() {
+ Density::Compressed
+ } else {
+ Density::Tall
+ };
let where_budget = context.budget(last_line_width(&result));
let pos_before_where = if type_param_bounds.is_empty() {
let where_clause_str = rewrite_where_clause(
context,
&generics.where_clause,
- context.config.item_brace_style(),
+ context.config.brace_style(),
Shape::legacy(where_budget, offset.block_only()),
where_density,
"{",
}
}
- match context.config.item_brace_style() {
+ match context.config.brace_style() {
_ if last_line_contains_single_line_comment(&result) => {
result.push('\n');
result.push_str(&offset.to_string(context.config));
result.push_str(&offset.to_string(context.config));
}
BraceStyle::PreferSameLine => result.push(' '),
- BraceStyle::SameLineWhere => if !where_clause_str.is_empty()
- && (!trait_items.is_empty() || result.contains('\n'))
- {
- result.push('\n');
- result.push_str(&offset.to_string(context.config));
- } else {
- result.push(' ');
- },
+ BraceStyle::SameLineWhere => {
+ if !where_clause_str.is_empty()
+ && (!trait_items.is_empty() || result.contains('\n'))
+ {
+ result.push('\n');
+ result.push_str(&offset.to_string(context.config));
+ } else {
+ result.push(' ');
+ }
+ }
}
result.push('{');
let open_pos = snippet.find_uncommented("{")? + 1;
if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) {
- let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
+ let mut visitor = FmtVisitor::from_context(context);
visitor.block_indent = offset.block_only().block_indent(context.config);
visitor.last_pos = item.span.lo() + BytePos(open_pos as u32);
}
}
-fn format_unit_struct(item_name: &str, ident: ast::Ident, vis: &ast::Visibility) -> String {
- format!("{};", format_header(item_name, ident, vis))
+fn format_unit_struct(context: &RewriteContext, p: &StructParts, offset: Indent) -> Option<String> {
+ let header_str = format_header(p.prefix, p.ident, p.vis);
+ let generics_str = if let Some(generics) = p.generics {
+ let hi = if generics.where_clause.predicates.is_empty() {
+ generics.span.hi()
+ } else {
+ generics.where_clause.span.hi()
+ };
+ format_generics(
+ context,
+ generics,
+ context.config.brace_style(),
+ BracePos::None,
+ offset,
+ mk_sp(generics.span.lo(), hi),
+ last_line_width(&header_str),
+ )?
+ } else {
+ String::new()
+ };
+ Some(format!("{}{};", header_str, generics_str))
}
pub fn format_struct_struct(
context: &RewriteContext,
- item_name: &str,
- ident: ast::Ident,
- vis: &ast::Visibility,
+ struct_parts: &StructParts,
fields: &[ast::StructField],
- generics: Option<&ast::Generics>,
- span: Span,
offset: Indent,
one_line_width: Option<usize>,
) -> Option<String> {
let mut result = String::with_capacity(1024);
+ let span = struct_parts.span;
- let header_str = format_header(item_name, ident, vis);
+ let header_str = struct_parts.format_header();
result.push_str(&header_str);
let header_hi = span.lo() + BytePos(header_str.len() as u32);
let body_lo = context.codemap.span_after(span, "{");
- let generics_str = match generics {
+ let generics_str = match struct_parts.generics {
Some(g) => format_generics(
context,
g,
- "{",
- "{",
- context.config.item_brace_style(),
- fields.is_empty(),
+ context.config.brace_style(),
+ if fields.is_empty() {
+ BracePos::ForceSameLine
+ } else {
+ BracePos::Auto
+ },
offset,
mk_sp(header_hi, body_lo),
last_line_width(&result),
None => {
// 3 = ` {}`, 2 = ` {`.
let overhead = if fields.is_empty() { 3 } else { 2 };
- if (context.config.item_brace_style() == BraceStyle::AlwaysNextLine
- && !fields.is_empty())
+ if (context.config.brace_style() == BraceStyle::AlwaysNextLine && !fields.is_empty())
|| context.config.max_width() < overhead + result.len()
{
format!("\n{}{{", offset.block_only().to_string(context.config))
result.push('\n');
result.push_str(&offset.to_string(context.config));
} else {
- result.push_str(&snippet);
+ result.push_str(snippet);
}
result.push('}');
return Some(result);
let items_str = rewrite_with_alignment(
fields,
context,
- Shape::indented(offset, context.config),
+ Shape::indented(offset, context.config).sub_width(1)?,
mk_sp(body_lo, span.hi()),
one_line_budget,
)?;
fn format_tuple_struct(
context: &RewriteContext,
- item_name: &str,
- ident: ast::Ident,
- vis: &ast::Visibility,
+ struct_parts: &StructParts,
fields: &[ast::StructField],
- generics: Option<&ast::Generics>,
- span: Span,
offset: Indent,
) -> Option<String> {
let mut result = String::with_capacity(1024);
+ let span = struct_parts.span;
- let header_str = format_header(item_name, ident, vis);
+ let header_str = struct_parts.format_header();
result.push_str(&header_str);
let body_lo = if fields.is_empty() {
- let lo = get_bytepos_after_visibility(context, vis, span, ")");
+ let lo = get_bytepos_after_visibility(context, struct_parts.vis, span, ")");
context.codemap.span_after(mk_sp(lo, span.hi()), "(")
} else {
fields[0].span.lo()
}
};
- let where_clause_str = match generics {
+ let where_clause_str = match struct_parts.generics {
Some(generics) => {
let budget = context.budget(last_line_width(&header_str));
let shape = Shape::legacy(budget, offset);
rewrite_where_clause(
context,
&generics.where_clause,
- context.config.item_brace_style(),
+ context.config.brace_style(),
Shape::legacy(where_budget, offset.block_only()),
Density::Compressed,
";",
result.push('\n');
result.push_str(&offset.to_string(context.config));
} else {
- result.push_str(&snippet);
+ result.push_str(snippet);
}
result.push(')');
} else {
- // 1 = ","
- let body = rewrite_call_inner(
- context,
- "",
- &fields.iter().map(|field| field).collect::<Vec<_>>()[..],
- span,
- Shape::indented(offset, context.config).sub_width(1)?,
- context.config.fn_call_width(),
- false,
- )?;
- result.push_str(&body);
+ let shape = Shape::indented(offset, context.config).sub_width(1)?;
+ let fields = &fields.iter().collect::<Vec<_>>()[..];
+ let one_line_width = context.config.width_heuristics().fn_call_width;
+ result = rewrite_call_inner(context, &result, fields, span, shape, one_line_width, false)?;
}
if !where_clause_str.is_empty() && !where_clause_str.contains('\n')
let where_clause_str = rewrite_where_clause(
context,
&generics.where_clause,
- context.config.item_brace_style(),
+ context.config.brace_style(),
Shape::legacy(where_budget, indent),
- context.config.where_density(),
+ Density::Vertical,
"=",
Some(span.hi()),
generics.span.hi(),
fn type_annotation_spacing(config: &Config) -> (&str, &str) {
(
- if config.space_before_type_annotation() {
- " "
- } else {
- ""
- },
- if config.space_after_type_annotation_colon() {
- " "
- } else {
- ""
- },
+ if config.space_before_colon() { " " } else { "" },
+ if config.space_after_colon() { " " } else { "" },
)
}
lhs_max_width: usize,
) -> Option<String> {
if contains_skip(&field.attrs) {
- return Some(context.snippet(mk_sp(field.attrs[0].span.lo(), field.span.hi())));
+ let snippet = context.snippet(mk_sp(field.attrs[0].span.lo(), field.span.hi()));
+ return Some(snippet.to_owned());
}
let type_annotation_spacing = type_annotation_spacing(context.config);
let attrs_str = field.attrs.rewrite(context, shape)?;
let attrs_extendable = attrs_str.is_empty()
- || (context.config.attributes_on_same_line_as_field()
- && is_attributes_extendable(&attrs_str));
+ || (context.config.same_line_attributes() && is_attributes_extendable(&attrs_str));
let missing_span = if field.attrs.is_empty() {
mk_sp(field.span.lo(), field.span.lo())
} else {
spacing.push(' ');
}
let ty_shape = shape.offset_left(overhead + spacing.len())?;
- if let Some(ref ty) = field.ty.rewrite(context, ty_shape) {
+ let mut orig_ty = field.ty.rewrite(context, ty_shape);
+ if let Some(ref ty) = orig_ty {
if !ty.contains('\n') {
return Some(attr_prefix + &spacing + ty);
}
}
- // We must use multiline.
- let new_shape = shape.with_max_width(context.config);
- let ty_rewritten = field.ty.rewrite(context, new_shape)?;
-
+ // We must use multiline. We are going to put attributes and a field on different lines.
+ // 1 = " "
+ let rhs_shape = shape.offset_left(last_line_width(&prefix) + 1)?;
+ orig_ty = field.ty.rewrite(context, rhs_shape);
let field_str = if prefix.is_empty() {
- ty_rewritten
- } else if prefix.len() + first_line_width(&ty_rewritten) + 1 <= shape.width {
- prefix + " " + &ty_rewritten
+ orig_ty?
} else {
- let type_offset = shape.indent.block_indent(context.config);
- let nested_shape = Shape::indented(type_offset, context.config);
- let nested_ty = field.ty.rewrite(context, nested_shape)?;
- prefix + "\n" + &type_offset.to_string(context.config) + &nested_ty
+ prefix + &choose_rhs(context, &*field.ty, rhs_shape, orig_ty)?
};
- combine_strs_with_missing_comments(
- context,
- &attrs_str,
- &field_str,
- missing_span,
- shape,
- attrs_extendable,
- )
+ combine_strs_with_missing_comments(context, &attrs_str, &field_str, missing_span, shape, false)
}
-pub fn rewrite_static(
- prefix: &str,
- vis: &ast::Visibility,
+pub struct StaticParts<'a> {
+ prefix: &'a str,
+ vis: &'a ast::Visibility,
ident: ast::Ident,
- ty: &ast::Ty,
+ ty: &'a ast::Ty,
mutability: ast::Mutability,
- expr_opt: Option<&ptr::P<ast::Expr>>,
- offset: Indent,
+ expr_opt: Option<&'a ptr::P<ast::Expr>>,
+ defaultness: Option<ast::Defaultness>,
span: Span,
+}
+
+impl<'a> StaticParts<'a> {
+ pub fn from_item(item: &'a ast::Item) -> Self {
+ let (prefix, ty, mutability, expr) = match item.node {
+ ast::ItemKind::Static(ref ty, mutability, ref expr) => ("static", ty, mutability, expr),
+ ast::ItemKind::Const(ref ty, ref expr) => {
+ ("const", ty, ast::Mutability::Immutable, expr)
+ }
+ _ => unreachable!(),
+ };
+ StaticParts {
+ prefix: prefix,
+ vis: &item.vis,
+ ident: item.ident,
+ ty: ty,
+ mutability: mutability,
+ expr_opt: Some(expr),
+ defaultness: None,
+ span: item.span,
+ }
+ }
+
+ pub fn from_trait_item(ti: &'a ast::TraitItem) -> Self {
+ let (ty, expr_opt) = match ti.node {
+ ast::TraitItemKind::Const(ref ty, ref expr_opt) => (ty, expr_opt),
+ _ => unreachable!(),
+ };
+ StaticParts {
+ prefix: "const",
+ vis: &ast::Visibility::Inherited,
+ ident: ti.ident,
+ ty: ty,
+ mutability: ast::Mutability::Immutable,
+ expr_opt: expr_opt.as_ref(),
+ defaultness: None,
+ span: ti.span,
+ }
+ }
+
+ pub fn from_impl_item(ii: &'a ast::ImplItem) -> Self {
+ let (ty, expr) = match ii.node {
+ ast::ImplItemKind::Const(ref ty, ref expr) => (ty, expr),
+ _ => unreachable!(),
+ };
+ StaticParts {
+ prefix: "const",
+ vis: &ii.vis,
+ ident: ii.ident,
+ ty: ty,
+ mutability: ast::Mutability::Immutable,
+ expr_opt: Some(expr),
+ defaultness: Some(ii.defaultness),
+ span: ii.span,
+ }
+ }
+}
+
+fn rewrite_static(
context: &RewriteContext,
+ static_parts: &StaticParts,
+ offset: Indent,
) -> Option<String> {
let colon = colon_spaces(
- context.config.space_before_type_annotation(),
- context.config.space_after_type_annotation_colon(),
+ context.config.space_before_colon(),
+ context.config.space_after_colon(),
);
let prefix = format!(
- "{}{} {}{}{}",
- format_visibility(vis),
- prefix,
- format_mutability(mutability),
- ident,
+ "{}{}{} {}{}{}",
+ format_visibility(static_parts.vis),
+ static_parts.defaultness.map_or("", format_defaultness),
+ static_parts.prefix,
+ format_mutability(static_parts.mutability),
+ static_parts.ident,
colon,
);
// 2 = " =".len()
- let ty_str = ty.rewrite(
- context,
- Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?,
- )?;
+ let ty_shape =
+ Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?;
+ let ty_str = static_parts.ty.rewrite(context, ty_shape)?;
- if let Some(expr) = expr_opt {
+ if let Some(expr) = static_parts.expr_opt {
let lhs = format!("{}{} =", prefix, ty_str);
// 1 = ;
let remaining_width = context.budget(offset.block_indent + 1);
rewrite_assign_rhs(
context,
lhs,
- expr,
+ &**expr,
Shape::legacy(remaining_width, offset.block_only()),
- ).and_then(|res| recover_comment_removed(res, span, context))
+ ).and_then(|res| recover_comment_removed(res, static_parts.span, context))
.map(|s| if s.ends_with(';') { s } else { s + ";" })
} else {
Some(format!("{}{};", prefix, ty_str))
) -> Option<String> {
let prefix = format!("type {}", ident);
- let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
+ let type_bounds_str = if let Some(bounds) = ty_param_bounds_opt {
// 2 = ": ".len()
let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
- let bounds: &[_] = ty_param_bounds;
let bound_str = bounds
.iter()
.map(|ty_bound| ty_bound.rewrite(context, shape))
};
if let Some(ty) = ty_opt {
- let ty_str = ty.rewrite(
- context,
- Shape::legacy(
- context.budget(indent.block_indent + prefix.len() + 2),
- indent.block_only(),
- ),
- )?;
- Some(format!("{}{} = {};", prefix, type_bounds_str, ty_str))
+ // 1 = `;`
+ let shape = Shape::indented(indent, context.config).sub_width(1)?;
+ let lhs = format!("{}{} =", prefix, type_bounds_str);
+ rewrite_assign_rhs(context, lhs, &**ty, shape).map(|s| s + ";")
} else {
Some(format!("{}{};", prefix, type_bounds_str))
}
.rewrite(context, Shape::legacy(shape.width, shape.indent))?;
if !is_empty_infer(context, &*self.ty) {
- if context.config.space_before_type_annotation() {
+ if context.config.space_before_colon() {
result.push_str(" ");
}
result.push_str(":");
- if context.config.space_after_type_annotation_colon() {
+ if context.config.space_after_colon() {
result.push_str(" ");
}
let overhead = last_line_width(&result);
debug!(
"rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
- one_line_budget,
- multi_line_budget,
- arg_indent
+ one_line_budget, multi_line_budget, arg_indent
);
// Check if vertical layout was forced.
if one_line_budget == 0 {
if snuggle_angle_bracket {
result.push('(');
- } else if context.config.fn_args_paren_newline() {
- result.push('\n');
- result.push_str(&arg_indent.to_string(context.config));
- if context.config.fn_args_indent() == IndentStyle::Visual {
- arg_indent = arg_indent + 1; // extra space for `(`
- }
- result.push('(');
} else {
result.push_str("(");
- if context.config.fn_args_indent() == IndentStyle::Visual {
+ if context.config.indent_style() == IndentStyle::Visual {
result.push('\n');
result.push_str(&arg_indent.to_string(context.config));
}
} else {
result.push('(');
}
- if context.config.spaces_within_parens() && !fd.inputs.is_empty() && result.ends_with('(') {
+ if context.config.spaces_within_parens_and_brackets() && !fd.inputs.is_empty()
+ && result.ends_with('(')
+ {
result.push(' ')
}
generics_str.contains('\n'),
)?;
- let put_args_in_block = match context.config.fn_args_indent() {
+ let put_args_in_block = match context.config.indent_style() {
IndentStyle::Block => arg_str.contains('\n') || arg_str.len() > one_line_budget,
_ => false,
} && !fd.inputs.is_empty();
if fd.inputs.is_empty() && used_width + 1 > context.config.max_width() {
result.push('\n');
}
- if context.config.spaces_within_parens() && !fd.inputs.is_empty() {
+ if context.config.spaces_within_parens_and_brackets() && !fd.inputs.is_empty() {
result.push(' ')
}
// If the last line of args contains comment, we cannot put the closing paren
// Return type.
if let ast::FunctionRetTy::Ty(..) = fd.output {
- let ret_should_indent = match context.config.fn_args_indent() {
+ let ret_should_indent = match context.config.indent_style() {
// If our args are block layout then we surely must have space.
IndentStyle::Block if put_args_in_block || fd.inputs.is_empty() => false,
_ if args_last_line_contains_comment => false,
}
};
let ret_indent = if ret_should_indent {
- let indent = match context.config.fn_return_indent() {
- ReturnIndent::WithWhereClause => indent + 4,
+ let indent = if arg_str.is_empty() {
// Aligning with non-existent args looks silly.
- _ if arg_str.is_empty() => {
- force_new_line_for_brace = true;
- indent + 4
- }
+ force_new_line_for_brace = true;
+ indent + 4
+ } else {
// FIXME: we might want to check that using the arg indent
// doesn't blow our budget, and if it does, then fallback to
// the where clause indent.
- _ => arg_indent,
+ arg_indent
};
result.push('\n');
}
}
- let should_compress_where = match context.config.where_density() {
- Density::Compressed => !result.contains('\n'),
- Density::CompressedIfEmpty => !has_body && !result.contains('\n'),
- _ => false,
- };
-
let pos_before_where = match fd.output {
ast::FunctionRetTy::Default(..) => args_span.hi(),
ast::FunctionRetTy::Ty(ref ty) => ty.span.hi(),
let is_args_multi_lined = arg_str.contains('\n');
- if where_clause.predicates.len() == 1 && should_compress_where {
- let budget = context.budget(last_line_used_width(&result, indent.width()));
- if let Some(where_clause_str) = rewrite_where_clause(
- context,
- where_clause,
- context.config.fn_brace_style(),
- Shape::legacy(budget, indent),
- Density::Compressed,
- "{",
- Some(span.hi()),
- pos_before_where,
- WhereClauseOption::compressed(),
- is_args_multi_lined,
- ) {
- result.push_str(&where_clause_str);
- force_new_line_for_brace |= last_line_contains_single_line_comment(&result);
- return Some((result, force_new_line_for_brace));
- }
- }
-
let option = WhereClauseOption::new(!has_body, put_args_in_block && ret_str.is_empty());
let where_clause_str = rewrite_where_clause(
context,
where_clause,
- context.config.fn_brace_style(),
+ context.config.brace_style(),
Shape::indented(indent, context.config),
Density::Tall,
"{",
}
}
- pub fn compressed() -> WhereClauseOption {
- WhereClauseOption {
- suppress_comma: true,
- snuggle: false,
- compress_where: true,
- }
- }
-
pub fn snuggled(current: &str) -> WhereClauseOption {
WhereClauseOption {
suppress_comma: false,
// FIXME: the comment for the self argument is dropped. This is blocked
// on rust issue #27522.
let min_args = explicit_self
- .and_then(|explicit_self| {
- rewrite_explicit_self(explicit_self, args, context)
- })
+ .and_then(|explicit_self| rewrite_explicit_self(explicit_self, args, context))
.map_or(1, |self_str| {
arg_item_strs[0] = self_str;
2
.map(ArgumentKind::Regular)
.chain(variadic_arg),
")",
+ ",",
|arg| match *arg {
ArgumentKind::Regular(arg) => span_lo_for_arg(arg),
ArgumentKind::Variadic(start) => start,
.and_then(|item| item.post_comment.as_ref())
.map_or(false, |s| s.trim().starts_with("//"));
- let (indent, trailing_comma) = match context.config.fn_args_indent() {
+ let (indent, trailing_comma) = match context.config.indent_style() {
IndentStyle::Block if fits_in_one_line => {
(indent.block_indent(context.config), SeparatorTactic::Never)
}
},
separator_place: SeparatorPlace::Back,
shape: Shape::legacy(budget, indent),
- ends_with_newline: tactic.ends_with_newline(context.config.fn_args_indent()),
+ ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
preserve_newline: true,
config: context.config,
};
if one_line_budget > 0 {
// 4 = "() {".len()
- let (indent, multi_line_budget) = match context.config.fn_args_indent() {
+ let (indent, multi_line_budget) = match context.config.indent_style() {
IndentStyle::Block => {
let indent = indent.block_indent(context.config);
(indent, context.budget(indent.width() + 1))
// Didn't work. we must force vertical layout and put args on a newline.
let new_indent = indent.block_indent(context.config);
- let used_space = match context.config.fn_args_indent() {
+ let used_space = match context.config.indent_style() {
// 1 = `,`
IndentStyle::Block => new_indent.width() + 1,
// Account for `)` and possibly ` {`.
Some((0, context.budget(used_space), new_indent))
}
-fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause, has_body: bool) -> bool {
+fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
let predicate_count = where_clause.predicates.len();
if config.where_single_line() && predicate_count == 1 {
return false;
}
- match (config.fn_brace_style(), config.where_density()) {
- (BraceStyle::AlwaysNextLine, _) => true,
- (_, Density::Compressed) if predicate_count == 1 => false,
- (_, Density::CompressedIfEmpty) if predicate_count == 1 && !has_body => false,
- (BraceStyle::SameLineWhere, _) if predicate_count > 0 => true,
- _ => false,
- }
+ let brace_style = config.brace_style();
+
+ brace_style == BraceStyle::AlwaysNextLine
+ || (brace_style == BraceStyle::SameLineWhere && predicate_count > 0)
}
fn rewrite_generics(
) -> Option<String> {
let g_shape = generics_shape_from_config(context.config, shape, 0)?;
let one_line_width = shape.width.checked_sub(2).unwrap_or(0);
- rewrite_generics_inner(context, generics, g_shape, one_line_width, span).or_else(|| {
- rewrite_generics_inner(context, generics, g_shape, 0, span)
- })
+ rewrite_generics_inner(context, generics, g_shape, one_line_width, span)
+ .or_else(|| rewrite_generics_inner(context, generics, g_shape, 0, span))
}
fn rewrite_generics_inner(
impl<'a> Rewrite for GenericsArg<'a> {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
match *self {
- GenericsArg::Lifetime(ref lifetime) => lifetime.rewrite(context, shape),
- GenericsArg::TyParam(ref ty) => ty.rewrite(context, shape),
+ GenericsArg::Lifetime(lifetime) => lifetime.rewrite(context, shape),
+ GenericsArg::TyParam(ty) => ty.rewrite(context, shape),
}
}
}
impl<'a> Spanned for GenericsArg<'a> {
fn span(&self) -> Span {
match *self {
- GenericsArg::Lifetime(ref lifetime) => lifetime.span(),
- GenericsArg::TyParam(ref ty) => ty.span(),
+ GenericsArg::Lifetime(lifetime) => lifetime.span(),
+ GenericsArg::TyParam(ty) => ty.span(),
}
}
}
context.codemap,
generics_args,
">",
+ ",",
|arg| arg.span().lo(),
|arg| arg.span().hi(),
|arg| arg.rewrite(context, shape),
}
pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> Option<Shape> {
- match config.generics_indent() {
+ match config.indent_style() {
IndentStyle::Visual => shape.visual_indent(1 + offset).sub_width(offset + 2),
IndentStyle::Block => {
// 1 = ","
let fmt = ListFormatting {
tactic: tactic,
separator: ",",
- trailing_separator: if context.config.generics_indent() == IndentStyle::Visual {
+ trailing_separator: if context.config.indent_style() == IndentStyle::Visual {
SeparatorTactic::Never
} else {
context.config.trailing_comma()
},
separator_place: SeparatorPlace::Back,
shape: shape,
- ends_with_newline: tactic.ends_with_newline(context.config.generics_indent()),
+ ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
preserve_newline: true,
config: context.config,
};
list_str: &str,
list_offset: Indent,
) -> String {
- if context.config.generics_indent() == IndentStyle::Block
+ if context.config.indent_style() == IndentStyle::Block
&& (list_str.contains('\n') || list_str.ends_with(','))
{
format!(
.block_unindent(context.config)
.to_string(context.config)
)
- } else if context.config.spaces_within_angle_brackets() {
+ } else if context.config.spaces_within_parens_and_brackets() {
format!("< {} >", list_str)
} else {
format!("<{}>", list_str)
fn rewrite_trait_bounds(
context: &RewriteContext,
- type_param_bounds: &ast::TyParamBounds,
+ bounds: &[ast::TyParamBound],
shape: Shape,
) -> Option<String> {
- let bounds: &[_] = type_param_bounds;
-
if bounds.is_empty() {
return Some(String::new());
}
context.codemap,
where_clause.predicates.iter(),
terminator,
+ ",",
|pred| pred.span().lo(),
|pred| pred.span().hi(),
|pred| pred.rewrite(context, clause_shape),
};
let preds_str = write_list(&items.collect::<Vec<_>>(), &fmt)?;
- let comment_separator = |comment: &str, shape: Shape| if comment.is_empty() {
- String::new()
- } else {
- format!("\n{}", shape.indent.to_string(context.config))
+ let comment_separator = |comment: &str, shape: Shape| {
+ if comment.is_empty() {
+ String::new()
+ } else {
+ format!("\n{}", shape.indent.to_string(context.config))
+ }
};
let newline_before_where = comment_separator(&comment_before, shape);
let newline_after_where = comment_separator(&comment_after, clause_shape);
return Some(String::new());
}
- if context.config.where_style() == Style::Rfc {
+ if context.config.indent_style() == IndentStyle::Block {
return rewrite_where_clause_rfc_style(
context,
where_clause,
let extra_indent = Indent::new(context.config.tab_spaces(), 0);
- let offset = match context.config.where_pred_indent() {
+ let offset = match context.config.indent_style() {
IndentStyle::Block => shape.indent + extra_indent.block_indent(context.config),
// 6 = "where ".len()
IndentStyle::Visual => shape.indent + extra_indent + 6,
};
- // FIXME: if where_pred_indent != Visual, then the budgets below might
+ // FIXME: if indent_style != Visual, then the budgets below might
// be out by a char or two.
let budget = context.config.max_width() - offset.width();
context.codemap,
where_clause.predicates.iter(),
terminator,
+ ",",
|pred| pred.span().lo(),
|pred| pred.span().hi(),
|pred| pred.rewrite(context, Shape::legacy(budget, offset)),
false,
);
let item_vec = items.collect::<Vec<_>>();
- // FIXME: we don't need to collect here if the where_layout isn't
- // HorizontalVertical.
- let tactic = definitive_tactic(
- &item_vec,
- context.config.where_layout(),
- Separator::Comma,
- budget,
- );
+ // FIXME: we don't need to collect here
+ let tactic = definitive_tactic(&item_vec, ListTactic::Vertical, Separator::Comma, budget);
let mut comma_tactic = context.config.trailing_comma();
// Kind of a hack because we don't usually have trailing commas in where clauses.
trailing_separator: comma_tactic,
separator_place: SeparatorPlace::Back,
shape: Shape::legacy(budget, offset),
- ends_with_newline: tactic.ends_with_newline(context.config.where_pred_indent()),
+ ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
preserve_newline: true,
config: context.config,
};
format!("{}{}{}", format_visibility(vis), item_name, ident)
}
+#[derive(PartialEq, Eq, Clone, Copy)]
+enum BracePos {
+ None,
+ Auto,
+ ForceSameLine,
+}
+
fn format_generics(
context: &RewriteContext,
generics: &ast::Generics,
- opener: &str,
- terminator: &str,
brace_style: BraceStyle,
- force_same_line_brace: bool,
+ brace_pos: BracePos,
offset: Indent,
span: Span,
used_width: usize,
let same_line_brace = if !generics.where_clause.predicates.is_empty() || result.contains('\n') {
let budget = context.budget(last_line_used_width(&result, offset.width()));
- let option = WhereClauseOption::snuggled(&result);
+ let mut option = WhereClauseOption::snuggled(&result);
+ if brace_pos == BracePos::None {
+ option.suppress_comma = true;
+ }
// If the generics are not parameterized then generics.span.hi() == 0,
// so we use span.lo(), which is the position after `struct Foo`.
let span_end_before_where = if generics.is_parameterized() {
brace_style,
Shape::legacy(budget, offset.block_only()),
Density::Tall,
- terminator,
+ "{",
Some(span.hi()),
span_end_before_where,
option,
false,
)?;
result.push_str(&where_clause_str);
- force_same_line_brace || brace_style == BraceStyle::PreferSameLine
+ brace_pos == BracePos::ForceSameLine || brace_style == BraceStyle::PreferSameLine
|| (generics.where_clause.predicates.is_empty()
&& trimmed_last_line_width(&result) == 1)
} else {
- force_same_line_brace || trimmed_last_line_width(&result) == 1
+ brace_pos == BracePos::ForceSameLine || trimmed_last_line_width(&result) == 1
|| brace_style != BraceStyle::AlwaysNextLine
};
+ if brace_pos == BracePos::None {
+ return Some(result);
+ }
let total_used_width = last_line_used_width(&result, used_width);
let remaining_budget = context.budget(total_used_width);
// If the same line brace if forced, it indicates that we are rewriting an item with empty body,
// and hence we take the closer into account as well for one line budget.
// We assume that the closer has the same length as the opener.
- let overhead = if force_same_line_brace {
- 1 + opener.len() + opener.len()
+ let overhead = if brace_pos == BracePos::ForceSameLine {
+ // 3 = ` {}`
+ 3
} else {
- 1 + opener.len()
+ // 2 = ` {`
+ 2
};
let forbid_same_line_brace = overhead > remaining_budget;
if !forbid_same_line_brace && same_line_brace {
result.push('\n');
result.push_str(&offset.block_only().to_string(context.config));
}
- result.push_str(opener);
+ result.push('{');
Some(result)
}
let span = mk_sp(self.span.lo(), self.span.hi() - BytePos(1));
let item_str = match self.node {
- ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => rewrite_fn_base(
- context,
- shape.indent,
- self.ident,
- &FnSig::new(fn_decl, generics, self.vis.clone()),
- span,
- false,
- false,
- ).map(|(s, _)| format!("{};", s)),
+ ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
+ rewrite_fn_base(
+ context,
+ shape.indent,
+ self.ident,
+ &FnSig::new(fn_decl, generics, self.vis.clone()),
+ span,
+ false,
+ false,
+ ).map(|(s, _)| format!("{};", s))
+ }
ast::ForeignItemKind::Static(ref ty, is_mutable) => {
// FIXME(#21): we're dropping potential comments in between the
// function keywords here.