Skip to content

Name namespace-scope unscoped enums#4838

Open
avikivity wants to merge 1 commit into
fmtlib:mainfrom
avikivity:unscoped-enums-bad
Open

Name namespace-scope unscoped enums#4838
avikivity wants to merge 1 commit into
fmtlib:mainfrom
avikivity:unscoped-enums-bad

Conversation

@avikivity

@avikivity avikivity commented Jul 5, 2026

Copy link
Copy Markdown

Unnamed unscoped enums at namespace scope are problematic
(llvm/llvm-project#207581). Giving each such
enum a name (derived from the constant it declares) is enough to avoid
the issue, so do that for the header-level integral constants instead of
leaving them anonymous.

@avikivity avikivity requested a review from vitaut as a code owner July 5, 2026 13:16
Unnamed unscoped enums at namespace scope are problematic
(llvm/llvm-project#207581). Giving each such
enum a name (derived from the constant it declares) is enough to avoid
the issue, so do that for the header-level integral constants instead of
leaving them anonymous.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@avikivity avikivity force-pushed the unscoped-enums-bad branch from dc8beff to 649ae19 Compare July 5, 2026 18:03
@avikivity

Copy link
Copy Markdown
Author

Update:

  • rebased
  • simplified: it's enough to name the unscoped enum to make it module-friendly

@avikivity avikivity changed the title Replace namespace-scope unscoped enums with FMT_INLINE_VAR Name namespace-scope unscoped enums Jul 5, 2026
@avikivity

Copy link
Copy Markdown
Author

@vitaut please review

@vitaut

vitaut commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for the PR.

The linked issue says

Two conditions are both necessary (and, together, sufficient):

  1. ...
  2. A module re-exports that enumerator with a using-declaration. Re-exporting
    a sibling (a type, or the dependent alias itself) does not trigger it.

Could you elaborate where these enumerators are re-exported?

@avikivity

Copy link
Copy Markdown
Author

The first module to export the enum is Seastar. It doesn't name the enumerator directly. Rather it uses fmt via headers, (Seastar cannnot assume all its users consume it as a module), and some of Seastar's exported symbols depend on this enum (max_packed_args, easy to see how it would become a dependency).

The second module is my fmt.cppm (I should probably switch to fmt.cc, but it isn't packaged by Fedora). Whether it is named there or not, it is referred to.

When the two modules are imported by ScyllaDB, the two declarations clash.

Naming those enums makes the problem go away. It was also fixed in clang, but I ask that you accept this patch as a band-aid for people who use ancient compilers like clang 22.1.8 (clang 22 isn't backporting any more, as well).

gcc is also vulnerable, I'll file a bug report there too.

@avikivity

Copy link
Copy Markdown
Author

gcc is also vulnerable, I'll file a bug report there too.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126192

@vitaut

vitaut commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

But fmt's module doesn't re-export the max_packed_args enumerator with a using-declaration, so I still don't understand where the issue is coming from.

@avikivity

Copy link
Copy Markdown
Author

Modules will stealthily export enough stuff to be able to build the exported inline functions.

IIRC my fmt.cppm did not export max_packed_args using a using statement, and I only added it later trying to workaround the failures. I will verify and report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants