update Serde, etc.

Lots of changes to how closures work
This commit is contained in:
Nick Cameron 2016-11-21 08:37:35 +13:00
parent 61ab06a92e
commit d3eba76e4d
19 changed files with 349 additions and 303 deletions

64
Cargo.lock generated
View File

@ -7,14 +7,14 @@ dependencies = [
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
"strings 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_errors 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.44.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -46,7 +46,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -70,7 +70,7 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -83,7 +83,7 @@ name = "memchr"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -93,24 +93,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "0.1.77"
version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.3.5"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-serialize"
version = "0.3.19"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -123,36 +123,36 @@ dependencies = [
[[package]]
name = "syntex_errors"
version = "0.44.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntex_pos"
version = "0.44.0"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntex_syntax"
version = "0.44.1"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_errors 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -172,7 +172,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -188,7 +188,7 @@ name = "toml"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -233,17 +233,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
"checksum itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c4a9b56eb56058f43dc66e58f40a214b2ccbc9f3df51861b63d51dec7b65bc3f"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
"checksum multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9223f4774d08e06185e44e555b9a7561243d387bac49c78a6205c42d6975fbf2"
"checksum regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)" = "64b03446c466d35b42f2a8b203c8e03ed8b91c0f17b56e1f84f7210a257aa665"
"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd"
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
"checksum strings 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54f86446ab480b4f60782188f4f78886465c5793aee248cbb48b7fdc0d022420"
"checksum syntex_errors 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0d95d2141ae79f312a01c6934d9984f9d7f5cfaf0c74aae5fbbc234a6dcb77a"
"checksum syntex_pos 0.44.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2cbf0598c5970f2dca122a4e6f7e93bf42f2d0b2dd88c3ea112413152864df"
"checksum syntex_syntax 0.44.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5a89ee386d492cdd3855becec489c25797bb91bcbb3c2478c41969b24cb318a2"
"checksum syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84822a1178204a191239ad844599f8c85c128cf9f4173397def4eb46b55b0aa1"
"checksum syntex_pos 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a43abded5057c75bac8555e46ec913ce502efb418267b1ab8e9783897470c7db"
"checksum syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef781e4b60f03431f1b5b59843546ce60ae029a787770cf8e0969ac1fd063a5"
"checksum term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3deff8a2b3b6607d6d7cc32ac25c0b33709453ca9cceac006caac51e963cf94a"
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"

View File

@ -22,8 +22,8 @@ regex = "0.1"
term = "0.4"
strings = "0.0.1"
diff = "0.1"
syntex_syntax = "0.44"
syntex_errors = "0.44"
syntex_syntax = "0.50"
syntex_errors = "0.50"
log = "0.3"
env_logger = "0.3"
getopts = "0.2"

View File

@ -98,10 +98,8 @@ fn format_crate(verbosity: Verbosity) -> Result<ExitStatus, std::io::Error> {
// Currently only bin and lib files get formatted
let files: Vec<_> = targets.into_iter()
.filter(|t| t.kind.should_format())
.inspect(|t| {
if verbosity == Verbosity::Verbose {
println!("[{:?}] {:?}", t.kind, t.path)
}
.inspect(|t| if verbosity == Verbosity::Verbose {
println!("[{:?}] {:?}", t.kind, t.path)
})
.map(|t| t.path)
.collect();
@ -204,15 +202,12 @@ fn format_files(files: &[PathBuf],
.args(files)
.args(fmt_args)
.spawn()
.map_err(|e| {
match e.kind() {
std::io::ErrorKind::NotFound => {
std::io::Error::new(std::io::ErrorKind::Other,
"Could not run rustfmt, please make sure it is in your \
PATH.")
}
_ => e,
.map_err(|e| match e.kind() {
std::io::ErrorKind::NotFound => {
std::io::Error::new(std::io::ErrorKind::Other,
"Could not run rustfmt, please make sure it is in your PATH.")
}
_ => e,
}));
command.wait()
}

View File

@ -46,7 +46,6 @@ pub trait LineRangeUtils {
}
impl SpanUtils for CodeMap {
#[inline]
fn span_after(&self, original: Span, needle: &str) -> BytePos {
let snippet = self.span_to_snippet(original).unwrap();
let offset = snippet.find_uncommented(needle).unwrap() + needle.len();
@ -54,7 +53,6 @@ impl SpanUtils for CodeMap {
original.lo + BytePos(offset as u32)
}
#[inline]
fn span_after_last(&self, original: Span, needle: &str) -> BytePos {
let snippet = self.span_to_snippet(original).unwrap();
let mut offset = 0;
@ -66,7 +64,6 @@ impl SpanUtils for CodeMap {
original.lo + BytePos(offset as u32)
}
#[inline]
fn span_before(&self, original: Span, needle: &str) -> BytePos {
let snippet = self.span_to_snippet(original).unwrap();
let offset = snippet.find_uncommented(needle).unwrap();

View File

@ -111,12 +111,10 @@ pub fn rewrite_comment(orig: &str,
line.trim_right()
})
.map(left_trim_comment_line)
.map(|line| {
if orig.starts_with("/*") && line_breaks == 0 {
line.trim_left()
} else {
line
}
.map(|line| if orig.starts_with("/*") && line_breaks == 0 {
line.trim_left()
} else {
line
});
let mut result = opener.to_owned();
@ -746,11 +744,9 @@ mod test {
// keeping it around unless it helps us test stuff.
fn uncommented(text: &str) -> String {
CharClasses::new(text.chars())
.filter_map(|(s, c)| {
match s {
FullCodeCharKind::Normal => Some(c),
_ => None,
}
.filter_map(|(s, c)| match s {
FullCodeCharKind::Normal => Some(c),
_ => None,
})
.collect()
}

View File

@ -22,14 +22,14 @@ use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTacti
DefinitiveListTactic, definitive_tactic, ListItem, format_item_list};
use string::{StringFormat, rewrite_string};
use utils::{extra_offset, last_line_width, wrap_str, binary_search, first_line_width,
semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr, stmt_block, stmt_expr};
semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr, stmt_expr};
use visitor::FmtVisitor;
use config::{Config, StructLitStyle, MultilineStyle, ElseIfBraceStyle, ControlBraceStyle};
use comment::{FindUncommented, rewrite_comment, contains_comment, recover_comment_removed};
use types::rewrite_path;
use items::{span_lo_for_arg, span_hi_for_arg};
use chains::rewrite_chain;
use macros::rewrite_macro;
use macros::{rewrite_macro, MacroPosition};
use syntax::{ast, ptr};
use syntax::codemap::{CodeMap, Span, BytePos, mk_sp};
@ -180,12 +180,13 @@ fn format_expr(expr: &ast::Expr,
ast::ExprKind::Mac(ref mac) => {
// Failure to rewrite a marco should not imply failure to
// rewrite the expression.
rewrite_macro(mac, None, context, width, offset).or_else(|| {
wrap_str(context.snippet(expr.span),
context.config.max_width,
width,
offset)
})
rewrite_macro(mac, None, context, width, offset, MacroPosition::Expression)
.or_else(|| {
wrap_str(context.snippet(expr.span),
context.config.max_width,
width,
offset)
})
}
ast::ExprKind::Ret(None) => {
wrap_str("return".to_owned(), context.config.max_width, width, offset)
@ -356,8 +357,7 @@ pub fn rewrite_array<'a, I>(expr_iter: I,
}
// This functions is pretty messy because of the rules around closures and blocks:
// * the body of a closure is represented by an ast::Block, but that does not
// imply there are `{}` (unless the block is empty) (see rust issue #27872),
// TODO
// * if there is a return type, then there must be braces,
// * given a closure with braces, whether that is parsed to give an inner block
// or not depends on if there is a return type and if there are statements
@ -367,7 +367,7 @@ pub fn rewrite_array<'a, I>(expr_iter: I,
// can change whether it is treated as an expression or statement.
fn rewrite_closure(capture: ast::CaptureBy,
fn_decl: &ast::FnDecl,
body: &ast::Block,
body: &ast::Expr,
span: Span,
context: &RewriteContext,
width: usize,
@ -386,7 +386,6 @@ fn rewrite_closure(capture: ast::CaptureBy,
// 1 = |
let argument_offset = offset + 1;
let ret_str = try_opt!(fn_decl.output.rewrite(context, budget, argument_offset));
let force_block = !ret_str.is_empty();
// 1 = space between arguments and return type.
let horizontal_budget = budget.checked_sub(ret_str.len() + 1).unwrap_or(0);
@ -428,97 +427,181 @@ fn rewrite_closure(capture: ast::CaptureBy,
prefix.push_str(&ret_str);
}
if body.stmts.is_empty() {
return Some(format!("{} {{}}", prefix));
}
// 1 = space between `|...|` and body.
let extra_offset = extra_offset(&prefix, offset) + 1;
let budget = try_opt!(width.checked_sub(extra_offset));
let total_offset = offset + extra_offset;
// This is where we figure out whether to use braces or not.
let mut had_braces = true;
let mut inner_block = body;
let mut trailing_expr = stmt_expr(&inner_block.stmts[inner_block.stmts.len() - 1]);
// If there is an inner block and we can ignore it, do so.
if body.stmts.len() == 1 && trailing_expr.is_some() {
if let Some(ref inner) = stmt_block(&inner_block.stmts[0]) {
inner_block = inner;
trailing_expr = if inner_block.stmts.is_empty() {
None
} else {
stmt_expr(&inner_block.stmts[inner_block.stmts.len() - 1])
};
} else if !force_block {
had_braces = false;
if let ast::ExprKind::Block(ref block) = body.node {
// The body of the closure is a block.
if block.stmts.is_empty() && !block_contains_comment(block, context.codemap) {
return Some(format!("{} {{}}", prefix));
}
}
let try_single_line = is_simple_block(inner_block, context.codemap) &&
inner_block.rules == ast::BlockCheckMode::Default;
// Figure out if the block is necessary.
let needs_block = block.rules != ast::BlockCheckMode::Default || block.stmts.len() > 1 ||
block_contains_comment(block, context.codemap) ||
prefix.contains('\n');
if try_single_line && !force_block {
let must_preserve_braces =
trailing_expr.is_none() ||
!classify::expr_requires_semi_to_be_stmt(left_most_sub_expr(trailing_expr.unwrap()));
if !(must_preserve_braces && had_braces) &&
(must_preserve_braces || !prefix.contains('\n')) {
// If we got here, then we can try to format without braces.
let inner_expr = &inner_block.stmts[0];
let mut rewrite = inner_expr.rewrite(context, budget, offset + extra_offset);
if must_preserve_braces {
// If we are here, then failure to rewrite is unacceptable.
if rewrite.is_none() {
return None;
if ret_str.is_empty() && !needs_block {
// lock.stmts.len() == 1
if let Some(ref expr) = stmt_expr(&block.stmts[0]) {
if let Some(rw) = rewrite_closure_expr(expr,
&prefix,
context,
budget,
total_offset) {
return Some(rw);
}
} else {
// Checks if rewrite succeeded and fits on a single line.
rewrite = and_one_line(rewrite);
}
}
if !needs_block {
// We need braces, but we might still prefer a one-liner.
let stmt = &block.stmts[0];
// 4 = braces and spaces.
let mut rewrite = stmt.rewrite(context, try_opt!(budget.checked_sub(4)), total_offset);
// Checks if rewrite succeeded and fits on a single line.
rewrite = and_one_line(rewrite);
if let Some(rewrite) = rewrite {
return Some(format!("{} {}", prefix, rewrite));
return Some(format!("{} {{ {} }}", prefix, rewrite));
}
}
// Either we require a block, or tried without and failed.
return rewrite_closure_block(&block, prefix, context, budget);
}
// If we fell through the above block, then we need braces, but we might
// still prefer a one-liner (we might also have fallen through because of
// lack of space).
if try_single_line && !prefix.contains('\n') {
let inner_expr = &inner_block.stmts[0];
// 4 = braces and spaces.
let mut rewrite = inner_expr.rewrite(context,
try_opt!(budget.checked_sub(4)),
offset + extra_offset);
if let Some(rw) = rewrite_closure_expr(body, &prefix, context, budget, total_offset) {
return Some(rw);
}
// Checks if rewrite succeeded and fits on a single line.
rewrite = and_one_line(rewrite);
// The closure originally had a non-block expression, but we can't fit on
// one line, so we'll insert a block.
let block = ast::Block {
stmts: vec![ast::Stmt {
id: ast::NodeId::new(0),
node: ast::StmtKind::Expr(ptr::P(body.clone())),
span: body.span,
}],
id: ast::NodeId::new(0),
rules: ast::BlockCheckMode::Default,
span: body.span,
};
return rewrite_closure_block(&block, prefix, context, budget);
if let Some(rewrite) = rewrite {
return Some(format!("{} {{ {} }}", prefix, rewrite));
fn rewrite_closure_expr(expr: &ast::Expr,
prefix: &str,
context: &RewriteContext,
budget: usize,
offset: Indent)
-> Option<String> {
let mut rewrite = expr.rewrite(context, budget, offset);
if classify::expr_requires_semi_to_be_stmt(left_most_sub_expr(expr)) {
rewrite = and_one_line(rewrite);
}
rewrite.map(|rw| format!("{} {}", prefix, rw))
}
// We couldn't format the closure body as a single line expression; fall
// back to block formatting.
let body_rewrite = try_opt!(inner_block.rewrite(&context, budget, Indent::empty()));
fn rewrite_closure_block(block: &ast::Block,
prefix: String,
context: &RewriteContext,
budget: usize)
-> Option<String> {
// Start with visual indent, then fall back to block indent if the
// closure is large.
let rewrite = try_opt!(block.rewrite(&context, budget, Indent::empty()));
let block_threshold = context.config.closure_block_indent_threshold;
if block_threshold < 0 || body_rewrite.matches('\n').count() <= block_threshold as usize {
return Some(format!("{} {}", prefix, body_rewrite));
let block_threshold = context.config.closure_block_indent_threshold;
if block_threshold < 0 || rewrite.matches('\n').count() <= block_threshold as usize {
return Some(format!("{} {}", prefix, rewrite));
}
// The body of the closure is big enough to be block indented, that
// means we must re-format.
let mut context = context.clone();
context.block_indent.alignment = 0;
let rewrite = try_opt!(block.rewrite(&context, budget, Indent::empty()));
Some(format!("{} {}", prefix, rewrite))
}
// The body of the closure is big enough to be block indented, that means we
// must re-format.
let mut context = context.clone();
context.block_indent.alignment = 0;
let body_rewrite = try_opt!(inner_block.rewrite(&context, budget, Indent::empty()));
Some(format!("{} {}", prefix, body_rewrite))
// // This is where we figure out whether to use braces or not.
// let mut had_braces = true;
// let mut inner_block = body;
// let mut trailing_expr = stmt_expr(&inner_block.stmts[inner_block.stmts.len() - 1]);
// // If there is an inner block and we can ignore it, do so.
// if body.stmts.len() == 1 && trailing_expr.is_some() {
// if let Some(ref inner) = stmt_block(&inner_block.stmts[0]) {
// inner_block = inner;
// trailing_expr = if inner_block.stmts.is_empty() {
// None
// } else {
// stmt_expr(&inner_block.stmts[inner_block.stmts.len() - 1])
// };
// } else if !force_block {
// had_braces = false;
// }
// }
// let try_single_line = is_simple_block(inner_block, context.codemap) &&
// inner_block.rules == ast::BlockCheckMode::Default;
// if try_single_line && !force_block {
// let must_preserve_braces =
// trailing_expr.is_none() ||
// !classify::expr_requires_semi_to_be_stmt(left_most_sub_expr(trailing_expr.unwrap()));
// if !(must_preserve_braces && had_braces) &&
// (must_preserve_braces || !prefix.contains('\n')) {
// // If we got here, then we can try to format without braces.
// let inner_expr = &inner_block.stmts[0];
// let mut rewrite = inner_expr.rewrite(context, budget, offset + extra_offset);
// if must_preserve_braces {
// // If we are here, then failure to rewrite is unacceptable.
// if rewrite.is_none() {
// return None;
// }
// } else {
// // Checks if rewrite succeeded and fits on a single line.
// rewrite = and_one_line(rewrite);
// }
// if let Some(rewrite) = rewrite {
// return Some(format!("{} {}", prefix, rewrite));
// }
// }
// }
// // If we fell through the above block, then we need braces, but we might
// // still prefer a one-liner (we might also have fallen through because of
// // lack of space).
// if try_single_line && !prefix.contains('\n') {
// let inner_expr = &inner_block.stmts[0];
// // 4 = braces and spaces.
// let mut rewrite = inner_expr.rewrite(context,
// try_opt!(budget.checked_sub(4)),
// offset + extra_offset);
// // Checks if rewrite succeeded and fits on a single line.
// rewrite = and_one_line(rewrite);
// if let Some(rewrite) = rewrite {
// return Some(format!("{} {{ {} }}", prefix, rewrite));
// }
// }
// // We couldn't format the closure body as a single line expression; fall
// // back to block formatting.
// let mut context = context.clone();
// context.block_indent.alignment = 0;
// let body_rewrite = try_opt!(inner_block.rewrite(&context, budget, Indent::empty()));
// Some(format!("{} {}", prefix, body_rewrite))
}
fn and_one_line(x: Option<String>) -> Option<String> {
@ -526,13 +609,12 @@ fn and_one_line(x: Option<String>) -> Option<String> {
}
fn nop_block_collapse(block_str: Option<String>, budget: usize) -> Option<String> {
block_str.map(|block_str| {
if block_str.starts_with('{') && budget >= 2 &&
(block_str[1..].find(|c: char| !c.is_whitespace()).unwrap() == block_str.len() - 2) {
"{}".to_owned()
} else {
block_str.to_owned()
}
block_str.map(|block_str| if block_str.starts_with('{') && budget >= 2 &&
(block_str[1..].find(|c: char| !c.is_whitespace()).unwrap() ==
block_str.len() - 2) {
"{}".to_owned()
} else {
block_str.to_owned()
})
}
@ -1616,23 +1698,21 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext,
let items = itemize_list(context.codemap,
field_iter,
"}",
|item| {
match *item {
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 pos = snippet.find_uncommented("..").unwrap();
last_field_hi + BytePos(pos as u32)
}
}
},
|item| {
match *item {
StructLitField::Regular(field) => field.span.hi,
StructLitField::Base(expr) => expr.span.hi,
|item| match *item {
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 pos = snippet.find_uncommented("..").unwrap();
last_field_hi + BytePos(pos as u32)
}
},
|item| match *item {
StructLitField::Regular(field) => field.span.hi,
StructLitField::Base(expr) => expr.span.hi,
},
|item| {
match *item {
StructLitField::Regular(field) => {

View File

@ -364,13 +364,11 @@ impl<'a> FmtVisitor<'a> {
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| 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,
@ -1629,23 +1627,17 @@ fn rewrite_args(context: &RewriteContext,
.map(ArgumentKind::Regular)
.chain(variadic_arg),
")",
|arg| {
match *arg {
ArgumentKind::Regular(arg) => span_lo_for_arg(arg),
ArgumentKind::Variadic(start) => start,
}
|arg| match *arg {
ArgumentKind::Regular(arg) => span_lo_for_arg(arg),
ArgumentKind::Variadic(start) => start,
},
|arg| {
match *arg {
ArgumentKind::Regular(arg) => arg.ty.span.hi,
ArgumentKind::Variadic(start) => start + BytePos(3),
}
|arg| match *arg {
ArgumentKind::Regular(arg) => arg.ty.span.hi,
ArgumentKind::Variadic(start) => start + BytePos(3),
},
|arg| {
match *arg {
ArgumentKind::Regular(..) => None,
ArgumentKind::Variadic(..) => Some("...".to_owned()),
}
|arg| match *arg {
ArgumentKind::Regular(..) => None,
ArgumentKind::Variadic(..) => Some("...".to_owned()),
},
comment_span_start,
span.hi);

View File

@ -393,9 +393,9 @@ fn parse_input(input: Input,
parse_session: &ParseSess)
-> Result<ast::Crate, Option<DiagnosticBuilder>> {
let result = match input {
Input::File(file) => parse::parse_crate_from_file(&file, Vec::new(), parse_session),
Input::File(file) => parse::parse_crate_from_file(&file, parse_session),
Input::Text(text) => {
parse::parse_crate_from_source_str("stdin".to_owned(), text, Vec::new(), parse_session)
parse::parse_crate_from_source_str("stdin".to_owned(), text, parse_session)
}
};

View File

@ -41,6 +41,13 @@ enum MacroStyle {
Braces,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MacroPosition {
Item,
Statement,
Expression,
}
impl MacroStyle {
fn opener(&self) -> &'static str {
match *self {
@ -55,7 +62,8 @@ pub fn rewrite_macro(mac: &ast::Mac,
extra_ident: Option<ast::Ident>,
context: &RewriteContext,
width: usize,
offset: Indent)
offset: Indent,
position: MacroPosition)
-> Option<String> {
if context.config.use_try_shorthand {
if let Some(expr) = convert_try_mac(mac, context) {
@ -77,13 +85,16 @@ pub fn rewrite_macro(mac: &ast::Mac,
if mac.node.tts.is_empty() && !contains_comment(&context.snippet(mac.span)) {
return match style {
MacroStyle::Parens if position == MacroPosition::Item => {
Some(format!("{}();", macro_name))
}
MacroStyle::Parens => Some(format!("{}()", macro_name)),
MacroStyle::Brackets => Some(format!("{}[]", macro_name)),
MacroStyle::Braces => Some(format!("{}{{}}", macro_name)),
};
}
let mut parser = tts_to_parser(context.parse_session, mac.node.tts.clone(), Vec::new());
let mut parser = tts_to_parser(context.parse_session, mac.node.tts.clone());
let mut expr_vec = Vec::new();
if MacroStyle::Braces != style {
@ -128,6 +139,10 @@ pub fn rewrite_macro(mac: &ast::Mac,
MacroStyle::Parens => {
// Format macro invocation as function call.
rewrite_call(context, &macro_name, &expr_vec, mac.span, width, offset)
.map(|rw| match position {
MacroPosition::Item => format!("{};", rw),
_ => rw,
})
}
MacroStyle::Brackets => {
// Format macro invocation as array literal.
@ -155,10 +170,10 @@ pub fn rewrite_macro(mac: &ast::Mac,
/// failed).
pub fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext) -> Option<ast::Expr> {
if &format!("{}", mac.node.path)[..] == "try" {
let mut parser = tts_to_parser(context.parse_session, mac.node.tts.clone(), Vec::new());
let mut parser = tts_to_parser(context.parse_session, mac.node.tts.clone());
Some(ast::Expr {
id: 0, // dummy value
id: ast::NodeId::new(0), // dummy value
node: ast::ExprKind::Try(try_opt!(parser.parse_expr().ok())),
span: mac.span, // incorrect span, but shouldn't matter too much
attrs: ThinVec::new(),

View File

@ -103,7 +103,7 @@ impl<'a> FmtVisitor<'a> {
fn replace_chars(string: &str) -> String {
string.chars()
.map(|ch| { if ch.is_whitespace() { ch } else { 'X' } })
.map(|ch| if ch.is_whitespace() { ch } else { 'X' })
.collect()
}

View File

@ -78,7 +78,7 @@ impl Rewrite for Pat {
offset)
}
PatKind::Lit(ref expr) => expr.rewrite(context, width, offset),
PatKind::Vec(ref prefix, ref slice_pat, ref suffix) => {
PatKind::Slice(ref prefix, ref slice_pat, ref suffix) => {
// Rewrite all the sub-patterns.
let prefix = prefix.iter().map(|p| p.rewrite(context, width, offset));
let slice_pat = slice_pat.as_ref()

View File

@ -279,32 +279,27 @@ fn format_function_type<'a, I>(inputs: I,
// 1 for (
let offset = offset + 1;
let list_lo = context.codemap.span_after(span, "(");
let items = itemize_list(context.codemap,
// FIXME Would be nice to avoid this allocation,
// but I couldn't get the types to work out.
inputs.map(|i| ArgumentKind::Regular(Box::new(i)))
.chain(variadic_arg),
")",
|arg| {
match *arg {
ArgumentKind::Regular(ref ty) => ty.span().lo,
ArgumentKind::Variadic(start) => start,
}
},
|arg| {
match *arg {
ArgumentKind::Regular(ref ty) => ty.span().hi,
ArgumentKind::Variadic(start) => start + BytePos(3),
}
},
|arg| {
match *arg {
ArgumentKind::Regular(ref ty) => ty.rewrite(context, budget, offset),
ArgumentKind::Variadic(_) => Some("...".to_owned()),
}
},
list_lo,
span.hi);
let items =
itemize_list(context.codemap,
// FIXME Would be nice to avoid this allocation,
// but I couldn't get the types to work out.
inputs.map(|i| ArgumentKind::Regular(Box::new(i)))
.chain(variadic_arg),
")",
|arg| match *arg {
ArgumentKind::Regular(ref ty) => ty.span().lo,
ArgumentKind::Variadic(start) => start,
},
|arg| match *arg {
ArgumentKind::Regular(ref ty) => ty.span().hi,
ArgumentKind::Variadic(start) => start + BytePos(3),
},
|arg| match *arg {
ArgumentKind::Regular(ref ty) => ty.rewrite(context, budget, offset),
ArgumentKind::Variadic(_) => Some("...".to_owned()),
},
list_lo,
span.hi);
let list_str = try_opt!(format_fn_args(items, budget, offset, context.config));
@ -606,7 +601,7 @@ impl Rewrite for ast::Ty {
format!("({})", ty_str)
})
}
ast::TyKind::Vec(ref ty) => {
ast::TyKind::Slice(ref ty) => {
let budget = if context.config.spaces_within_square_brackets {
try_opt!(width.checked_sub(4))
} else {
@ -630,7 +625,7 @@ impl Rewrite for ast::Ty {
ast::TyKind::Path(ref q_self, ref path) => {
rewrite_path(context, false, q_self.as_ref(), path, width, offset)
}
ast::TyKind::FixedLengthVec(ref ty, ref repeats) => {
ast::TyKind::Array(ref ty, ref repeats) => {
let use_spaces = context.config.spaces_within_square_brackets;
let lbr = if use_spaces { "[ " } else { "[" };
let rbr = if use_spaces { " ]" } else { "]" };

View File

@ -127,11 +127,9 @@ pub fn contains_skip(attrs: &[Attribute]) -> bool {
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
typaram.bounds
.last()
.map_or(typaram.span, |bound| {
match *bound {
ast::RegionTyParamBound(ref lt) => lt.span,
ast::TraitTyParamBound(ref prt, _) => prt.span,
}
.map_or(typaram.span, |bound| match *bound {
ast::RegionTyParamBound(ref lt) => lt.span,
ast::TraitTyParamBound(ref prt, _) => prt.span,
})
.hi
}
@ -163,19 +161,6 @@ pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
}
}
#[inline]
pub fn stmt_block(stmt: &ast::Stmt) -> Option<&ast::Block> {
match stmt.node {
ast::StmtKind::Expr(ref expr) => {
match expr.node {
ast::ExprKind::Block(ref inner) => Some(inner),
_ => None,
}
}
_ => None,
}
}
#[inline]
pub fn stmt_expr(stmt: &ast::Stmt) -> Option<&ast::Expr> {
match stmt.node {
@ -334,13 +319,11 @@ pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<
#[test]
fn bin_search_test() {
let closure = |i| {
match i {
4 => Ok(()),
j if j > 4 => Err(Ordering::Less),
j if j < 4 => Err(Ordering::Greater),
_ => unreachable!(),
}
let closure = |i| match i {
4 => Ok(()),
j if j > 4 => Err(Ordering::Less),
j if j < 4 => Err(Ordering::Greater),
_ => unreachable!(),
};
assert_eq!(Some(()), binary_search(1, 10, &closure));

View File

@ -20,7 +20,7 @@ use codemap::{LineRangeUtils, SpanUtils};
use config::Config;
use rewrite::{Rewrite, RewriteContext};
use comment::rewrite_comment;
use macros::rewrite_macro;
use macros::{rewrite_macro, MacroPosition};
use items::{rewrite_static, rewrite_associated_type, rewrite_type_alias, format_impl, format_trait};
fn is_use_item(item: &ast::Item) -> bool {
@ -66,7 +66,7 @@ impl<'a> FmtVisitor<'a> {
}
ast::StmtKind::Mac(ref mac) => {
let (ref mac, _macro_style, _) = **mac;
self.visit_mac(mac, None);
self.visit_mac(mac, None, MacroPosition::Statement);
}
}
}
@ -124,13 +124,14 @@ impl<'a> FmtVisitor<'a> {
fn visit_fn(&mut self,
fk: visit::FnKind,
fd: &ast::FnDecl,
b: &ast::Block,
s: Span,
_: ast::NodeId,
defaultness: ast::Defaultness) {
let indent = self.block_indent;
let block;
let rewrite = match fk {
visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis) => {
visit::FnKind::ItemFn(ident, generics, unsafety, constness, abi, vis, b) => {
block = b;
self.rewrite_fn(indent,
ident,
fd,
@ -141,9 +142,10 @@ impl<'a> FmtVisitor<'a> {
abi,
vis,
codemap::mk_sp(s.lo, b.span.lo),
b)
&b)
}
visit::FnKind::Method(ident, sig, vis) => {
visit::FnKind::Method(ident, sig, vis, b) => {
block = b;
self.rewrite_fn(indent,
ident,
fd,
@ -154,9 +156,9 @@ impl<'a> FmtVisitor<'a> {
sig.abi,
vis.unwrap_or(&ast::Visibility::Inherited),
codemap::mk_sp(s.lo, b.span.lo),
b)
&b)
}
visit::FnKind::Closure => None,
visit::FnKind::Closure(_) => unreachable!(),
};
if let Some(fn_str) = rewrite {
@ -164,16 +166,16 @@ impl<'a> FmtVisitor<'a> {
self.buffer.push_str(&fn_str);
if let Some(c) = fn_str.chars().last() {
if c == '}' {
self.last_pos = source!(self, b.span).hi;
self.last_pos = source!(self, block.span).hi;
return;
}
}
} else {
self.format_missing(source!(self, b.span).lo);
self.format_missing(source!(self, block.span).lo);
}
self.last_pos = source!(self, b.span).lo;
self.visit_block(b)
self.last_pos = source!(self, block.span).lo;
self.visit_block(block)
}
pub fn visit_item(&mut self, item: &ast::Item) {
@ -261,11 +263,9 @@ impl<'a> FmtVisitor<'a> {
item.span,
indent,
None)
.map(|s| {
match *def {
ast::VariantData::Tuple(..) => s + ";",
_ => s,
}
.map(|s| match *def {
ast::VariantData::Tuple(..) => s + ";",
_ => s,
})
};
self.push_rewrite(item.span, rewrite);
@ -280,7 +280,7 @@ impl<'a> FmtVisitor<'a> {
self.format_mod(module, &item.vis, item.span, item.ident);
}
ast::ItemKind::Mac(ref mac) => {
self.visit_mac(mac, Some(item.ident));
self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
}
ast::ItemKind::ForeignMod(ref foreign_mod) => {
self.format_missing_with_indent(source!(self, item.span).lo);
@ -315,9 +315,9 @@ impl<'a> FmtVisitor<'a> {
unsafety,
constness,
abi,
&item.vis),
&item.vis,
body),
decl,
body,
item.span,
item.id,
ast::Defaultness::Final)
@ -361,9 +361,8 @@ impl<'a> FmtVisitor<'a> {
self.push_rewrite(ti.span, rewrite);
}
ast::TraitItemKind::Method(ref sig, Some(ref body)) => {
self.visit_fn(visit::FnKind::Method(ti.ident, sig, None),
self.visit_fn(visit::FnKind::Method(ti.ident, sig, None, body),
&sig.decl,
body,
ti.span,
ti.id,
ast::Defaultness::Final);
@ -390,9 +389,8 @@ impl<'a> FmtVisitor<'a> {
match ii.node {
ast::ImplItemKind::Method(ref sig, ref body) => {
self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis)),
self.visit_fn(visit::FnKind::Method(ii.ident, sig, Some(&ii.vis), body),
&sig.decl,
body,
ii.span,
ii.id,
ii.defaultness);
@ -416,15 +414,20 @@ impl<'a> FmtVisitor<'a> {
self.push_rewrite(ii.span, rewrite);
}
ast::ImplItemKind::Macro(ref mac) => {
self.visit_mac(mac, Some(ii.ident));
self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
}
}
}
fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>) {
fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPosition) {
// 1 = ;
let width = self.config.max_width - self.block_indent.width() - 1;
let rewrite = rewrite_macro(mac, ident, &self.get_context(), width, self.block_indent);
let rewrite = rewrite_macro(mac,
ident,
&self.get_context(),
width,
self.block_indent,
pos);
self.push_rewrite(mac.span, rewrite);
}
@ -513,7 +516,9 @@ impl<'a> FmtVisitor<'a> {
fn format_mod(&mut self, m: &ast::Mod, vis: &ast::Visibility, s: Span, ident: ast::Ident) {
// Decide whether this is an inline mod or an external mod.
let local_file_name = self.codemap.span_to_filename(s);
let is_internal = local_file_name == self.codemap.span_to_filename(source!(self, m.inner));
let inner_span = source!(self, m.inner);
let is_internal = !(inner_span.lo.0 == 0 && inner_span.hi.0 == 0) &&
local_file_name == self.codemap.span_to_filename(inner_span);
self.buffer.push_str(&*utils::format_visibility(vis));
self.buffer.push_str("mod ");

View File

@ -46,9 +46,7 @@ fn main() {
});
fffffffffffffffffffffffffffffffffff(a, {
SCRIPT_TASK_ROOT.with(|root| {
*root.borrow_mut() = Some(&script_task);
});
SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task); });
});
let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = xxxxxxx.map(|x| x + 5)

View File

@ -44,9 +44,7 @@ fn main() {
});
fffffffffffffffffffffffffffffffffff(a, {
SCRIPT_TASK_ROOT.with(|root| {
*root.borrow_mut() = Some(&script_task);
});
SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task); });
});
let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = xxxxxxx.map(|x| x + 5)

View File

@ -3,14 +3,13 @@
fn main() {
let square = (|i: i32| i * i);
let commented = |// first
a, // argument
// second
b: WithType, // argument
// ignored
_| {
(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)
};
let commented =
|// first
a, // argument
// second
b: WithType, // argument
// ignored
_| (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);
let block_body = move |xxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
ref yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy| {

View File

@ -73,27 +73,21 @@ fn main() {
arg(a, b, c, d, e)
}
loong_func().quux(move || {
if true {
1
} else {
2
}
loong_func().quux(move || if true {
1
} else {
2
});
fffffffffffffffffffffffffffffffffff(a, {
SCRIPT_TASK_ROOT.with(|root| {
*root.borrow_mut() = Some(&script_task);
});
SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task); });
});
a.b
.c
.d();
x().y(|| {
match cond() {
true => (),
false => (),
}
x().y(|| match cond() {
true => (),
false => (),
});
}

View File

@ -1,4 +1,3 @@
fn issue_1055() {
let foo = (|| {
})();
let foo = (|| {})();
}