|
| 1 | +# Swift and C++ interop: Guide for Swift contributors |
| 2 | + |
| 3 | +This document describes how to contribute changes to Swift |
| 4 | +and C++ interoperability support in the Swift compiler. |
| 5 | +The recommended way to contribute touches on topics |
| 6 | +like source stability of C++ interop, making breaking |
| 7 | +changes, and compatibility testing. |
| 8 | + |
| 9 | +Here's a short summary of how you should contribute |
| 10 | +to Swift and C++ interop: |
| 11 | +- Treat every change as potentially source breaking, unless proven otherwise. |
| 12 | +- Guard any potentially source breaking change with appropriate interop compat version checks. |
| 13 | +- Explicitly specify the interop compat version in your test when adding breaking changes. |
| 14 | +- Ensure that your GitHub PR is approved by one of the code owners before merging. |
| 15 | + |
| 16 | +## Changing Swift and C++ interop |
| 17 | + |
| 18 | +The initial support for Swift and C++ interop in Swift 5.9 |
| 19 | +is considered to be source stable, as in a future compiler |
| 20 | +like Swift 5.10 |
| 21 | +must build any Swift code that uses C++ interop |
| 22 | +and was previously built with Swift 5.9 compiler without |
| 23 | +forcing the user to make **any** changes to their code. |
| 24 | +Because of that promise that we're making to our users, |
| 25 | +we need to be very diligent when it comes to making |
| 26 | +changes to how Swift and C++ interop work, as they could |
| 27 | +potentially violate this promise. Thus it's recommended |
| 28 | +that you treat every |
| 29 | +change as source breaking, unless proven otherwise. |
| 30 | + |
| 31 | +### What is C++ Interop Compat Version |
| 32 | + |
| 33 | +C++ interop compat version is the Swift version |
| 34 | +value given to the `-cxx-interoperability-mode=` Swift |
| 35 | +command line option. |
| 36 | + |
| 37 | +It supports values like: |
| 38 | +- `default`. Corresponds to the currently used Swift language version. |
| 39 | + For instance, by default for Swift 5 compiler the C++ interop compat version |
| 40 | + will be 5 when `-cxx-interoperability-mode=default` is passed. However, |
| 41 | + if you pass `-cxx-interoperability-mode=default` and `-swift-version 6`, |
| 42 | + then the C++ interop compat version becomes 6. |
| 43 | + |
| 44 | +- `swift-X.Y`. A specific version like Swift 5.9. |
| 45 | + |
| 46 | +- `upcoming-swift`. Corresponds to the C++ interop compat version that |
| 47 | + represents the development *unreleased* version of Swift and C++ interoperability. |
| 48 | + All new source breaking changes must be guarded by this version first |
| 49 | + before they migrate to a specific *released* version of Swift and C++ interoperability. |
| 50 | + |
| 51 | +### Guarding Source Breaking Changes in Compiler Implementation |
| 52 | + |
| 53 | +Any source breaking change must be guarded with an appropriate |
| 54 | +interop compat version check. Swift's `LangOptions` have |
| 55 | +a `cxxInteropCompatVersion` member that is the interop compat version. |
| 56 | + |
| 57 | +You can use the `isCxxInteropCompatVersionAtLeast` check to validate that |
| 58 | +you're building for the upcoming version of C++ and Swift interop. |
| 59 | +For example, in the clang importer, you can call this check method on |
| 60 | +the `Impl`: |
| 61 | + |
| 62 | +``` |
| 63 | +// Inside of Clang Importer (Impl is `ClangImporter::Impl`) |
| 64 | +if (Impl.isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())) { |
| 65 | + // ... breaking change ... |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +Elsewhere, this method can be called on the `LangOptoins` themselves: |
| 70 | + |
| 71 | +``` |
| 72 | +if (SwiftContext.LangOpts.isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())) { |
| 73 | + // ... breaking change ... |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +### Testing the change |
| 78 | + |
| 79 | +Please add new tests under `test/Interop/Cxx`, or |
| 80 | +modify existing tests there. |
| 81 | + |
| 82 | +Any tests for source breaking changes |
| 83 | +should invoke the Swift compiler with |
| 84 | +the `-cxx-interoperability-mode=upcoming-swift` |
| 85 | +option. |
| 86 | + |
| 87 | +## Submitting the Change as PR on GitHub |
| 88 | + |
| 89 | +GitHub PR checklist for C++ interop related changes: |
| 90 | +- Please tag your PR with 'C++ Interop' tag. |
| 91 | +- Code owners should be added for review automatically. |
| 92 | +- Please ensure that one of the current code owners reviews and approves the PR before merging. |
| 93 | + |
| 94 | +## Releasing a new Swift and C++ Interop Compat Version |
| 95 | + |
| 96 | +You need to update all Swift |
| 97 | +sources to migrate these checks `isCxxInteropCompatVersionAtLeast(version::getUpcomingCxxInteropCompatVersion())` |
| 98 | +to the concrete version you're now releasing, for instance `isCxxInteropCompatVersionAtLeast(5, 10)`. |
| 99 | + |
| 100 | +There are more things we'll need to do but we haven't released a new interop compat version yet, |
| 101 | +so this document will be updated once we do so. |
0 commit comments