Skip to content

Commit

Permalink
fix(items): Fix handling of rustdoc and macro attributes in enum
Browse files Browse the repository at this point in the history
This fix was made thanks to the hint at [1].
This was reported in issue rust-lang#5662 [2].

Previously, a enum item containing an attribute (rustdoc or macro) would
be considered multi-line, thus forcing the formatting strategy of all
the items in the enum to be Vertical (i.e. multi-line formatting).

When determining the formatting strategy for enum items, we should
ignore the attributes. This is what we do in the `is_multi_line_variant`
function. Or else, simply adding a rustdoc comment or a macro attribute
would cause the formatting of the whole enum to change, which is not a
desirable behavior.

We will be adding tests in the following commits.

- [1] rust-lang#5662 (comment)
- [2] rust-lang#5662
  • Loading branch information
malikolivier committed Aug 18, 2024
1 parent 40f5075 commit ce990c8
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use crate::expr::{
rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, rewrite_let_else_block,
RhsAssignKind, RhsTactics,
};
use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
use crate::lists::{
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
};
use crate::macros::{rewrite_macro, MacroPosition};
use crate::overflow;
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
Expand Down Expand Up @@ -643,8 +645,27 @@ impl<'a> FmtVisitor<'a> {
let mut items: Vec<_> = itemize_list_with(self.config.struct_variant_width());

// If one of the variants use multiple lines, use multi-lined formatting for all variants.
let has_multiline_variant = items.iter().any(|item| item.inner_as_ref().contains('\n'));
let has_single_line_variant = items.iter().any(|item| !item.inner_as_ref().contains('\n'));
fn is_multi_line_variant(item: &ListItem) -> bool {
let variant_str = item.inner_as_ref();
let mut first_line_is_read = false;
for line in variant_str.split('\n') {
if first_line_is_read {
return false;
}

// skip rustdoc comments and macro attributes
let line = line.trim_start();
if line.starts_with("///") || line.starts_with("#") {
continue;
} else {
first_line_is_read = true;
}
}

true
}
let has_multiline_variant = items.iter().any(is_multi_line_variant);
let has_single_line_variant = items.iter().any(|item| !is_multi_line_variant(item));
if has_multiline_variant && has_single_line_variant {
items = itemize_list_with(0);
}
Expand Down

0 comments on commit ce990c8

Please sign in to comment.