Skip to content

Commit

Permalink
Format trailing where clauses in rustfmt
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Aug 27, 2023
1 parent df2471b commit 2c4abbb
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 19 deletions.
76 changes: 57 additions & 19 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,9 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
where_predicates_split,
} = *ty_alias_kind;
let ty_opt = ty.as_ref();
let rhs_hi = ty
.as_ref()
.map_or(where_clauses.0.1.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),
Expand All @@ -1679,17 +1682,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(..) => Some(format!("default {result}")),
Expand All @@ -1703,6 +1712,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,
) -> Option<String> {
let mut result = String::with_capacity(128);
Expand All @@ -1719,9 +1730,6 @@ fn rewrite_ty<R: Rewrite>(
.where_clause
.predicates
.split_at(where_predicates_split);
if !after_where_predicates.is_empty() {
return None;
}
result.push_str(&format!("{}type ", format_visibility(context, vis)));
let ident_str = rewrite_ident(context, ident);

Expand Down Expand Up @@ -1750,7 +1758,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.0.1,
Expand All @@ -1762,14 +1770,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(' ');
}
Expand All @@ -1783,7 +1797,7 @@ fn rewrite_ty<R: Rewrite>(
Some(comment_span)
if contains_comment(context.snippet_provider.span_to_snippet(comment_span)?) =>
{
let comment_shape = if has_where {
let comment_shape = if !before_where_predicates.is_empty() {
Shape::indented(indent, context.config)
} else {
Shape::indented(indent, context.config)
Expand All @@ -1802,12 +1816,36 @@ fn rewrite_ty<R: Rewrite>(
_ => format!("{result}="),
};

// 1 = `;`
let shape = Shape::indented(indent, context.config).sub_width(1)?;
rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";")
// 1 = `;` unless there's a trailing where clause
let shape = if after_where_predicates.is_empty() {
Shape::indented(indent, context.config).sub_width(1)?
} else {
Shape::indented(indent, context.config)
};
rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape)?
} else {
Some(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.1.1,
context.config.brace_style(),
Shape::indented(indent, context.config),
false,
";",
None,
rhs_hi,
option,
)?;
result.push_str(&after_where_clause_str);
}

result += ";";
Some(result)
}

fn type_annotation_spacing(config: &Config) -> (&str, &str) {
Expand Down
20 changes: 20 additions & 0 deletions tests/source/type-alias-where-clauses.rs
Original file line number Diff line number Diff line change
@@ -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;
20 changes: 20 additions & 0 deletions tests/target/type-alias-where-clauses.rs
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 2c4abbb

Please sign in to comment.