Skip to content

[cxx-interop] Fix assertion failure from unavailable typedef + enum pattern #81625

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 4 commits into
base: main
Choose a base branch
from

Conversation

j-hui
Copy link
Contributor

@j-hui j-hui commented May 19, 2025

The NS_OPTIONS macro sometimes uses a pattern where it loosely
associates a typedef with an anonymous enum via a shared underlying
integer type (emphasis on "loosely"). The typedef is marked as
unavailable in Swift so as to not cause name ambiguity when we associate
the anonymous enum with said typedef. We use unavailability as
a heuristic during the import process, but that conflates NS_OPTIONS
with NS_ENUMs that can be marked as unavailable for entirely unrelated
reasons.

That in and of itself is fine, because the import logic is general
enough to handle both cases, but we have an assertion that seems to be
unaware of this scenario, and trips on unavailable NS_ENUMs. (In those
cases, the typedef points to the enum rather than the underlying integer
type.) This patch fixes the assertion to be resilient against such cases
by looking through the enum a typedef refers to.

This PR also includes some NFC commits which consolidate usage of the findOptionSetEnum() helper function. This pattern (and the failing assertion) was previously duplicated across six distinct locations across ImportDecl.cpp and ImportType.cpp. The interface and behavior of this function is based on findOptionSetType(), which was previously defined in ImportDecl.cpp but also used in ImportType.cpp via an ad hoc function declaration.

Those NFC commits make way for 75e4f04, where the actual fix is contained to a fairly small change.

rdar://150399978

j-hui added 2 commits May 19, 2025 14:10
…nction

Also renames it to findOptionSetEnum() to make it a bit clearer at face
value that the returned ImportedType will contain a Swift enum.

Also refactors some nearby instances of

  if (auto e = dyn_cast<ElaboratedType>(t))
      t = e->desugar();

into a helper function, desugarIfElaborated().
…EnumInfo.cpp

It's at home there alongside other ObjC enum-specific logic, rather than
in the middle of ImportDecl.cpp (since it isn't directly or exclusively
related to importing decls).
@j-hui
Copy link
Contributor Author

j-hui commented May 19, 2025

Draft PR with only NFC commits for now, to run under CI

@j-hui
Copy link
Contributor Author

j-hui commented May 19, 2025

@swift-ci please test

@j-hui
Copy link
Contributor Author

j-hui commented May 20, 2025

macOS tests are still hanging but Linux + Windows have passed, so it seems I didn't accidentally break anything with the [NFC] commits. Pushing actual patch + opening the PR now

j-hui added 2 commits May 19, 2025 22:17
The NS_OPTIONS macro sometimes uses a pattern where it loosely
associates a typedef with an anonymous enum via a shared underlying
integer type (emphasis on "loosely"). The typedef is marked as
unavailable in Swift so as to not cause name ambiguity when we associate
the anonymous enum with said typedef. We use unavailability as
a heuristic during the import process, but that conflates NS_OPTIONS
with NS_ENUMs that can be marked as unavailable for entirely unrelated
reasons.

That in and of itself is fine, because the import logic is general
enough to handle both cases, but we have an assertion that seems to be
unaware of this scenario, and trips on unavailable NS_ENUMs. (In those
cases, the typedef points to the enum rather than the underlying integer
type.) This patch fixes the assertion to be resilient against such cases
by looking through the enum a typedef refers to.

rdar://150399978
@j-hui j-hui force-pushed the fix-unavailable-enum branch from bea20a2 to 75e4f04 Compare May 20, 2025 05:18
@j-hui j-hui marked this pull request as ready for review May 20, 2025 05:18
@j-hui
Copy link
Contributor Author

j-hui commented May 20, 2025

@egorzhdan for what it's worth, I tried explicitly checking for {CF,NS}_OPTIONS in this patch bea20a2 but it causes one of our regression tests that uses a custom macro to fail, so I'm not including that in this patch set. For the future, I'm wondering whether we should be explicitly checking for the enum_flag or enum_open attributes, rather than relying on heuristics like availability or the spelling of the macro used to produce these decls.

For now, 75e4f04 keeps the behavior consistent with what it was before, and simply adjusts the assertion to accommodate NS_ENUMs.

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.

1 participant