From a91fd699a012ae99bf36d12d88f98154e363979e Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 15 Apr 2017 18:40:39 +0900 Subject: [PATCH 1/2] Add heuristic choosing block or visual indent for unary op based on span --- src/expr.rs | 35 +++++++++++++++++++++++++++-------- src/patterns.rs | 6 ++++-- src/types.rs | 2 +- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 2723c4099c1..0a17bff9d01 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -157,7 +157,11 @@ fn format_expr(expr: &ast::Expr, }; if let Some(ref expr) = *opt_expr { - rewrite_unary_prefix(context, &format!("break{} ", id_str), &**expr, shape) + rewrite_unary_prefix(context, + &format!("break{} ", id_str), + &**expr, + shape, + expr.span) } else { wrap_str(format!("break{}", id_str), context.config.max_width, shape) } @@ -178,9 +182,11 @@ fn format_expr(expr: &ast::Expr, } ast::ExprKind::Ret(None) => wrap_str("return".to_owned(), context.config.max_width, shape), ast::ExprKind::Ret(Some(ref expr)) => { - rewrite_unary_prefix(context, "return ", &**expr, shape) + rewrite_unary_prefix(context, "return ", &**expr, shape, expr.span) + } + ast::ExprKind::Box(ref expr) => { + rewrite_unary_prefix(context, "box ", &**expr, shape, expr.span) } - ast::ExprKind::Box(ref expr) => rewrite_unary_prefix(context, "box ", &**expr, shape), ast::ExprKind::AddrOf(mutability, ref expr) => { rewrite_expr_addrof(context, mutability, expr, shape) } @@ -222,7 +228,7 @@ fn format_expr(expr: &ast::Expr, } else { delim.into() }; - rewrite_unary_prefix(context, &sp_delim, &**rhs, shape) + rewrite_unary_prefix(context, &sp_delim, &**rhs, shape, expr.span) } (Some(ref lhs), None) => { let sp_delim = if context.config.spaces_around_ranges { @@ -1997,9 +2003,22 @@ pub fn rewrite_tuple<'a, I>(context: &RewriteContext, pub fn rewrite_unary_prefix(context: &RewriteContext, prefix: &str, rewrite: &R, - shape: Shape) + mut shape: Shape, + span: Span) -> Option { - let shape = try_opt!(shape.shrink_left(prefix.len())).visual_indent(0); + // Heuristic: if unary is `&` and `rewrite` contains `{`, + // it is likely that block indent is preferred to visual indent. + if prefix == "&" { + let snippet = String::from(context.snippet(span).trim_left_matches('&')); + let first_line = try_opt!(snippet.lines().nth(0)); + if first_line.contains("{") { + shape = try_opt!(shape.sub_width(prefix.len())).block_indent(0); + } else { + shape = try_opt!(shape.shrink_left(prefix.len())).visual_indent(0); + } + } else { + shape = try_opt!(shape.shrink_left(prefix.len())).visual_indent(0); + } rewrite .rewrite(context, shape) .map(|r| format!("{}{}", prefix, r)) @@ -2031,7 +2050,7 @@ fn rewrite_unary_op(context: &RewriteContext, ast::UnOp::Not => "!", ast::UnOp::Neg => "-", }; - rewrite_unary_prefix(context, operator_str, expr, shape) + rewrite_unary_prefix(context, operator_str, expr, shape, expr.span) } fn rewrite_assignment(context: &RewriteContext, @@ -2126,5 +2145,5 @@ fn rewrite_expr_addrof(context: &RewriteContext, ast::Mutability::Immutable => "&", ast::Mutability::Mutable => "&mut ", }; - rewrite_unary_prefix(context, operator_str, expr, shape) + rewrite_unary_prefix(context, operator_str, expr, shape, expr.span) } diff --git a/src/patterns.rs b/src/patterns.rs index bc5c917dc00..1ed13ab70b6 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -27,7 +27,9 @@ use syntax::codemap::{self, BytePos, Span}; impl Rewrite for Pat { fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { match self.node { - PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape), + PatKind::Box(ref pat) => { + rewrite_unary_prefix(context, "box ", &**pat, shape, self.span) + } PatKind::Ident(binding_mode, ident, ref sub_pat) => { let (prefix, mutability) = match binding_mode { BindingMode::ByRef(mutability) => ("ref ", mutability), @@ -71,7 +73,7 @@ impl Rewrite for Pat { } PatKind::Ref(ref pat, mutability) => { let prefix = format!("&{}", format_mutability(mutability)); - rewrite_unary_prefix(context, &prefix, &**pat, shape) + rewrite_unary_prefix(context, &prefix, &**pat, shape, self.span) } PatKind::Tuple(ref items, dotdot_pos) => { rewrite_tuple_pat(items, dotdot_pos, None, self.span, context, shape) diff --git a/src/types.rs b/src/types.rs index d766b9770de..b8038de709f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -580,7 +580,7 @@ impl Rewrite for ast::Ty { Mutability::Immutable => "*const ", }; - rewrite_unary_prefix(context, prefix, &*mt.ty, shape) + rewrite_unary_prefix(context, prefix, &*mt.ty, shape, self.span) } ast::TyKind::Rptr(ref lifetime, ref mt) => { let mut_str = format_mutability(mt.mutbl); From 0614e94d0df2d50f7f16e93c469006a31294ec6d Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 15 Apr 2017 18:42:45 +0900 Subject: [PATCH 2/2] Format source codes --- src/expr.rs | 18 +++++++++--------- src/imports.rs | 6 +++--- tests/target/closure.rs | 16 ++++++++-------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 0a17bff9d01..7b4153083cb 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1230,10 +1230,10 @@ fn rewrite_match(context: &RewriteContext, fn arm_start_pos(arm: &ast::Arm) -> BytePos { let &ast::Arm { - ref attrs, - ref pats, - .. - } = arm; + ref attrs, + ref pats, + .. + } = arm; if !attrs.is_empty() { return attrs[0].span.lo; } @@ -1264,11 +1264,11 @@ impl Rewrite for ast::Arm { fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { debug!("Arm::rewrite {:?} {:?}", self, shape); let &ast::Arm { - ref attrs, - ref pats, - ref guard, - ref body, - } = self; + ref attrs, + ref pats, + ref guard, + ref body, + } = self; // FIXME this is all a bit grotty, would be nice to abstract out the // treatment of attributes. diff --git a/src/imports.rs b/src/imports.rs index 791ff0ee387..99651159b2a 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -133,9 +133,9 @@ fn rewrite_view_path_prefix(path: &ast::Path, let path_str = if path.segments.last().unwrap().identifier.to_string() == "self" && path.segments.len() > 1 { let path = &ast::Path { - span: path.span.clone(), - segments: path.segments[..path.segments.len() - 1].to_owned(), - }; + span: path.span.clone(), + segments: path.segments[..path.segments.len() - 1].to_owned(), + }; try_opt!(rewrite_path(context, PathContext::Import, None, path, shape)) } else { try_opt!(rewrite_path(context, PathContext::Import, None, path, shape)) diff --git a/tests/target/closure.rs b/tests/target/closure.rs index ad6b48aeac9..c9edec799e2 100644 --- a/tests/target/closure.rs +++ b/tests/target/closure.rs @@ -74,16 +74,16 @@ fn issue863() { fn issue934() { let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { - let mut h = SpanlessHash::new(cx); - h.hash_block(block); - h.finish() - }; + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish() + }; let hash: &Fn(&&Block) -> u64 = &|block| -> u64 { - let mut h = SpanlessHash::new(cx); - h.hash_block(block); - h.finish(); - }; + let mut h = SpanlessHash::new(cx); + h.hash_block(block); + h.finish(); + }; } impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {