Skip to content

Commit

Permalink
Add support for ExprKind::Let
Browse files Browse the repository at this point in the history
  • Loading branch information
camsteffen committed Jan 30, 2022
1 parent 8b0b213 commit b276cb7
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 7 deletions.
26 changes: 25 additions & 1 deletion src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub(crate) fn format_expr(
ast::ExprKind::Tup(ref items) => {
rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1)
}
ast::ExprKind::Let(..) => None,
ast::ExprKind::Let(ref pat, ref expr, _span) => rewrite_let(context, shape, pat, expr),
ast::ExprKind::If(..)
| ast::ExprKind::ForLoop(..)
| ast::ExprKind::Loop(..)
Expand Down Expand Up @@ -1779,6 +1779,30 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>(
Some(format!("({})", list_str))
}

fn rewrite_let(
context: &RewriteContext<'_>,
shape: Shape,
pat: &ast::Pat,
expr: &ast::Expr,
) -> Option<String> {
let mut result = "let ".to_owned();

// 4 = "let ".len()
let pat_shape = shape.offset_left(4)?;
let pat_str = pat.rewrite(context, pat_shape)?;
result.push_str(&pat_str);

result.push_str(" =");

rewrite_assign_rhs(
context,
result,
expr,
&RhsAssignKind::Expr(&expr.kind, expr.span),
shape,
)
}

pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>(
context: &'a RewriteContext<'_>,
items: impl Iterator<Item = &'a T>,
Expand Down
22 changes: 17 additions & 5 deletions src/pairs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ pub(crate) fn rewrite_all_pairs(
shape: Shape,
context: &RewriteContext<'_>,
) -> Option<String> {
expr.flatten(context, shape).and_then(|list| {
let list = expr.flatten(context, shape)?;
if !list.force_multi_line {
// First we try formatting on one line.
rewrite_pairs_one_line(&list, shape, context)
.or_else(|| rewrite_pairs_multiline(&list, shape, context))
})
if let Some(out) = rewrite_pairs_one_line(&list, shape, context) {
return Some(out);
}
}
rewrite_pairs_multiline(&list, shape, context)
}

// This may return a multi-line result since we allow the last expression to go
Expand Down Expand Up @@ -246,6 +249,7 @@ trait FlattenPair: Rewrite + Sized {
struct PairList<'a, 'b, T: Rewrite> {
list: Vec<(&'b T, Option<String>)>,
separators: Vec<&'a str>,
force_multi_line: bool,
}

impl FlattenPair for ast::Expr {
Expand Down Expand Up @@ -283,6 +287,7 @@ impl FlattenPair for ast::Expr {
let mut stack = vec![];
let mut list = vec![];
let mut separators = vec![];
let mut force_multi_line = false;
let mut node = self;
loop {
match node.kind {
Expand All @@ -293,6 +298,9 @@ impl FlattenPair for ast::Expr {
_ => {
let op_len = separators.last().map_or(0, |s: &&str| s.len());
let rw = default_rewrite(node, op_len, list.is_empty());
// a `let` expression forces multi-line, unless it is the first expression
force_multi_line |=
!list.is_empty() && matches!(node.kind, ast::ExprKind::Let(..));
list.push((node, rw));
if let Some(pop) = stack.pop() {
match pop.kind {
Expand All @@ -310,7 +318,11 @@ impl FlattenPair for ast::Expr {
}

assert_eq!(list.len() - 1, separators.len());
Some(PairList { list, separators })
Some(PairList {
list,
separators,
force_multi_line,
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/cargo-fmt/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Integration tests for cargo-fmt.

use std::env;
use std::process::Command;
use std::path::Path;
use std::process::Command;

/// Run the cargo-fmt executable and return its output.
fn cargo_fmt(args: &[&str]) -> (String, String) {
Expand Down
11 changes: 11 additions & 0 deletions tests/source/let_chains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main() {
// can be one line
if let x = x && x {}
// must wrap
if xxx && let x = x {}

if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa && aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa {}

if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa || aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa {}

}
1 change: 1 addition & 0 deletions tests/source/match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ fn guards() {
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
if fooooooooooooooooooooo &&
(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {}
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if let Some(foooooooooooooo) = hiiiiiiiiiiiiiii => {}
}
}

Expand Down
23 changes: 23 additions & 0 deletions tests/target/let_chains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fn main() {
// can be one line
if let x = x && x {}
// must wrap
if xxx
&& let x = x
{}

if aaaaaaaaaaaaaaaaaaaaa
&& aaaaaaaaaaaaaaa
&& aaaaaaaaa
&& let Some(x) = xxxxxxxxxxxx
&& aaaaaaa
&& let None = aaaaaaaaaa
{}

if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa
|| aaaaaaaaa
&& let Some(x) = xxxxxxxxxxxx
&& aaaaaaa
&& let None = aaaaaaaaaa
{}
}
2 changes: 2 additions & 0 deletions tests/target/match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ fn guards() {
if fooooooooooooooooooooo
&& (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|| cccccccccccccccccccccccccccccccccccccccc) => {}
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
if let Some(foooooooooooooo) = hiiiiiiiiiiiiiii => {}
}
}

Expand Down

0 comments on commit b276cb7

Please sign in to comment.