about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-06-30 17:40:38 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-07-12 21:00:13 +0400
commit2964d0a5332fb0fd4d2c056ee9b651215b99b027 (patch)
tree9bd7566ca2d3cead03e04616d0d3c79d395bc11b
parent45f4f6ccf7fbccd81db84f2a7ee7881884668ab2 (diff)
downloadrust-2964d0a5332fb0fd4d2c056ee9b651215b99b027.tar.gz
rust-2964d0a5332fb0fd4d2c056ee9b651215b99b027.zip
implement rustfmt formatting for `for<>` closure binders
-rw-r--r--src/closures.rs33
-rw-r--r--src/expr.rs16
-rw-r--r--src/types.rs2
-rw-r--r--src/utils.rs2
4 files changed, 40 insertions, 13 deletions
diff --git a/src/closures.rs b/src/closures.rs
index e688db1c39d..88a6bebb68c 100644
--- a/src/closures.rs
+++ b/src/closures.rs
@@ -11,6 +11,7 @@ use crate::overflow::OverflowableItem;
 use crate::rewrite::{Rewrite, RewriteContext};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
+use crate::types::rewrite_lifetime_param;
 use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt};
 
 // This module is pretty messy because of the rules around closures and blocks:
@@ -24,6 +25,7 @@ use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt};
 //     can change whether it is treated as an expression or statement.
 
 pub(crate) fn rewrite_closure(
+    binder: &ast::ClosureBinder,
     capture: ast::CaptureBy,
     is_async: &ast::Async,
     movability: ast::Movability,
@@ -36,7 +38,7 @@ pub(crate) fn rewrite_closure(
     debug!("rewrite_closure {:?}", body);
 
     let (prefix, extra_offset) = rewrite_closure_fn_decl(
-        capture, is_async, movability, fn_decl, body, span, context, shape,
+        binder, capture, is_async, movability, fn_decl, body, span, context, shape,
     )?;
     // 1 = space between `|...|` and body.
     let body_shape = shape.offset_left(extra_offset)?;
@@ -227,6 +229,7 @@ fn rewrite_closure_block(
 
 // Return type is (prefix, extra_offset)
 fn rewrite_closure_fn_decl(
+    binder: &ast::ClosureBinder,
     capture: ast::CaptureBy,
     asyncness: &ast::Async,
     movability: ast::Movability,
@@ -236,6 +239,17 @@ fn rewrite_closure_fn_decl(
     context: &RewriteContext<'_>,
     shape: Shape,
 ) -> Option<(String, usize)> {
+    let binder = match binder {
+        ast::ClosureBinder::For { generic_params, .. } if generic_params.is_empty() => {
+            "for<> ".to_owned()
+        }
+        ast::ClosureBinder::For { generic_params, .. } => {
+            let lifetime_str = rewrite_lifetime_param(context, shape, generic_params)?;
+            format!("for<{lifetime_str}> ")
+        }
+        ast::ClosureBinder::NotPresent => "".to_owned(),
+    };
+
     let immovable = if movability == ast::Movability::Static {
         "static "
     } else {
@@ -250,7 +264,7 @@ fn rewrite_closure_fn_decl(
     // 4 = "|| {".len(), which is overconservative when the closure consists of
     // a single expression.
     let nested_shape = shape
-        .shrink_left(immovable.len() + is_async.len() + mover.len())?
+        .shrink_left(binder.len() + immovable.len() + is_async.len() + mover.len())?
         .sub_width(4)?;
 
     // 1 = |
@@ -288,7 +302,7 @@ fn rewrite_closure_fn_decl(
         .tactic(tactic)
         .preserve_newline(true);
     let list_str = write_list(&item_vec, &fmt)?;
-    let mut prefix = format!("{}{}{}|{}|", immovable, is_async, mover, list_str);
+    let mut prefix = format!("{}{}{}{}|{}|", binder, immovable, is_async, mover, list_str);
 
     if !ret_str.is_empty() {
         if prefix.contains('\n') {
@@ -312,8 +326,15 @@ pub(crate) fn rewrite_last_closure(
     expr: &ast::Expr,
     shape: Shape,
 ) -> Option<String> {
-    if let ast::ExprKind::Closure(capture, ref is_async, movability, ref fn_decl, ref body, _) =
-        expr.kind
+    if let ast::ExprKind::Closure(
+        ref binder,
+        capture,
+        ref is_async,
+        movability,
+        ref fn_decl,
+        ref body,
+        _,
+    ) = expr.kind
     {
         let body = match body.kind {
             ast::ExprKind::Block(ref block, _)
@@ -326,7 +347,7 @@ pub(crate) fn rewrite_last_closure(
             _ => body,
         };
         let (prefix, extra_offset) = rewrite_closure_fn_decl(
-            capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+            binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
         )?;
         // If the closure goes multi line before its body, do not overflow the closure.
         if prefix.contains('\n') {
diff --git a/src/expr.rs b/src/expr.rs
index e4cc93026f1..a7b73ba78c5 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -203,11 +203,17 @@ pub(crate) fn format_expr(
                 Some("yield".to_string())
             }
         }
-        ast::ExprKind::Closure(capture, ref is_async, movability, ref fn_decl, ref body, _) => {
-            closures::rewrite_closure(
-                capture, is_async, movability, fn_decl, body, expr.span, context, shape,
-            )
-        }
+        ast::ExprKind::Closure(
+            ref binder,
+            capture,
+            ref is_async,
+            movability,
+            ref fn_decl,
+            ref body,
+            _,
+        ) => closures::rewrite_closure(
+            binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+        ),
         ast::ExprKind::Try(..)
         | ast::ExprKind::Field(..)
         | ast::ExprKind::MethodCall(..)
diff --git a/src/types.rs b/src/types.rs
index 64a201e45dd..2627886db10 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1067,7 +1067,7 @@ pub(crate) fn can_be_overflowed_type(
 }
 
 /// Returns `None` if there is no `LifetimeDef` in the given generic parameters.
-fn rewrite_lifetime_param(
+pub(crate) fn rewrite_lifetime_param(
     context: &RewriteContext<'_>,
     shape: Shape,
     generic_params: &[ast::GenericParam],
diff --git a/src/utils.rs b/src/utils.rs
index 4b26f4e40df..cd852855602 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -479,7 +479,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Binary(_, _, ref expr)
         | ast::ExprKind::Index(_, ref expr)
         | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Closure(_, _, _, _, ref expr, _)
+        | ast::ExprKind::Closure(_, _, _, _, _, ref expr, _)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
         // This can only be a string lit