Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoiding extra linebreaks when doc-comment added to enum #5662

Open
xldenis opened this issue Jan 17, 2023 · 2 comments · May be fixed by #5724 or #6286
Open

Avoiding extra linebreaks when doc-comment added to enum #5662

xldenis opened this issue Jan 17, 2023 · 2 comments · May be fixed by #5724 or #6286

Comments

@xldenis
Copy link

xldenis commented Jan 17, 2023

I've noticed what I consider to be an unfortunate decision in rustfmt: the moment a single doc-comment is added in an enum, the whole enum is laid out with a line per field, even when no fields are documented.

That is, the type:

enum MyType {
    A { field1: bool, field2: bool },
    B { field1: bool, field2: bool },
    /// OMG a comment
    C { field1: bool, field2: bool },
    D { field1: bool, field2: bool },
}

becomes

enum MyType {
    A {
        field1: bool,
        field2: bool,
    },
    B {
        field1: bool,
        field2: bool,
    },
    /// OMG a comment
    C {
        field1: bool,
        field2: bool,
    },
    D {
        field1: bool,
        field2: bool,
    },
}

The formatting policy I would like would leave the type unchanged. If a doc-comment is added to a single field of a variant, then only that variant should be broken up on multiple lines rather than the whole type.

is this something that could potentially be customizable as an option in rustfmt.toml? If so, I would be happy to implement this if someone can point be in the right direction.

@ytmimi
Copy link
Contributor

ytmimi commented Jan 17, 2023

Thanks for reaching out. Confirming that I'm able to reproduce the behavior with the latest master rustfmt 1.5.1-nightly (ee2bed96 2022-11-08).

I also want to point out that this isn't unique to doc comments. It could be any attribute. For example, this input:

enum MyType {
    A { field1: bool, field2: bool },
    #[something]
    B { field1: bool, field2: bool },
}

will be reformatted as:

enum MyType {
    A {
        field1: bool,
        field2: bool,
    },
    #[something]
    B {
        field1: bool,
        field2: bool,
    },
}

If you want to take a look at implementing this you'll want to check out format_variant_list. More specifically you'll likely need to make modifications here:

rustfmt/src/items.rs

Lines 518 to 523 in ee2bed9

// 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'));
if has_multiline_variant && has_single_line_variant {
items = itemize_list_with(0);
}

In your example the C variant is considered multi-line since the doc comment /// OMG a comment is treated as if it were part of the variant, and the newline separating the doc comment and the variant is classifying the whole variant as multi-lined.

It might make sense to try and make the multi-lined check smarter by ignoring the first lines that start with # or ///. However, a new config option would be needed to allow both single line and multi-line enum variants.

@RalfJung
Copy link
Member

It's not as simple as "doc comments make the enum multiline", see #6120. I have no idea at all what the underlying pattern is here.

malikolivier added a commit to malikolivier/rustfmt that referenced this issue Aug 16, 2024
Made this first fix attempt with the hint at [1]

[1] rust-lang#5662 (comment)
malikolivier added a commit to malikolivier/rustfmt that referenced this issue Aug 16, 2024
Made this first fix attempt with the hint at [1]

[1] rust-lang#5662 (comment)
malikolivier added a commit to malikolivier/rustfmt that referenced this issue Aug 18, 2024
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
@malikolivier malikolivier linked a pull request Aug 19, 2024 that will close this issue
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants