about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.rs3
-rw-r--r--src/pairs.rs41
2 files changed, 41 insertions, 3 deletions
diff --git a/src/expr.rs b/src/expr.rs
index c15e680333b..25226991fbc 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1842,11 +1842,14 @@ fn rewrite_let(
 ) -> Option<String> {
     let mut result = "let ".to_owned();
 
+    // TODO(ytmimi) comments could appear between `let` and the `pat`
+
     // 4 = "let ".len()
     let pat_shape = shape.offset_left(4)?;
     let pat_str = pat.rewrite(context, pat_shape)?;
     result.push_str(&pat_str);
 
+    // TODO(ytmimi) comments could appear between `pat` and `=`
     result.push_str(" =");
 
     let comments_lo = context
diff --git a/src/pairs.rs b/src/pairs.rs
index 96f023b3b0e..9dac20d3699 100644
--- a/src/pairs.rs
+++ b/src/pairs.rs
@@ -42,9 +42,13 @@ pub(crate) fn rewrite_all_pairs(
     context: &RewriteContext<'_>,
 ) -> Option<String> {
     expr.flatten(context, shape).and_then(|list| {
-        // First we try formatting on one line.
-        rewrite_pairs_one_line(&list, shape, context)
-            .or_else(|| rewrite_pairs_multiline(&list, shape, context))
+        if list.let_chain_count() > 0 && !list.can_rewrite_let_chain_single_line() {
+            rewrite_pairs_multiline(&list, shape, context)
+        } else {
+            // First we try formatting on one line.
+            rewrite_pairs_one_line(&list, shape, context)
+                .or_else(|| rewrite_pairs_multiline(&list, shape, context))
+        }
     })
 }
 
@@ -255,6 +259,37 @@ struct PairList<'a, 'b, T: Rewrite> {
     separators: Vec<&'a str>,
 }
 
+fn is_ident(expr: &ast::Expr) -> bool {
+    match &expr.kind {
+        ast::ExprKind::Path(None, path) if path.segments.len() == 1 => true,
+        ast::ExprKind::Unary(_, expr)
+        | ast::ExprKind::AddrOf(_, _, expr)
+        | ast::ExprKind::Paren(expr)
+        | ast::ExprKind::Try(expr) => is_ident(expr),
+        _ => false,
+    }
+}
+
+impl<'a, 'b> PairList<'a, 'b, ast::Expr> {
+    fn let_chain_count(&self) -> usize {
+        self.list
+            .iter()
+            .filter(|(expr, _)| matches!(expr.kind, ast::ExprKind::Let(_, _, _)))
+            .count()
+    }
+
+    fn can_rewrite_let_chain_single_line(&self) -> bool {
+        if self.list.len() != 2 {
+            return false;
+        }
+
+        let fist_item_is_ident = is_ident(self.list[0].0);
+        let second_item_is_let_chain = matches!(self.list[1].0.kind, ast::ExprKind::Let(_, _, _));
+
+        fist_item_is_ident && second_item_is_let_chain
+    }
+}
+
 impl FlattenPair for ast::Expr {
     fn flatten(
         &self,