-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
[SR-14195] Swift emits an invalid module interface when a public type has the same name as a module #56573
Comments
…tinterface files. This is a workaround for a compiler bug that generates a broken textual interface. See swiftlang/swift#56573 for details.
…tinterface files. This is a workaround for a compiler bug that generates a broken textual interface. See swiftlang/swift#56573 for details.
A workarounds for this bug swiftlang/swift#56573
If file contains enum for example Example:
Generated *.swiftinterface file:
Expected *.swiftinterface file:
|
This reverts commit a814b62.
…ftlang/swift#56573" This reverts commit 2edd7db.
Added `BUILD_LIBRARIES_FOR_DISTRIBUTION=YES` to include the .swiftinterface file in the built framework. See: https://developer.apple.com/forums/thread/125646 Needed some additional Swift flags because our module contains a class with the same name, to work around a Swift bug. See: swiftlang/swift#56573 Mixing Swift and Objective C thanks to tips in: https://joesusnick.medium.com/swift-package-manager-with-a-mixed-swift-and-objective-c-project-part-2-2-e71dad234e6
See this issue for details: swiftlang/swift#56573
See this issue for details: swiftlang/swift#56573
how does 'library evolution' play into this? should I just turn off library evolution? |
Either that if you are not shipping a binary-compatible library or here are some other options. |
Change module name to work around Swift bug swiftlang/swift#56573
…ode' and potential import failures in certain configurations, see swiftlang/swift#56573 for workarounds.
…nycode' with 'Puny' to resolve namespace conflicts. public class 'Punycode.Punycode' shadows module 'Punycode', which may cause failures when importing 'Punycode' or its clients in some configurations; please rename either the class 'Punycode.Punycode' or the module 'Punycode', or see swiftlang/swift#56573 for workarounds
…stallation instructions for Swift Package Manager and Carthage The framework name has been changed from **Punycode** to **PunycodeSwift**. This change is based on the information provided in [this issue](swiftlang/swift#56573), which discusses potential naming conflicts in Swift modules. To integrate Punycode into your project using Swift Package Manager, add the following to your `Package.swift` file: ```swift dependencies: [ .package(url: "https://github.com/gumob/PunycodeSwift.git", .upToNextMajor(from: "3.0.0")) ] ``` For Carthage, add the following to your `Cartfile` and follow [these instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). This change also updates the macOS, iOS, tvOS, watchOS, and visionOS versions supported by the framework, as well as the Swift version required.
feat(module): replace module name with PubNubSDK (swiftlang/swift#56573) feat(subscribe): add new subscriptionChanged(channels, groups) status, remove connecting and reconnecting cases feat(reconnection-policy): remove .legacyExponential(base, scale, maxDelay) reconnection policy feat(objects): add additional fields to fetch in PubNub.MembershipInclude and PubNub.MemberInclude feat(configuration): set default AutomaticRetry for retrying subscribe requests with exponential reconnection policy feat(listeners): add support for attaching additional listeners to Subscription and SubscriptionSet fix(listeners): ensure that subscriptions are always internally stored as weak references
Additional Detail from JIRA
md5: 61edb3ff0102d366e7e0d5868573a20b
is blocked by:
Issue Description:
When a module with library evolution enabled either declares or imports an ABI-public type with the same name as a module it imports, the Swift compiler can emit a module interface with invalid type references that cannot be imported. This happens because attempts to prefix type names with that module are instead interpreted as attempts to find a nested type within the identically-named type. This problem is usually invisible until a client tries to read the module interface, which is rarely done in normal development workflows, so the invalid module interface may not be noticed until much later.
(This bug is already tracked indirectly by SR-898, but I am creating a separate bug that is specific to module interfaces so we can clearly document workarounds and track emitting SR-898's new syntax into module interfaces.)
Example
The simplest example is a module which is named after the main type it provides. For instance, suppose a module called
Compass
has a file which declares:When you build the Compass module with library evolution enabled, Swift will emit a module interface for this file which looks something like this:
Note that, in the
var
declaration, Swift printsCompass.Direction
to mean "theDirection
type in theCompass
module". However, when a later Swift compiler tries to import this file (which may only happen if it's a different compiler version), it will resolve the nameCompass
inCompass.Direction
to the classCompass
, not the moduleCompass
. This will usually cause a compiler error:It's possible to see more complicated versions of this bug; for instance, the new type could have the same name as a module imported by the interface, or it could import a type with its own name. Especially in these cases, it's possible that your own module interface will be valid because it never references the affected module, but your clients' module interfaces may be affected.
Workarounds
The simplest, most reliable solution is to rename either the module or the type. For instance, if the module is named
CompassKit
orOrienteer
and the type is namedCompass
, there will be no conflict between them.If that isn't possible, you may be able to work around this bug by adding the special compiler flags
-Xfrontend -module-interface-preserve-types-as-written
to OTHER_SWIFT_FLAGS. This solution is not 100% reliable; in particular, you may have to manually implement conformances to protocols likeHashable
to get them to print correctly. It is also something your module's clients may need to adopt if their interfaces refer to types from the affected module.If all else fails, you can write a script or tool which edits the
.swiftinterface
files generated by your project. A simple regular expression substitution usually works, but these sorts of tools are often quite fragile, so use them as a last resort.Prevention and verification
Swift 5.4 supports a
-verify-emitted-module-interface
flag which causes it to immediately typecheck.swiftinterface
files after emitting them to verify that they are valid. You can add that flag to OTHER_SWIFT_FLAGS to make sure your interfaces are readable.You can also take a copy of your framework or library, delete the
.swiftmodule
files from it (leaving the.swiftinterface
files alone), and check that you can still import it in a test project.Eventual compiler fix
The root cause of this bug is that Swift's language rules don't provide a way to unambiguously specify a module name. SR-898 tracks this issue; once an appropriate feature is added to the language, we will need to start printing it into module interfaces. This bug will eventually track that adoption work.
The text was updated successfully, but these errors were encountered: