SE-0444: Fix interactions with Cxx interop #76756
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
With the upcoming
MemberImportVisibility
feature enabled, code built with Cxx interop also enabled could be rejected by the compiler with cryptic errors about the__ObjC
module not being imported. This is the result of a surprising implementation detail of Cxx interop. When importing C++ namespaces and their members, the Clang importer puts these declarations in the Clang header import module (a.k.a. the bridging header module,__ObjC
). C++ namespaces don't have a logical modular home in the Swift AST because they can span multiple modules, so it's understandable why this implementation was chosen. However, the concrete members of namespaces also get placed in the__ObjC
module too, and this really confuses things.To work around this idiosyncrasy of Cxx interop, I've introduced
Decl::getModuleContextForNameLookup()
which returns the module that a declaration would ideally belong to if Cxx interop didn't have this behavior. This alternative toDecl::getModuleContext()
is now used everywhere thatMemberImportVisibility
rules are enforced to provide consistency.Additionally, I found that I also had to further special-case the header import module for Cxx interop because it turns out that there are some additional declarations, beyond imported namespaces, that also live there and need to be implicitly visible in every source file. The
__ObjC
module is not implicitly imported in source files when Cxx interop is enabled, so these declarations are not deemed visible under normal name lookup rules. When I tried to add an implicit import of__ObjC
when Cxx interop is enabled, it broke a bunch tests. So for now, when a decl really belongs to the__ObjC
module in Cxx interop mode, we just always allow it to be referenced.This Cxx interop behavior really needs a re-think in my opinion, but that will require larger discussions.
Resolves rdar://136600598.