Skip to content

Commit ce990c8

Browse files
committed
fix(items): Fix handling of rustdoc and macro attributes in enum
This fix was made thanks to the hint at [1]. This was reported in issue #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] #5662 (comment) - [2] #5662
1 parent 40f5075 commit ce990c8

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

Diff for: src/items.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use crate::expr::{
2121
rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, rewrite_let_else_block,
2222
RhsAssignKind, RhsTactics,
2323
};
24-
use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
24+
use crate::lists::{
25+
definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
26+
};
2527
use crate::macros::{rewrite_macro, MacroPosition};
2628
use crate::overflow;
2729
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
@@ -643,8 +645,27 @@ impl<'a> FmtVisitor<'a> {
643645
let mut items: Vec<_> = itemize_list_with(self.config.struct_variant_width());
644646

645647
// If one of the variants use multiple lines, use multi-lined formatting for all variants.
646-
let has_multiline_variant = items.iter().any(|item| item.inner_as_ref().contains('\n'));
647-
let has_single_line_variant = items.iter().any(|item| !item.inner_as_ref().contains('\n'));
648+
fn is_multi_line_variant(item: &ListItem) -> bool {
649+
let variant_str = item.inner_as_ref();
650+
let mut first_line_is_read = false;
651+
for line in variant_str.split('\n') {
652+
if first_line_is_read {
653+
return false;
654+
}
655+
656+
// skip rustdoc comments and macro attributes
657+
let line = line.trim_start();
658+
if line.starts_with("///") || line.starts_with("#") {
659+
continue;
660+
} else {
661+
first_line_is_read = true;
662+
}
663+
}
664+
665+
true
666+
}
667+
let has_multiline_variant = items.iter().any(is_multi_line_variant);
668+
let has_single_line_variant = items.iter().any(|item| !is_multi_line_variant(item));
648669
if has_multiline_variant && has_single_line_variant {
649670
items = itemize_list_with(0);
650671
}

0 commit comments

Comments
 (0)