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

[clang-format] incorrect formatting with & qualifier and requires clause with multi-arg template #65904

Closed
danakj opened this issue Sep 10, 2023 · 3 comments · Fixed by #65908
Assignees

Comments

@danakj
Copy link
Contributor

danakj commented Sep 10, 2023

The first one has no & qualifier and is formatted correct.

The second one adds & and clang-format gets confused, I don't think it's aware this is a function anymore.

struct S {
    template <class... Args>
    constexpr void f()
        requires(true && C<true, Args...>)
    {
        return;
    }

    template <class... Args>
        constexpr void f() & requires(true && C<true, Args...>) { return; }
};

The const and const& qualifiers are parsed correctly. && is also incorrect.

struct S {
    template <class... Args>
    constexpr void f() const
        requires(true && C<true, Args...>)
    {
        return;
    }

    template <class... Args>
    constexpr void f() const&
        requires(true && C<true, Args...>)
    {
        return;
    }

    template <class... Args>
        constexpr void f() && requires(true && C<true, Args...>) { return; }
};

https://godbolt.org/z/qKTWec96e

@danakj
Copy link
Contributor Author

danakj commented Sep 10, 2023

It does very wrong things with whatever comes after as well:

struct S {
    template <class... Args>
        constexpr void f() && requires(true && C<true, Args...>) { return; }

        private : int i;
};

@rymiel
Copy link
Member

rymiel commented Sep 10, 2023

It seems that for this bug to show up, you need both the parentheses after the requires keyword and also a comma (i.e. the one in the angle brackets), like so:
void f() & requires(C<true, true>)
Investigating

@rymiel rymiel self-assigned this Sep 10, 2023
rymiel added a commit to rymiel/llvm-project that referenced this issue Sep 10, 2023
clang-format uses a heuristic to determine if a requires() is either a
requires clause or requires expression, based on what is in the
parentheses. Part of this heuristic assumed that a requires clause can
never contain a comma, however this is not the case if said comma is in
the template argument of a type.

This patch allows commas to appear in a requires clause if an angle
bracket `<` has been opened.

Fixes llvm#65904
@rymiel rymiel removed the new issue label Sep 10, 2023
@danakj
Copy link
Contributor Author

danakj commented Sep 10, 2023

That was fast, thank you =)

rymiel added a commit that referenced this issue Sep 27, 2023
clang-format uses a heuristic to determine if a requires() is either a
requires clause or requires expression, based on what is in the
parentheses. Part of this heuristic assumed that a requires clause can
never contain a comma, however this is not the case if said comma is in
the template argument of a type.

This patch allows commas to appear in a requires clause if an angle
bracket `<` has been opened.

Fixes #65904
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this issue Sep 29, 2023
clang-format uses a heuristic to determine if a requires() is either a
requires clause or requires expression, based on what is in the
parentheses. Part of this heuristic assumed that a requires clause can
never contain a comma, however this is not the case if said comma is in
the template argument of a type.

This patch allows commas to appear in a requires clause if an angle
bracket `<` has been opened.

Fixes llvm#65904
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.

2 participants