implement rustfmt formatting for for<> closure binders

This commit is contained in:
Maybe Waffle 2022-06-30 17:40:38 +04:00
parent d2923b4007
commit b504a18563
4 changed files with 40 additions and 13 deletions

View File

@ -11,6 +11,7 @@
use crate::rewrite::{Rewrite, RewriteContext}; use crate::rewrite::{Rewrite, RewriteContext};
use crate::shape::Shape; use crate::shape::Shape;
use crate::source_map::SpanUtils; use crate::source_map::SpanUtils;
use crate::types::rewrite_lifetime_param;
use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt}; 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: // This module is pretty messy because of the rules around closures and blocks:
@ -24,6 +25,7 @@
// can change whether it is treated as an expression or statement. // can change whether it is treated as an expression or statement.
pub(crate) fn rewrite_closure( pub(crate) fn rewrite_closure(
binder: &ast::ClosureBinder,
capture: ast::CaptureBy, capture: ast::CaptureBy,
is_async: &ast::Async, is_async: &ast::Async,
movability: ast::Movability, movability: ast::Movability,
@ -36,7 +38,7 @@ pub(crate) fn rewrite_closure(
debug!("rewrite_closure {:?}", body); debug!("rewrite_closure {:?}", body);
let (prefix, extra_offset) = rewrite_closure_fn_decl( 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. // 1 = space between `|...|` and body.
let body_shape = shape.offset_left(extra_offset)?; let body_shape = shape.offset_left(extra_offset)?;
@ -227,6 +229,7 @@ fn rewrite_closure_block(
// Return type is (prefix, extra_offset) // Return type is (prefix, extra_offset)
fn rewrite_closure_fn_decl( fn rewrite_closure_fn_decl(
binder: &ast::ClosureBinder,
capture: ast::CaptureBy, capture: ast::CaptureBy,
asyncness: &ast::Async, asyncness: &ast::Async,
movability: ast::Movability, movability: ast::Movability,
@ -236,6 +239,17 @@ fn rewrite_closure_fn_decl(
context: &RewriteContext<'_>, context: &RewriteContext<'_>,
shape: Shape, shape: Shape,
) -> Option<(String, usize)> { ) -> 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 { let immovable = if movability == ast::Movability::Static {
"static " "static "
} else { } else {
@ -250,7 +264,7 @@ fn rewrite_closure_fn_decl(
// 4 = "|| {".len(), which is overconservative when the closure consists of // 4 = "|| {".len(), which is overconservative when the closure consists of
// a single expression. // a single expression.
let nested_shape = shape 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)?; .sub_width(4)?;
// 1 = | // 1 = |
@ -288,7 +302,7 @@ fn rewrite_closure_fn_decl(
.tactic(tactic) .tactic(tactic)
.preserve_newline(true); .preserve_newline(true);
let list_str = write_list(&item_vec, &fmt)?; 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 !ret_str.is_empty() {
if prefix.contains('\n') { if prefix.contains('\n') {
@ -312,8 +326,15 @@ pub(crate) fn rewrite_last_closure(
expr: &ast::Expr, expr: &ast::Expr,
shape: Shape, shape: Shape,
) -> Option<String> { ) -> Option<String> {
if let ast::ExprKind::Closure(capture, ref is_async, movability, ref fn_decl, ref body, _) = if let ast::ExprKind::Closure(
expr.kind ref binder,
capture,
ref is_async,
movability,
ref fn_decl,
ref body,
_,
) = expr.kind
{ {
let body = match body.kind { let body = match body.kind {
ast::ExprKind::Block(ref block, _) ast::ExprKind::Block(ref block, _)
@ -326,7 +347,7 @@ pub(crate) fn rewrite_last_closure(
_ => body, _ => body,
}; };
let (prefix, extra_offset) = rewrite_closure_fn_decl( 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 the closure goes multi line before its body, do not overflow the closure.
if prefix.contains('\n') { if prefix.contains('\n') {

View File

@ -203,11 +203,17 @@ pub(crate) fn format_expr(
Some("yield".to_string()) Some("yield".to_string())
} }
} }
ast::ExprKind::Closure(capture, ref is_async, movability, ref fn_decl, ref body, _) => { ast::ExprKind::Closure(
closures::rewrite_closure( ref binder,
capture, is_async, movability, fn_decl, body, expr.span, context, shape, 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::Try(..)
| ast::ExprKind::Field(..) | ast::ExprKind::Field(..)
| ast::ExprKind::MethodCall(..) | ast::ExprKind::MethodCall(..)

View File

@ -1067,7 +1067,7 @@ pub(crate) fn can_be_overflowed_type(
} }
/// Returns `None` if there is no `LifetimeDef` in the given generic parameters. /// Returns `None` if there is no `LifetimeDef` in the given generic parameters.
fn rewrite_lifetime_param( pub(crate) fn rewrite_lifetime_param(
context: &RewriteContext<'_>, context: &RewriteContext<'_>,
shape: Shape, shape: Shape,
generic_params: &[ast::GenericParam], generic_params: &[ast::GenericParam],

View File

@ -479,7 +479,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
| ast::ExprKind::Binary(_, _, ref expr) | ast::ExprKind::Binary(_, _, ref expr)
| ast::ExprKind::Index(_, ref expr) | ast::ExprKind::Index(_, ref expr)
| ast::ExprKind::Unary(_, ref expr) | ast::ExprKind::Unary(_, ref expr)
| ast::ExprKind::Closure(_, _, _, _, ref expr, _) | ast::ExprKind::Closure(_, _, _, _, _, ref expr, _)
| ast::ExprKind::Try(ref expr) | ast::ExprKind::Try(ref expr)
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr), | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
// This can only be a string lit // This can only be a string lit