Format trailing where clauses in rustfmt

This commit is contained in:
Michael Goulet 2023-08-16 18:10:54 +00:00 committed by Caleb Cartwright
parent 14d5165960
commit df06d7eb09
3 changed files with 99 additions and 19 deletions

View File

@ -1712,6 +1712,9 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
where_clauses,
} = *ty_alias_kind;
let ty_opt = ty.as_ref();
let rhs_hi = ty
.as_ref()
.map_or(where_clauses.before.span.hi(), |ty| ty.span.hi());
let (ident, vis) = match visitor_kind {
Item(i) => (i.ident, &i.vis),
AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
@ -1726,17 +1729,23 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
match (visitor_kind, &op_ty) {
(Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => {
let op = OpaqueType { bounds: op_bounds };
rewrite_ty(rw_info, Some(bounds), Some(&op), vis)
rewrite_ty(rw_info, Some(bounds), Some(&op), rhs_hi, vis)
}
(Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => {
rewrite_ty(rw_info, Some(bounds), ty_opt, vis)
rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
}
(AssocImplItem(_), _) => {
let result = if let Some(op_bounds) = op_ty {
let op = OpaqueType { bounds: op_bounds };
rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY)
rewrite_ty(
rw_info,
Some(bounds),
Some(&op),
rhs_hi,
&DEFAULT_VISIBILITY,
)
} else {
rewrite_ty(rw_info, Some(bounds), ty_opt, vis)
rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
}?;
match defaultness {
ast::Defaultness::Default(..) => Ok(format!("default {result}")),
@ -1750,6 +1759,8 @@ fn rewrite_ty<R: Rewrite>(
rw_info: &TyAliasRewriteInfo<'_, '_>,
generic_bounds_opt: Option<&ast::GenericBounds>,
rhs: Option<&R>,
// the span of the end of the RHS (or the end of the generics, if there is no RHS)
rhs_hi: BytePos,
vis: &ast::Visibility,
) -> RewriteResult {
let mut result = String::with_capacity(128);
@ -1758,9 +1769,6 @@ fn rewrite_ty<R: Rewrite>(
.where_clause
.predicates
.split_at(where_clauses.split);
if !after_where_predicates.is_empty() {
return Err(RewriteError::Unknown);
}
result.push_str(&format!("{}type ", format_visibility(context, vis)));
let ident_str = rewrite_ident(context, ident);
@ -1796,7 +1804,7 @@ fn rewrite_ty<R: Rewrite>(
if rhs.is_none() {
option.suppress_comma();
}
let where_clause_str = rewrite_where_clause(
let before_where_clause_str = rewrite_where_clause(
context,
before_where_predicates,
where_clauses.before.span,
@ -1808,14 +1816,20 @@ fn rewrite_ty<R: Rewrite>(
generics.span.hi(),
option,
)?;
result.push_str(&where_clause_str);
result.push_str(&before_where_clause_str);
if let Some(ty) = rhs {
// If there's a where clause, add a newline before the assignment. Otherwise just add a
// space.
let has_where = !before_where_predicates.is_empty();
if has_where {
let mut result = if let Some(ty) = rhs {
// If there are any where clauses, add a newline before the assignment.
// If there is a before where clause, do not indent, but if there is
// only an after where clause, additionally indent the type.
if !before_where_predicates.is_empty() {
result.push_str(&indent.to_string_with_newline(context.config));
} else if !after_where_predicates.is_empty() {
result.push_str(
&indent
.block_indent(context.config)
.to_string_with_newline(context.config),
);
} else {
result.push(' ');
}
@ -1834,7 +1848,7 @@ fn rewrite_ty<R: Rewrite>(
.unknown_error()?,
) =>
{
let comment_shape = if has_where {
let comment_shape = if !before_where_predicates.is_empty() {
Shape::indented(indent, context.config)
} else {
let shape = Shape::indented(indent, context.config);
@ -1855,13 +1869,39 @@ fn rewrite_ty<R: Rewrite>(
_ => format!("{result}="),
};
// 1 = `;`
// 1 = `;` unless there's a trailing where clause
let shape = Shape::indented(indent, context.config);
let shape = shape.sub_width(1).max_width_error(shape.width, span)?;
rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";")
let shape = if after_where_predicates.is_empty() {
Shape::indented(indent, context.config)
.sub_width(1)
.max_width_error(shape.width, span)?
} else {
shape
};
rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape)?
} else {
Ok(format!("{result};"))
result
};
if !after_where_predicates.is_empty() {
let option = WhereClauseOption::new(true, WhereClauseSpace::Newline);
let after_where_clause_str = rewrite_where_clause(
context,
after_where_predicates,
where_clauses.after.span,
context.config.brace_style(),
Shape::indented(indent, context.config),
false,
";",
None,
rhs_hi,
option,
)?;
result.push_str(&after_where_clause_str);
}
result += ";";
Ok(result)
}
fn type_annotation_spacing(config: &Config) -> (&str, &str) {

View File

@ -0,0 +1,20 @@
type Foo
where
A: B,
C: D,
= E;
type Foo
where
A: B,
C: D,
= E
where
F: G,
H: I;
type Foo
= E
where
F: G,
H: I;

View File

@ -0,0 +1,20 @@
type Foo
where
A: B,
C: D,
= E;
type Foo
where
A: B,
C: D,
= E
where
F: G,
H: I;
type Foo
= E
where
F: G,
H: I;