use chains::rewrite_chain;
use codemap::{LineRangeUtils, SpanUtils};
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
- rewrite_comment, FindUncommented};
+ rewrite_comment, rewrite_missing_comment, FindUncommented};
use config::{Config, ControlBraceStyle, IndentStyle, MultilineStyle, Style};
use items::{span_hi_for_arg, span_lo_for_arg};
use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting,
struct_lit_shape, struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting,
- ListItem, ListTactic, Separator, SeparatorTactic};
-use macros::{rewrite_macro, MacroPosition};
+ ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
+use macros::{rewrite_macro, MacroArg, MacroPosition};
use patterns::{can_be_overflowed_pat, TuplePatField};
use rewrite::{Rewrite, RewriteContext};
use string::{rewrite_string, StringFormat};
}
}
-#[derive(PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
pub enum ExprType {
Statement,
SubExpression,
let expr_rw = match expr.node {
ast::ExprKind::Array(ref expr_vec) => rewrite_array(
expr_vec.iter().map(|e| &**e),
- mk_sp(context.codemap.span_after(expr.span, "["), expr.span.hi),
+ mk_sp(context.codemap.span_after(expr.span, "["), expr.span.hi()),
context,
shape,
false,
),
},
ast::ExprKind::Call(ref callee, ref args) => {
- let inner_span = mk_sp(callee.span.hi, expr.span.hi);
+ let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
rewrite_call_with_binary_search(
context,
&**callee,
ExprType::Statement => {
if is_unsafe_block(block) {
block.rewrite(context, shape)
- } else {
+ } else if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
// Rewrite block without trying to put it in a single line.
- if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
- return rw;
- }
+ rw
+ } else {
let prefix = try_opt!(block_prefix(context, block, shape));
rewrite_block_with_visitor(context, &prefix, block, shape)
}
)
}
}
+ ast::ExprKind::Yield(ref opt_expr) => if let Some(ref expr) = *opt_expr {
+ rewrite_unary_prefix(context, "yield ", &**expr, shape)
+ } else {
+ wrap_str("yield".to_string(), context.config.max_width(), shape)
+ },
ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
rewrite_closure(capture, fn_decl, body, expr.span, context, shape)
}
}
match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
- (Some(ref lhs), Some(ref rhs)) => {
+ (Some(lhs), Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {} ", delim)
} else if needs_space_before_range(context, lhs) {
} else {
delim.into()
};
- rewrite_pair(&**lhs, &**rhs, "", &sp_delim, "", context, shape)
+ rewrite_pair(&*lhs, &*rhs, "", &sp_delim, "", context, shape)
}
- (None, Some(ref rhs)) => {
+ (None, Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!("{} ", delim)
} else {
delim.into()
};
- rewrite_unary_prefix(context, &sp_delim, &**rhs, shape)
+ rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
}
- (Some(ref lhs), None) => {
+ (Some(lhs), None) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {}", delim)
} else {
delim.into()
};
- rewrite_unary_suffix(context, &sp_delim, &**lhs, shape)
+ rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
}
(None, None) => wrap_str(delim.into(), context.config.max_width(), shape),
}
shape,
),
ast::ExprKind::Catch(ref block) => {
- if let rewrite @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape)
- {
- return rewrite;
+ if let rw @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape) {
+ rw
+ } else {
+ // 9 = `do catch `
+ let budget = shape.width.checked_sub(9).unwrap_or(0);
+ Some(format!(
+ "{}{}",
+ "do catch ",
+ try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
+ ))
}
- // 9 = `do catch `
- let budget = shape.width.checked_sub(9).unwrap_or(0);
- Some(format!(
- "{}{}",
- "do catch ",
- try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
- ))
}
};
let attrs = outer_attributes(&expr.attrs);
let attrs_str = try_opt!(attrs.rewrite(context, shape));
let span = mk_sp(
- attrs.last().map_or(expr.span.lo, |attr| attr.span.hi),
- expr.span.lo,
+ attrs.last().map_or(expr.span.lo(), |attr| attr.span.hi()),
+ expr.span.lo(),
);
combine_strs_with_missing_comments(context, &attrs_str, &expr_str, span, shape, false)
})
context.codemap,
expr_iter,
"]",
- |item| item.span.lo,
- |item| item.span.hi,
+ |item| item.span.lo(),
+ |item| item.span.hi(),
|item| item.rewrite(context, nested_shape),
- span.lo,
- span.hi,
+ span.lo(),
+ span.hi(),
false,
).collect::<Vec<_>>();
} else {
SeparatorTactic::Vertical
},
+ separator_place: SeparatorPlace::Back,
shape: nested_shape,
ends_with_newline: ends_with_newline,
preserve_newline: false,
let result = if context.config.array_layout() == IndentStyle::Visual ||
tactic == DefinitiveListTactic::Horizontal
{
- if context.config.spaces_within_square_brackets() && list_str.len() > 0 {
+ if context.config.spaces_within_square_brackets() && !list_str.is_empty() {
format!("[ {} ]", list_str)
} else {
format!("[{}]", list_str)
|arg| span_hi_for_arg(context, arg),
|arg| arg.rewrite(context, arg_shape),
context.codemap.span_after(span, "|"),
- body.span.lo,
+ body.span.lo(),
false,
);
let item_vec = arg_items.collect::<Vec<_>>();
tactic: tactic,
separator: ",",
trailing_separator: SeparatorTactic::Never,
+ separator_place: SeparatorPlace::Back,
shape: arg_shape,
ends_with_newline: false,
preserve_newline: true,
};
if no_return_type && !needs_block {
// lock.stmts.len() == 1
- if let Some(ref expr) = stmt_expr(&block.stmts[0]) {
+ if let Some(expr) = stmt_expr(&block.stmts[0]) {
if let Some(rw) = rewrite_closure_expr(expr, &prefix, context, body_shape) {
return Some(rw);
}
}
// Either we require a block, or tried without and failed.
- rewrite_closure_block(&block, &prefix, context, body_shape)
+ rewrite_closure_block(block, &prefix, context, body_shape)
} else {
rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|| {
// The closure originally had a non-block expression, but we can't fit on
if classify::expr_requires_semi_to_be_stmt(left_most_sub_expr(expr)) {
rewrite = and_one_line(rewrite);
}
+ rewrite = rewrite.and_then(|rw| {
+ if context.config.multiline_closure_forces_block() && rw.contains('\n') {
+ None
+ } else {
+ Some(rw)
+ }
+ });
rewrite.map(|rw| format!("{} {}", prefix, rw))
}
// closure is large.
let block_threshold = context.config.closure_block_indent_threshold();
if block_threshold >= 0 {
- if let Some(block_str) = block.rewrite(&context, shape) {
+ if let Some(block_str) = block.rewrite(context, shape) {
if block_str.matches('\n').count() <= block_threshold as usize &&
!need_block_indent(&block_str, shape)
{
// The body of the closure is big enough to be block indented, that
// means we must re-format.
let block_shape = shape.block();
- let block_str = try_opt!(block.rewrite(&context, block_shape));
+ let block_str = try_opt!(block.rewrite(context, block_shape));
Some(format!("{} {}", prefix, block_str))
}
ast::BlockCheckMode::Unsafe(..) => {
let snippet = context.snippet(block.span);
let open_pos = try_opt!(snippet.find_uncommented("{"));
- visitor.last_pos = block.span.lo + BytePos(open_pos as u32)
+ visitor.last_pos = block.span.lo() + BytePos(open_pos as u32)
}
- ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo,
+ ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo(),
}
visitor.visit_block(block, None);
""
};
- format_expr(
- ex,
- match self.node {
- ast::StmtKind::Expr(_) => ExprType::SubExpression,
- ast::StmtKind::Semi(_) => ExprType::Statement,
- _ => unreachable!(),
- },
- context,
- try_opt!(shape.sub_width(suffix.len())),
- ).map(|s| s + suffix)
+ let shape = try_opt!(shape.sub_width(suffix.len()));
+ format_expr(ex, ExprType::Statement, context, shape).map(|s| s + suffix)
}
ast::StmtKind::Mac(..) | ast::StmtKind::Item(..) => None,
};
let cond_span = if let Some(cond) = self.cond {
cond.span
} else {
- mk_sp(self.block.span.lo, self.block.span.lo)
+ mk_sp(self.block.span.lo(), self.block.span.lo())
};
- // for event in event
+ // `for event in event`
+ // Do not include label in the span.
+ let lo = self.label.map_or(self.span.lo(), |label| label.span.hi());
let between_kwd_cond = mk_sp(
- context.codemap.span_after(self.span, self.keyword.trim()),
+ context
+ .codemap
+ .span_after(mk_sp(lo, self.span.hi()), self.keyword.trim()),
self.pat
- .map_or(cond_span.lo, |p| if self.matcher.is_empty() {
- p.span.lo
+ .map_or(cond_span.lo(), |p| if self.matcher.is_empty() {
+ p.span.lo()
} else {
context.codemap.span_before(self.span, self.matcher.trim())
}),
let between_kwd_cond_comment = extract_comment(between_kwd_cond, context, shape);
let after_cond_comment =
- extract_comment(mk_sp(cond_span.hi, self.block.span.lo), context, shape);
+ extract_comment(mk_sp(cond_span.hi(), self.block.span.lo()), context, shape);
let block_sep = if self.cond.is_none() && between_kwd_cond_comment.is_some() {
""
next_else_block.as_ref().map(|e| &**e),
false,
true,
- mk_sp(else_block.span.lo, self.span.hi),
+ mk_sp(else_block.span.lo(), self.span.hi()),
).rewrite(context, shape)
}
ast::ExprKind::If(ref cond, ref if_block, ref next_else_block) => {
next_else_block.as_ref().map(|e| &**e),
false,
true,
- mk_sp(else_block.span.lo, self.span.hi),
+ mk_sp(else_block.span.lo(), self.span.hi()),
).rewrite(context, shape)
}
_ => {
};
let between_kwd_else_block = mk_sp(
- self.block.span.hi,
+ self.block.span.hi(),
context
.codemap
- .span_before(mk_sp(self.block.span.hi, else_block.span.lo), "else"),
+ .span_before(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
);
let between_kwd_else_block_comment =
extract_comment(between_kwd_else_block, context, shape);
let after_else = mk_sp(
context
.codemap
- .span_after(mk_sp(self.block.span.hi, else_block.span.lo), "else"),
- else_block.span.lo,
+ .span_after(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
+ else_block.span.lo(),
);
let after_else_comment = extract_comment(after_else, context, shape);
}
fn extract_comment(span: Span, context: &RewriteContext, shape: Shape) -> Option<String> {
- let comment_str = context.snippet(span);
- if contains_comment(&comment_str) {
- let comment = try_opt!(rewrite_comment(
- comment_str.trim(),
- false,
- shape,
- context.config,
- ));
- Some(format!(
+ match rewrite_missing_comment(span, shape, context) {
+ Some(ref comment) if !comment.is_empty() => Some(format!(
"\n{indent}{}\n{indent}",
comment,
indent = shape.indent.to_string(context.config)
- ))
- } else {
- None
+ )),
+ _ => None,
}
}
let open_brace_pos = if inner_attrs.is_empty() {
context
.codemap
- .span_after(mk_sp(cond.span.hi, arms[0].span().lo), "{")
+ .span_after(mk_sp(cond.span.hi(), arms[0].span().lo()), "{")
} else {
- inner_attrs[inner_attrs.len() - 1].span().hi
+ inner_attrs[inner_attrs.len() - 1].span().hi()
};
let arm_indent_str = if context.config.indent_match_arms() {
.zip(is_last_iter)
.map(|(arm, is_last)| ArmWrapper::new(arm, is_last)),
"}",
- |arm| arm.arm.span().lo,
- |arm| arm.arm.span().hi,
+ |arm| arm.arm.span().lo(),
+ |arm| arm.arm.span().hi(),
|arm| arm.rewrite(context, arm_shape),
open_brace_pos,
- span.hi,
+ span.hi(),
false,
);
let arms_vec: Vec<_> = items.collect();
// We will add/remove commas inside `arm.rewrite()`, and hence no separator here.
separator: "",
trailing_separator: SeparatorTactic::Never,
+ separator_place: SeparatorPlace::Back,
shape: arm_shape,
ends_with_newline: true,
preserve_newline: true,
));
}
(
- mk_sp(arm.attrs[arm.attrs.len() - 1].span.hi, arm.pats[0].span.lo),
+ mk_sp(
+ arm.attrs[arm.attrs.len() - 1].span.hi(),
+ arm.pats[0].span.lo(),
+ ),
try_opt!(arm.attrs.rewrite(context, shape)),
)
} else {
- (mk_sp(arm.span().lo, arm.span().lo), String::new())
+ (mk_sp(arm.span().lo(), arm.span().lo()), String::new())
};
let pats_str = try_opt!(
rewrite_match_pattern(context, &arm.pats, &arm.guard, shape).and_then(|pats_str| {
fn rewrite_match_pattern(
context: &RewriteContext,
- pats: &Vec<ptr::P<ast::Pat>>,
+ pats: &[ptr::P<ast::Pat>],
guard: &Option<ptr::P<ast::Expr>>,
shape: Shape,
) -> Option<String> {
tactic: tactic,
separator: " |",
trailing_separator: SeparatorTactic::Never,
+ separator_place: context.config.match_pattern_separator_break_point(),
shape: pat_shape,
ends_with_newline: false,
preserve_newline: false,
if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
{
if let ast::StmtKind::Expr(ref expr) = block.stmts[0].node {
- (expr.can_be_overflowed(context, 1), &**expr)
+ (
+ !context.config.multiline_match_arm_forces_block() &&
+ expr.can_be_overflowed(context, 1),
+ &**expr,
+ )
} else {
(false, &*body)
}
}
- _ => (body.can_be_overflowed(context, 1), &*body),
+ _ => (
+ !context.config.multiline_match_arm_forces_block() &&
+ body.can_be_overflowed(context, 1),
+ &*body,
+ ),
}
}
has_guard: bool,
is_last: bool,
) -> Option<String> {
- let (extend, body) = flatten_arm_body(context, &body);
+ let (extend, body) = flatten_arm_body(context, body);
- let comma = arm_comma(&context.config, body, is_last);
+ let comma = arm_comma(context.config, body, is_last);
let alt_block_sep = String::from("\n") + &shape.indent.block_only().to_string(context.config);
let alt_block_sep = alt_block_sep.as_str();
let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block) = body.node {
// Let's try and get the arm body on the same line as the condition.
// 4 = ` => `.len()
let orig_body_shape = shape
- .offset_left(extra_offset(&pats_str, shape) + 4)
+ .offset_left(extra_offset(pats_str, shape) + 4)
.and_then(|shape| shape.sub_width(comma.len()));
let orig_body = if let Some(body_shape) = orig_body_shape {
let rewrite = nop_block_collapse(
string: &str,
shape: Shape,
) -> bool {
- if context.codemap.lookup_char_pos(span.lo).col.0 != shape.indent.width() {
+ if context.codemap.lookup_char_pos(span.lo()).col.0 != shape.indent.width() {
return true;
}
if line.len() > shape.width {
return true;
}
- } else {
- if line.len() > shape.width + shape.indent.width() {
- return true;
- }
+ } else if line.len() > shape.width + shape.indent.width() {
+ return true;
}
}
};
rewrite_call_inner(
context,
- &callee,
+ callee,
&args.iter().map(|x| &**x).collect::<Vec<_>>(),
span,
shape,
} else {
1
};
- let used_width = extra_offset(&callee_str, shape);
+ let used_width = extra_offset(callee_str, shape);
let one_line_width = shape
.width
.checked_sub(used_width + 2 * paren_overhead)
).ok_or(Ordering::Greater)?;
let span_lo = context.codemap.span_after(span, "(");
- let args_span = mk_sp(span_lo, span.hi);
+ let args_span = mk_sp(span_lo, span.hi());
let (extendable, list_str) = rewrite_call_args(
context,
}
let args_shape = shape
- .sub_width(last_line_width(&callee_str))
+ .sub_width(last_line_width(callee_str))
.ok_or(Ordering::Less)?;
Ok(format!(
"{}{}",
context.codemap,
args.iter(),
")",
- |item| item.span().lo,
- |item| item.span().hi,
+ |item| item.span().lo(),
+ |item| item.span().hi(),
|item| item.rewrite(context, shape),
- span.lo,
- span.hi,
+ span.lo(),
+ span.hi(),
true,
);
let mut item_vec: Vec<_> = items.collect();
} else {
context.config.trailing_comma()
},
+ separator_place: SeparatorPlace::Back,
shape: shape,
ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
preserve_newline: false,
where
T: Rewrite + Spanned + ToExpr + 'a,
{
- let overflow_last = can_be_overflowed(&context, args);
+ let overflow_last = can_be_overflowed(context, args);
// Replace the last item with its first line to see if it fits with
// first arguments.
let placeholder = if overflow_last {
let mut context = context.clone();
if let Some(expr) = args[args.len() - 1].to_expr() {
- match expr.node {
- ast::ExprKind::MethodCall(..) => context.force_one_line_chain = true,
- _ => (),
+ if let ast::ExprKind::MethodCall(..) = expr.node {
+ context.force_one_line_chain = true;
}
}
- last_arg_shape(&context, &item_vec, shape, args_max_width).and_then(|arg_shape| {
+ last_arg_shape(&context, item_vec, shape, args_max_width).and_then(|arg_shape| {
rewrite_last_arg_with_overflow(&context, args, &mut item_vec[args.len() - 1], arg_shape)
})
} else {
fn last_arg_shape(
context: &RewriteContext,
- items: &Vec<ListItem>,
+ items: &[ListItem],
shape: Shape,
args_max_width: usize,
) -> Option<Shape> {
let overhead = items.iter().rev().skip(1).fold(0, |acc, i| {
- acc + i.item.as_ref().map_or(0, |s| first_line_width(&s))
+ acc + i.item.as_ref().map_or(0, |s| first_line_width(s))
});
let max_width = min(args_max_width, shape.width);
let arg_indent = if context.use_block_indent() {
(context.inside_macro && !args_str.contains('\n') &&
args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
{
- if context.config.spaces_within_parens() && args_str.len() > 0 {
+ if context.config.spaces_within_parens() && !args_str.is_empty() {
format!("( {} )", args_str)
} else {
format!("({})", args_str)
.and_then(|s| s.sub_width(paren_overhead))
);
- let paren_wrapper = |s: &str| if context.config.spaces_within_parens() && s.len() > 0 {
+ let paren_wrapper = |s: &str| if context.config.spaces_within_parens() && !s.is_empty() {
format!("( {} )", s)
} else {
format!("({})", s)
(_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
"{}\n{}{}{}{}",
expr_str,
- indent.to_string(&context.config),
+ indent.to_string(context.config),
lbr,
new_index_str,
rbr
(None, Some(ref new_index_str)) => Some(format!(
"{}\n{}{}{}{}",
expr_str,
- indent.to_string(&context.config),
+ indent.to_string(context.config),
lbr,
new_index_str,
rbr
path_shape,
));
- if fields.len() == 0 && base.is_none() {
+ if fields.is_empty() && base.is_none() {
return Some(format!("{} {{}}", path_str));
}
fields,
context,
shape,
- mk_sp(body_lo, span.hi),
+ mk_sp(body_lo, span.hi()),
one_line_width,
))
} else {
.chain(base.into_iter().map(StructLitField::Base));
let span_lo = |item: &StructLitField| match *item {
- StructLitField::Regular(field) => field.span().lo,
+ StructLitField::Regular(field) => field.span().lo(),
StructLitField::Base(expr) => {
- let last_field_hi = fields.last().map_or(span.lo, |field| field.span.hi);
- let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo));
+ let last_field_hi = fields.last().map_or(span.lo(), |field| field.span.hi());
+ let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo()));
let pos = snippet.find_uncommented("..").unwrap();
last_field_hi + BytePos(pos as u32)
}
};
let span_hi = |item: &StructLitField| match *item {
- StructLitField::Regular(field) => field.span().hi,
- StructLitField::Base(expr) => expr.span.hi,
+ StructLitField::Regular(field) => field.span().hi(),
+ StructLitField::Base(expr) => expr.span.hi(),
};
let rewrite = |item: &StructLitField| match *item {
StructLitField::Regular(field) => {
span_hi,
rewrite,
body_lo,
- span.hi,
+ span.hi(),
false,
);
let item_vec = items.collect::<Vec<_>>();
"{}{}:\n{}{}",
attrs_str,
name,
- expr_offset.to_string(&context.config),
+ expr_offset.to_string(context.config),
s
)
})
context.codemap,
items,
")",
- |item| item.span().lo,
- |item| item.span().hi,
+ |item| item.span().lo(),
+ |item| item.span().hi(),
|item| item.rewrite(context, nested_shape),
list_lo,
- span.hi - BytePos(1),
+ span.hi() - BytePos(1),
false,
);
let item_vec: Vec<_> = items.collect();
tactic: tactic,
separator: ",",
trailing_separator: SeparatorTactic::Never,
+ separator_place: SeparatorPlace::Back,
shape: shape,
ends_with_newline: false,
preserve_newline: false,
};
let list_str = try_opt!(write_list(&item_vec, &fmt));
- if context.config.spaces_within_parens() && list_str.len() > 0 {
+ if context.config.spaces_within_parens() && !list_str.is_empty() {
Some(format!("( {} )", list_str))
} else {
Some(format!("({})", list_str))
{
debug!("rewrite_tuple {:?}", shape);
if context.use_block_indent() {
- // We use the same rule as funcation call for rewriting tuple.
+ // We use the same rule as function calls for rewriting tuples.
let force_trailing_comma = if context.inside_macro {
span_ends_with_comma(context, span)
} else {
false
}
}
+
+impl<'a> ToExpr for MacroArg {
+ fn to_expr(&self) -> Option<&ast::Expr> {
+ match self {
+ &MacroArg::Expr(ref expr) => Some(expr),
+ _ => None,
+ }
+ }
+
+ fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
+ match self {
+ &MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
+ &MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
+ &MacroArg::Pat(..) => false,
+ }
+ }
+}