mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Format try shorthand
This commit is contained in:
parent
fc2549b576
commit
ee7b5805fc
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
/// Formatting of chained expressions, i.e. expressions which are chained by
|
||||
/// dots: struct and enum field access and method calls.
|
||||
/// dots: struct and enum field access, method calls, and try shorthand (?).
|
||||
///
|
||||
/// Instead of walking these subexpressions one-by-one, as is our usual strategy
|
||||
/// for expression formatting, we collect maximal sequences of these expressions
|
||||
@ -81,7 +81,6 @@
|
||||
/// true, then we allow the last method call to spill over multiple lines without
|
||||
/// forcing the rest of the chain to be split.
|
||||
|
||||
|
||||
use Indent;
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use utils::{wrap_str, first_line_width};
|
||||
@ -109,8 +108,16 @@ pub fn rewrite_chain(expr: &ast::Expr,
|
||||
// put the first non-parent item on the same line as the parent.
|
||||
let (indent, extend) = if !parent_rewrite.contains('\n') && is_continuable(parent) ||
|
||||
parent_rewrite.len() <= context.config.tab_spaces {
|
||||
// Try and put at least the first two items on the same line.
|
||||
(chain_indent(context, offset + Indent::new(0, parent_rewrite.len())), true)
|
||||
// <<<<<<< HEAD
|
||||
// // Try and put at least the first two items on the same line.
|
||||
// (chain_indent(context, offset + Indent::new(0, parent_rewrite.len())), true)
|
||||
// =======
|
||||
let indent = if let ast::ExprKind::Try(..) = subexpr_list.last().unwrap().node {
|
||||
parent_block_indent.block_indent(context.config)
|
||||
} else {
|
||||
offset + Indent::new(0, parent_rewrite.len())
|
||||
};
|
||||
(indent, true)
|
||||
} else if is_block_expr(parent, &parent_rewrite) {
|
||||
// The parent is a block, so align the rest of the chain with the closing
|
||||
// brace.
|
||||
@ -184,12 +191,27 @@ pub fn rewrite_chain(expr: &ast::Expr,
|
||||
wrap_str(format!("{}{}{}",
|
||||
parent_rewrite,
|
||||
first_connector,
|
||||
rewrites.join(&connector)),
|
||||
join_rewrites(&rewrites, &subexpr_list, &connector)),
|
||||
context.config.max_width,
|
||||
width,
|
||||
offset)
|
||||
}
|
||||
|
||||
fn join_rewrites(rewrites: &[String], subexps: &[&ast::Expr], connector: &str) -> String {
|
||||
let mut rewrite_iter = rewrites.iter();
|
||||
let mut result = rewrite_iter.next().unwrap().clone();
|
||||
|
||||
for (rewrite, expr) in rewrite_iter.zip(subexps.iter()) {
|
||||
match expr.node {
|
||||
ast::ExprKind::Try(_) => (),
|
||||
_ => result.push_str(connector),
|
||||
};
|
||||
result.push_str(&rewrite[..]);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// States whether an expression's last line exclusively consists of closing
|
||||
// parens, braces, and brackets in its idiomatic formatting.
|
||||
fn is_block_expr(expr: &ast::Expr, repr: &str) -> bool {
|
||||
@ -293,6 +315,16 @@ fn rewrite_method_call_with_overflow(expr_kind: &ast::ExprKind,
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_expr_chain(expr: &ast::Expr) -> Option<&ast::Expr> {
|
||||
match expr.node {
|
||||
ast::ExprKind::MethodCall(_, _, ref expressions) => Some(&expressions[0]),
|
||||
ast::ExprKind::TupField(ref subexpr, _) |
|
||||
ast::ExprKind::Field(ref subexpr, _) |
|
||||
ast::ExprKind::Try(ref subexpr) => Some(subexpr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite the last element in the chain `expr`. E.g., given `a.b.c` we rewrite
|
||||
// `.c`.
|
||||
fn rewrite_chain_subexpr(expr: &ast::Expr,
|
||||
@ -328,6 +360,13 @@ fn rewrite_chain_subexpr(expr: &ast::Expr,
|
||||
None
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Try(_) => {
|
||||
if width >= 1 {
|
||||
Some("?".into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
29
src/expr.rs
29
src/expr.rs
@ -148,6 +148,7 @@ impl Rewrite for ast::Expr {
|
||||
ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
|
||||
rewrite_closure(capture, fn_decl, body, self.span, context, width, offset)
|
||||
}
|
||||
// ast::ExprKind::Try(..) |
|
||||
ast::ExprKind::Field(..) |
|
||||
ast::ExprKind::TupField(..) |
|
||||
ast::ExprKind::MethodCall(..) => rewrite_chain(self, context, width, offset),
|
||||
@ -199,21 +200,20 @@ impl Rewrite for ast::Expr {
|
||||
rewrite_unary_prefix(context, delim, &**rhs, width, offset)
|
||||
}
|
||||
(Some(ref lhs), None) => {
|
||||
Some(format!("{}{}",
|
||||
try_opt!(lhs.rewrite(context,
|
||||
try_opt!(width.checked_sub(delim.len())),
|
||||
offset)),
|
||||
delim))
|
||||
rewrite_unary_suffix(context, delim, &**lhs, width, offset)
|
||||
}
|
||||
(None, None) => wrap_str(delim.into(), context.config.max_width, width, offset),
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Try(ref expr) => {
|
||||
rewrite_unary_suffix(context, "?", &**expr, width, offset)
|
||||
}
|
||||
// We do not format these expressions yet, but they should still
|
||||
// satisfy our width restrictions.
|
||||
ast::ExprKind::InPlace(..) |
|
||||
ast::ExprKind::InlineAsm(..) |
|
||||
// TODO(#867): Handle try shorthand
|
||||
ast::ExprKind::Try(_) => {
|
||||
// TODO(#848): Handle type ascription
|
||||
ast::ExprKind::Type(_, _) => {
|
||||
wrap_str(context.snippet(self.span),
|
||||
context.config.max_width,
|
||||
width,
|
||||
@ -1762,6 +1762,21 @@ pub fn rewrite_unary_prefix<R: Rewrite>(context: &RewriteContext,
|
||||
.map(|r| format!("{}{}", prefix, r))
|
||||
}
|
||||
|
||||
// FIXME: this is probably not correct for multi-line Rewrites. we should
|
||||
// subtract suffix.len() from the last line budget, not the first!
|
||||
pub fn rewrite_unary_suffix<R: Rewrite>(context: &RewriteContext,
|
||||
suffix: &str,
|
||||
rewrite: &R,
|
||||
width: usize,
|
||||
offset: Indent)
|
||||
-> Option<String> {
|
||||
rewrite.rewrite(context, try_opt!(width.checked_sub(suffix.len())), offset)
|
||||
.map(|mut r| {
|
||||
r.push_str(suffix);
|
||||
r
|
||||
})
|
||||
}
|
||||
|
||||
fn rewrite_unary_op(context: &RewriteContext,
|
||||
op: &ast::UnOp,
|
||||
expr: &ast::Expr,
|
||||
|
@ -112,3 +112,12 @@ fn issue587() {
|
||||
|
||||
std::mem::transmute(dl.symbol::<()>("init").unwrap())
|
||||
}
|
||||
|
||||
fn try_shorthand() {
|
||||
let x = expr?;
|
||||
let y = expr.kaas()?.test();
|
||||
let loooooooooooooooooooooooooooooooooooooooooong = does_this?.look?.good?.should_we_break?.after_the_first_question_mark?;
|
||||
let yyyy = expr?.another?.another?.another?.another?.another?.another?.another?.another?.test();
|
||||
let zzzz = expr?.another?.another?.another?.another?;
|
||||
let aaa = x ???????????? ?????????????? ???? ????? ?????????????? ????????? ?????????????? ??;
|
||||
}
|
||||
|
@ -133,3 +133,16 @@ fn issue587() {
|
||||
|
||||
std::mem::transmute(dl.symbol::<()>("init").unwrap())
|
||||
}
|
||||
|
||||
fn try_shorthand() {
|
||||
let x = expr?;
|
||||
let y = expr.kaas()?.test();
|
||||
let loooooooooooooooooooooooooooooooooooooooooong = does_this?
|
||||
.look?
|
||||
.good?
|
||||
.should_we_break?
|
||||
.after_the_first_question_mark?;
|
||||
let yyyy = expr?.another?.another?.another?.another?.another?.another?.another?.another?.test();
|
||||
let zzzz = expr?.another?.another?.another?.another?;
|
||||
let aaa = x??????????????????????????????????????????????????????????????????????????;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user