Skip to content

Fix/Inconsistent Struct Body Opening Brace Placement After Where Clause #5508

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

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions src/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,29 @@ fn format_unit_struct(
Some(format!("{}{};", header_str, generics_str))
}

fn set_brace_pos(has_fields: bool, has_content: bool, version: Version) -> BracePos {
return match version {
Version::One => {
if has_fields {
return BracePos::Auto;
}
BracePos::ForceSameLine
}
Version::Two => {
match (has_fields, has_content) {
// Doesn't have fields, there is nothing between {}, has generics.
(true, true) => BracePos::ForceSameLine,

// Doesn't have fields, has something between { }, has generics.
(true, false) => BracePos::Auto,

// Has fields, has generics.
(false, _) => BracePos::Auto,
}
}
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of notes:

  1. the return in return match version is redundant, since the match is the only statement in this function. remove the trailing semicolon from the match statement to convert it to an expression and have it implicitly return its value.
  2. I'm all for extracting this logic into a stand alone function, but I think we can simplify the logic see my next comment for details.


pub(crate) fn format_struct_struct(
context: &RewriteContext<'_>,
struct_parts: &StructParts<'_>,
Expand Down Expand Up @@ -1289,11 +1312,11 @@ pub(crate) fn format_struct_struct(
context,
g,
context.config.brace_style(),
if fields.is_empty() {
BracePos::ForceSameLine
} else {
BracePos::Auto
},
set_brace_pos(
!fields.is_empty(),
span.hi() <= body_lo + BytePos(5),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, this check span.hi() <= body_lo + BytePos(5) has got me scratching my head and it's not obvious from reading the code what it's supposed to be doing. I'm all for moving this logic into a standalone function, but I think this check could be simplified to something like:

            if fields.is_empty() {
                let snippet = context.snippet(mk_sp(body_lo, span.hi()));
                let body_contains_commets = contains_comment(snippet);
                if context.config.version() == Version::Two && body_contains_commets {
                    BracePos::Auto
                } else {
                    BracePos::ForceSameLine
                }
            } else {
                BracePos::Auto
            }

context.config.version(),
),
offset,
// make a span that starts right after `struct Foo`
mk_sp(header_hi, body_lo),
Expand Down
20 changes: 20 additions & 0 deletions tests/source/issue-5507/issue-5507-indent-style-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// rustfmt-version: Two

struct EmptyBody<T>
where T: Eq {
}

struct LineComment<T>
where T: Eq {
// body
}

struct BlockComment<T>
where T: Eq {
/* block comment */
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also add a MultiLineBlockComment case

struct MultiLineBlockComment<T>
    where T: Eq {
    /* block comment 
     * block comment
     */
}


struct HasBody<T>
where T: Eq {
x: T
}
21 changes: 21 additions & 0 deletions tests/source/issue-5507/issue-5507-indent-style-visual.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// rustfmt-indent_style: Visual
// rustfmt-version: Two

struct EmptyBody<T>
where T: Eq {
}

struct LineComment<T>
where T: Eq {
// body
}

struct BlockComment<T>
where T: Eq {
/* block comment */
}

struct HasBody<T>
where T: Eq {
x: T
}
25 changes: 25 additions & 0 deletions tests/target/issue-5507/issue-5507-indent-style-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// rustfmt-version: Two

struct EmptyBody<T>
where
T: Eq,
{}

struct LineComment<T>
where
T: Eq,
{
// body
}

struct BlockComment<T>
where
T: Eq,
{/* block comment */}

struct HasBody<T>
where
T: Eq,
{
x: T,
}
22 changes: 22 additions & 0 deletions tests/target/issue-5507/issue-5507-indent-style-visual.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// rustfmt-indent_style: Visual
// rustfmt-version: Two

struct EmptyBody<T>
where T: Eq
{}

struct LineComment<T>
where T: Eq
{
// body
}

struct BlockComment<T>
where T: Eq
{/* block comment */}

struct HasBody<T>
where T: Eq
{
x: T,
}