diff --git a/src/expr.rs b/src/expr.rs index a8f1c3a01b55..69f62319ade2 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -599,11 +599,14 @@ fn rewrite_closure_block(block: &ast::Block, -> Option { // Start with visual indent, then fall back to block indent if the // closure is large. - if let Some(block_str) = block.rewrite(&context, shape) { - let block_threshold = context.config.closure_block_indent_threshold(); - if block_threshold < 0 || block_str.matches('\n').count() <= block_threshold as usize { - if let Some(block_str) = block_str.rewrite(context, shape) { - return Some(format!("{} {}", prefix, block_str)); + let block_threshold = context.config.closure_block_indent_threshold(); + if block_threshold >= 0 { + 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) { + if let Some(block_str) = block_str.rewrite(context, shape) { + return Some(format!("{} {}", prefix, block_str)); + } } } } @@ -1676,20 +1679,40 @@ fn rewrite_call_inner(context: &RewriteContext, .ok_or(Ordering::Greater)?; let span_lo = context.codemap.span_after(span, "("); - let span = mk_sp(span_lo, span.hi); + let new_span = mk_sp(span_lo, span.hi); let (extendable, list_str) = rewrite_call_args(context, args, - span, + new_span, nested_shape, one_line_width, force_trailing_comma) .ok_or(Ordering::Less)?; + + if !use_block_indent(context) && need_block_indent(&list_str, nested_shape) && !extendable { + println!("here"); + let mut new_context = context.clone(); + new_context.use_block = true; + return rewrite_call_inner(&new_context, + callee_str, + args, + span, + shape, + force_trailing_comma); + } + Ok(format!("{}{}", callee_str, wrap_args_with_parens(context, &list_str, extendable, shape, nested_shape))) } +fn need_block_indent(s: &str, shape: Shape) -> bool { + s.lines().skip(1).any(|s| { + s.find(|c| !char::is_whitespace(c)) + .map_or(false, |w| w + 1 < shape.indent.width()) + }) +} + fn rewrite_call_args(context: &RewriteContext, args: &[ptr::P], span: Span, @@ -1720,8 +1743,7 @@ fn rewrite_call_args(context: &RewriteContext, // Replace the last item with its first line to see if it fits with // first arguments. if overflow_last { - let arg_shape = if context.config.fn_call_style() == IndentStyle::Block && - is_extendable(args) { + let arg_shape = if use_block_indent(context) && is_extendable(args) { Shape { width: context.config.fn_call_width(), indent: shape.block().indent.block_unindent(context.config), @@ -1799,8 +1821,7 @@ fn rewrite_call_args(context: &RewriteContext, // If arguments do not fit in a single line and do not contain newline, // try to put it on the next line. Try this only when we are in block mode // and not rewriting macro. - Some(ref s) if context.config.fn_call_style() == IndentStyle::Block && - !context.inside_macro && + Some(ref s) if use_block_indent(context) && !context.inside_macro && ((!can_be_overflowed(context, args) && last_char_is_not_comma && s.contains('\n')) || first_line_width(s) > one_line_budget) => { @@ -1814,23 +1835,25 @@ fn rewrite_call_args(context: &RewriteContext, } } +fn use_block_indent(context: &RewriteContext) -> bool { + context.config.fn_call_style() == IndentStyle::Block || context.use_block +} + fn can_be_overflowed(context: &RewriteContext, args: &[ptr::P]) -> bool { match args.last().map(|x| &x.node) { Some(&ast::ExprKind::Match(..)) => { - (context.config.fn_call_style() == IndentStyle::Block && args.len() == 1) || + (use_block_indent(context) && args.len() == 1) || (context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1) } Some(&ast::ExprKind::Block(..)) | Some(&ast::ExprKind::Closure(..)) => { - context.config.fn_call_style() == IndentStyle::Block || + use_block_indent(context) || context.config.fn_call_style() == IndentStyle::Visual && args.len() > 1 } Some(&ast::ExprKind::Call(..)) | Some(&ast::ExprKind::Mac(..)) | - Some(&ast::ExprKind::Struct(..)) => { - context.config.fn_call_style() == IndentStyle::Block && args.len() == 1 - } - Some(&ast::ExprKind::Tup(..)) => context.config.fn_call_style() == IndentStyle::Block, + Some(&ast::ExprKind::Struct(..)) => use_block_indent(context) && args.len() == 1, + Some(&ast::ExprKind::Tup(..)) => use_block_indent(context), _ => false, } } @@ -1865,8 +1888,8 @@ fn wrap_args_with_parens(context: &RewriteContext, shape: Shape, nested_shape: Shape) -> String { - if context.config.fn_call_style() == IndentStyle::Visual || - (context.inside_macro && !args_str.contains('\n')) || is_extendable { + if !use_block_indent(context) || (context.inside_macro && !args_str.contains('\n')) || + is_extendable { if context.config.spaces_within_parens() && args_str.len() > 0 { format!("( {} )", args_str) } else { @@ -2062,9 +2085,10 @@ fn shape_from_fn_call_style(context: &RewriteContext, overhead: usize, offset: usize) -> Option { - match context.config.fn_call_style() { - IndentStyle::Block => Some(shape.block().block_indent(context.config.tab_spaces())), - IndentStyle::Visual => shape.visual_indent(offset).sub_width(overhead), + if use_block_indent(context) { + Some(shape.block().block_indent(context.config.tab_spaces())) + } else { + shape.visual_indent(offset).sub_width(overhead) } } diff --git a/src/rewrite.rs b/src/rewrite.rs index c1047e41b33c..272e67756abb 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -27,6 +27,7 @@ pub struct RewriteContext<'a> { pub codemap: &'a CodeMap, pub config: &'a Config, pub inside_macro: bool, + pub use_block: bool, } impl<'a> RewriteContext<'a> { diff --git a/src/visitor.rs b/src/visitor.rs index 9ce200a915ed..affcbf6b082d 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -610,6 +610,7 @@ pub fn get_context(&self) -> RewriteContext { codemap: self.codemap, config: self.config, inside_macro: false, + use_block: false, } } } diff --git a/tests/target/nested-visual-block.rs b/tests/target/nested-visual-block.rs new file mode 100644 index 000000000000..7dd75c52891f --- /dev/null +++ b/tests/target/nested-visual-block.rs @@ -0,0 +1,57 @@ +fn main() { + // #1078 + let items = itemize_list( + context.codemap, + field_iter, + "}", + |item| match *item { + StructLitField::Regular(ref field) => field.span.lo, + StructLitField::Base(ref 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 pos = snippet.find_uncommented("..").unwrap(); + last_field_hi + BytePos(pos as u32) + } + }, + |item| match *item { + StructLitField::Regular(ref field) => field.span.hi, + StructLitField::Base(ref expr) => expr.span.hi, + }, + |item| { + match *item { + StructLitField::Regular(ref field) => { + rewrite_field(inner_context, + &field, + &Constraints::new(v_budget.checked_sub(1).unwrap_or(0), indent)) + } + StructLitField::Base(ref expr) => { + // 2 = .. + expr.rewrite(inner_context, + &Constraints::new(try_opt!(v_budget.checked_sub(2)), indent + 2)) + .map(|s| format!("..{}", s)) + } + } + }, + context.codemap.span_after(span, "{"), + span.hi, + ); + + // #1580 + self.0.pool.execute(move || { + let _timer = segments.0.rotate_timer.time(); + if let Err(e) = segments.rotate_async(wal) { + error!("error compacting segment storage WAL", unsafe { error: e.display() }); + } + }); + + // #1581 + bootstrap.checks.register( + "PERSISTED_LOCATIONS", + move || if locations2.0.inner_mut.lock().poisoned { + Check::new(State::Error, + "Persisted location storage is poisoned due to a write failure") + } else { + Check::new(State::Healthy, "Persisted location storage is healthy") + } + ); +}