Skip to content

Commit d6d774b

Browse files
committed
refactor: remove trailing space from format_visibility
format_visibility returned e.g. "pub(crate) " with a trailing space. Every call site either relied on this space as a separator or (in format_header) explicitly trimmed it off. Remove the trailing space from format_visibility and add it explicitly at each call site. No change in formatted output. This fixes the root cause of #6880: tuple struct field prefixes no longer carry a trailing space into rewrite_assign_rhs, so wrapping the type to the next line can no longer leave trailing whitespace.
1 parent ef22670 commit d6d774b

6 files changed

Lines changed: 63 additions & 24 deletions

File tree

src/imports.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,17 @@ impl UseTree {
344344
let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| {
345345
crate::utils::format_visibility(context, vis)
346346
});
347+
let vis_separator = if vis.is_empty() { "" } else { " " };
347348
let use_str = self
348-
.rewrite_result(context, shape.offset_left(vis.len(), self.span())?)
349+
.rewrite_result(
350+
context,
351+
shape.offset_left(vis.len() + vis_separator.len(), self.span())?,
352+
)
349353
.map(|s| {
350354
if s.is_empty() {
351355
s
352356
} else {
353-
format!("{}use {};", vis, s)
357+
format!("{vis}{vis_separator}use {s};")
354358
}
355359
})?;
356360
match self.attrs {

src/items.rs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,11 @@ impl<'a> FnSig<'a> {
353353
fn to_str(&self, context: &RewriteContext<'_>) -> String {
354354
let mut result = String::with_capacity(128);
355355
// Vis defaultness constness unsafety abi.
356-
result.push_str(&*format_visibility(context, self.visibility));
356+
let vis = format_visibility(context, self.visibility);
357+
result.push_str(&*vis);
358+
if !vis.is_empty() {
359+
result.push(' ');
360+
}
357361
result.push_str(format_defaultness(self.defaultness));
358362
result.push_str(format_constness(self.constness));
359363
self.coroutine_kind
@@ -956,7 +960,11 @@ fn format_impl_ref_and_type(
956960
} = iimpl;
957961
let mut result = String::with_capacity(128);
958962

959-
result.push_str(&format_visibility(context, &item.vis));
963+
let vis = format_visibility(context, &item.vis);
964+
result.push_str(&vis);
965+
if !vis.is_empty() {
966+
result.push(' ');
967+
}
960968

961969
if let Some(of_trait) = of_trait.as_deref() {
962970
result.push_str(format_defaultness(of_trait.defaultness));
@@ -1165,9 +1173,10 @@ pub(crate) fn format_trait(
11651173
} = *trait_;
11661174

11671175
let mut result = String::with_capacity(128);
1176+
let vis = format_visibility(context, &item.vis);
1177+
let vis_separator = if vis.is_empty() { "" } else { " " };
11681178
let header = format!(
1169-
"{}{}{}{}trait ",
1170-
format_visibility(context, &item.vis),
1179+
"{vis}{vis_separator}{}{}{}trait ",
11711180
format_constness(constness),
11721181
format_safety(safety),
11731182
format_auto(is_auto),
@@ -1376,8 +1385,9 @@ pub(crate) fn format_trait_alias(
13761385
let g_shape = shape.offset_left(6, span)?.sub_width(2, span)?;
13771386
let generics_str = rewrite_generics(context, alias, &ta.generics, g_shape)?;
13781387
let vis_str = format_visibility(context, vis);
1388+
let vis_separator = if vis_str.is_empty() { "" } else { " " };
13791389
let constness = format_constness(ta.constness);
1380-
let lhs = format!("{vis_str}{constness}trait {generics_str} =");
1390+
let lhs = format!("{vis_str}{vis_separator}{constness}trait {generics_str} =");
13811391
// 1 = ";"
13821392
let trait_alias_bounds = TraitAliasBounds {
13831393
generic_bounds: &ta.bounds,
@@ -1749,7 +1759,12 @@ fn rewrite_ty<R: Rewrite>(
17491759
) -> RewriteResult {
17501760
let mut result = String::with_capacity(128);
17511761
let TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span) = *rw_info;
1752-
result.push_str(&format!("{}type ", format_visibility(context, vis)));
1762+
let vis = format_visibility(context, vis);
1763+
if !vis.is_empty() {
1764+
result.push_str(&format!("{vis} type "));
1765+
} else {
1766+
result.push_str("type ");
1767+
}
17531768
let ident_str = rewrite_ident(context, ident);
17541769

17551770
if generics.params.is_empty() {
@@ -1887,15 +1902,18 @@ pub(crate) fn rewrite_struct_field_prefix(
18871902
field: &ast::FieldDef,
18881903
) -> RewriteResult {
18891904
let vis = format_visibility(context, &field.vis);
1905+
let vis_separator = if vis.is_empty() { "" } else { " " };
18901906
let safety = format_safety(field.safety);
18911907
let type_annotation_spacing = type_annotation_spacing(context.config);
18921908
Ok(match field.ident {
18931909
Some(name) => format!(
1894-
"{vis}{safety}{}{}:",
1910+
"{vis}{vis_separator}{safety}{}{}:",
18951911
rewrite_ident(context, name),
18961912
type_annotation_spacing.0
18971913
),
1898-
None => format!("{vis}{safety}"),
1914+
None => format!("{vis}{vis_separator}{safety}")
1915+
.trim_end()
1916+
.to_string(),
18991917
})
19001918
}
19011919

@@ -1936,6 +1954,8 @@ pub(crate) fn rewrite_struct_field(
19361954
};
19371955
let mut spacing = String::from(if field.ident.is_some() {
19381956
type_annotation_spacing.1
1957+
} else if !prefix.is_empty() {
1958+
" "
19391959
} else {
19401960
""
19411961
});
@@ -1970,6 +1990,13 @@ pub(crate) fn rewrite_struct_field(
19701990

19711991
let is_prefix_empty = prefix.is_empty();
19721992
// We must use multiline. We are going to put attributes and a field on different lines.
1993+
// Trim trailing whitespace from the prefix for tuple struct fields to avoid leaving it
1994+
// behind when the type wraps to the next line (e.g. "pub(crate) " -> "pub(crate)").
1995+
let prefix = if field.ident.is_none() {
1996+
prefix.trim_end().to_string()
1997+
} else {
1998+
prefix
1999+
};
19732000
let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, &RhsAssignKind::Ty, shape)?;
19742001
// Remove a leading white-space from `rewrite_assign_rhs()` when rewriting a tuple struct.
19752002
let field_str = if is_prefix_empty {
@@ -2116,9 +2143,10 @@ fn rewrite_static(
21162143
}
21172144

21182145
let colon = colon_spaces(context.config);
2146+
let vis = format_visibility(context, static_parts.vis);
2147+
let vis_separator = if vis.is_empty() { "" } else { " " };
21192148
let mut prefix = format!(
2120-
"{}{}{}{} {}{}{}",
2121-
format_visibility(context, static_parts.vis),
2149+
"{vis}{vis_separator}{}{}{} {}{}{}",
21222150
static_parts.defaultness.map_or("", format_defaultness),
21232151
format_safety(static_parts.safety),
21242152
static_parts.prefix,
@@ -3307,7 +3335,7 @@ fn format_header(
33073335
let mut result = String::with_capacity(128);
33083336
let shape = Shape::indented(offset, context.config);
33093337

3310-
result.push_str(format_visibility(context, vis).trim());
3338+
result.push_str(&format_visibility(context, vis));
33113339

33123340
// Check for a missing comment between the visibility and the item name.
33133341
let after_vis = vis.span.hi();
@@ -3493,11 +3521,11 @@ impl Rewrite for ast::ForeignItem {
34933521
// FIXME(#21): we're dropping potential comments in between the
34943522
// function kw here.
34953523
let vis = format_visibility(context, &self.vis);
3524+
let vis_separator = if vis.is_empty() { "" } else { " " };
34963525
let safety = format_safety(static_foreign_item.safety);
34973526
let mut_str = format_mutability(static_foreign_item.mutability);
34983527
let prefix = format!(
3499-
"{}{}static {}{}:",
3500-
vis,
3528+
"{vis}{vis_separator}{}static {}{}:",
35013529
safety,
35023530
mut_str,
35033531
rewrite_ident(context, static_foreign_item.ident)
@@ -3580,7 +3608,11 @@ pub(crate) fn rewrite_mod(
35803608
attrs_shape: Shape,
35813609
) -> RewriteResult {
35823610
let mut result = String::with_capacity(32);
3583-
result.push_str(&*format_visibility(context, &item.vis));
3611+
let vis = format_visibility(context, &item.vis);
3612+
result.push_str(&*vis);
3613+
if !vis.is_empty() {
3614+
result.push(' ');
3615+
}
35843616
result.push_str("mod ");
35853617
result.push_str(rewrite_ident(context, ident));
35863618
result.push(';');

src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,10 +1454,10 @@ fn format_lazy_static(
14541454
for (i, (vis, id, ty, expr)) in parsed_elems.iter().enumerate() {
14551455
// Rewrite as a static item.
14561456
let vis = crate::utils::format_visibility(context, vis);
1457+
let vis_separator = if vis.is_empty() { "" } else { " " };
14571458
let mut stmt = String::with_capacity(128);
14581459
stmt.push_str(&format!(
1459-
"{}static ref {}: {} =",
1460-
vis,
1460+
"{vis}{vis_separator}static ref {}: {} =",
14611461
id,
14621462
ty.rewrite_result(context, nested_shape)?
14631463
));

src/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) fn format_visibility(
5555
vis: &Visibility,
5656
) -> Cow<'static, str> {
5757
match vis.kind {
58-
VisibilityKind::Public => Cow::from("pub "),
58+
VisibilityKind::Public => Cow::from("pub"),
5959
VisibilityKind::Inherited => Cow::from(""),
6060
VisibilityKind::Restricted { ref path, .. } => {
6161
let Path { ref segments, .. } = **path;
@@ -69,7 +69,7 @@ pub(crate) fn format_visibility(
6969
let path = segments_iter.collect::<Vec<_>>().join("::");
7070
let in_str = if is_keyword(&path) { "" } else { "in " };
7171

72-
Cow::from(format!("pub({in_str}{path}) "))
72+
Cow::from(format!("pub({in_str}{path})"))
7373
}
7474
}
7575
}

src/visitor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
983983
) {
984984
let vis_str = utils::format_visibility(&self.get_context(), vis);
985985
self.push_str(&*vis_str);
986+
if !vis_str.is_empty() {
987+
self.push_str(" ");
988+
}
986989
self.push_str(format_safety(safety));
987990
self.push_str("mod ");
988991
// Calling `to_owned()` to work around borrow checker.

tests/target/struct_field_doc_comment.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ struct MyTuple(
2525

2626
struct MyTuple(
2727
#[cfg(unix)] // some comment
28-
pub u64,
29-
#[cfg(not(unix))] /*block comment */ pub(crate) u32,
28+
pub u64,
29+
#[cfg(not(unix))] /*block comment */ pub(crate) u32,
3030
);
3131

3232
struct MyTuple(
3333
/// Doc Comments
3434
/* TODO note to add more to Doc Comments */
35-
pub u32,
35+
pub u32,
3636
/// Doc Comments
3737
// TODO note
38-
pub(crate) u64,
38+
pub(crate) u64,
3939
);
4040

4141
struct MyStruct {

0 commit comments

Comments
 (0)