From 7d2ae4e7d87682e6fcfa1095d24aa53ffd2aebac Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 29 Jan 2025 09:41:27 +0000 Subject: [PATCH 01/16] burp --- ...migration-tooling-for-upcoming-features.md | 335 ++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 proposals/NNNN-migration-tooling-for-upcoming-features.md diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md new file mode 100644 index 0000000000..47097ba859 --- /dev/null +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -0,0 +1,335 @@ +# Adoption tooling for Swift features + +* Proposal: [SE-NNNN](NNNN-filename.md) +* Authors: [Anthony Latsis](https://github.com/AnthonyLatsis) +* Review Manager: TBD +* Status: **Awaiting implementation** +* Implementation: TBD +* Review: TBD + +## Introduction + +The future we envision for Swift will take many more valiant evolutionary +decisions and major transformations with a proportional impact on its +expanding domains. + +Source-breaking changes to Swift were first staged behind the now obsolete +Swift 3 language mode. +Each successive major release has since included a correponding language mode, +using the previous language mode as the default to maximize source +compatibility. +For example, Swift 6 compilers operate in the Swift 5 language mode by default. +Users that are not ready to adopt the new default can still specify an earlier +language mode explicitly. +Once the time is right, old language modes together with the legacy behaviors +they manifest will be proposed to be deprecated. + +The cumulative source compatibility impact of the changes that were accreting +around a converging Swift 6 language mode gave rise to the +[Swift feature model][SE-0362], which enabled piecemeal adoption of individual +features as opposed to an entire language mode. +Upcoming features facilitated sooner adoption of improvements and drastically +reduced the pressures in our evolutionary model. + +This proposal centers seeks to improve the experience of adopting individual +features. +The proposition is that the growing complexity and diversification of Swift +calls for a flexible, integrated mechanism for supporting quality assistance +with feature adoption. +And that — in principle — comprehensive, code-aware assistance can be delivered +without breaking source and acted upon incrementally. + +## Motivation + +Whether you are adjusting code to follow new language rules or researching ways +to apply new functionality, adopting features can be a time-consuming endeavor +at the least. + +Some source-breaking language features are anticipated to generate hundreds +of targeted errors in sizable projects. +Occasionally, errors will also cascade down the dependecy graph or fall out +from changes in behavior without a clear indication of the precise cause or source of +the issue, requiring further investigation. +Developers are left to either resolve all of these errors or address a subset +and take the risk of switching the feature back off before they can resume +development and focus on other important tasks. + +### User Intent + +> [!CAUTION] +> TODO: No way for users to declare an intetion to adopt a feature + +### Automation + +Many existing and prospective upcoming features imply or implement simple and +consistent code modifications to facilitate the adoption process: + +* [`NonfrozenEnumExhaustivity`][SE-0192]: Restore exhaustivity with + `@unknown default:`. +* [`ConciseMagicFile`][SE-0274]: `#file` → `#filePath`. +* [`ForwardTrailingClosures`][SE-0286]: Disambiguate argument matching by + de-trailing closures and/or inlining default arguments. +* [`ExistentialAny`][SE-0335]: `P` → `any P`. +* [`ImplicitOpenExistentials`][SE-0352]: Suppress opening with `as any P` + coercions. +* [`BareSlashRegexLiterals`][SE-0354]: Disambiguate using parentheses, + e.g. `foo(/a, b/)` → `foo((/a), b/)`. +* [`DeprecateApplicationMain`][SE-0383]: `@UIApplicationMain` → `@main`, + `@NSApplicationMain` → `@main`. +* [`DisableOutwardActorInference`][SE-0401]: Specify global actor isolation + explicitly. +* [`InternalImportsByDefault`][SE-0409]: `import X` → `public import X`. +* [`GlobalConcurrency`][SE-0412]: + - Convert the global variable to a `let` (or) + - `@MainActor`-isolate it (or) + - Mark it with `nonisolated(unsafe)` +* [`MemberImportVisibility`][SE-0444]: Add explicit imports appropriately. +* [`InferSendableFromCaptures`][SE-0418]: Suppress inference with coercions + and type annotations. +* [Inherit isolation by default for async functions][async-inherit-isolation-pitch]: + Mark nonisolated functions with the proposed attribute. + +Feature + +Extending diagnostic metadata to include information that allows for +recognizing these diagnostics and distinguishing semantics-preserving fix-its +from alternative source changes would open up numerous opportunities for +higher-level tools — ranging from the Swift package manager to IDEs — to +implement powerful solutions for organizing, automating, and tuning code +migration processes. + +### Flexibility/Ergonomics + +> [!CAUTION] +> Still a draft. + +Although upcoming features should strive to facilitate code migration, + +language design principles may prevail over bespoke code migration solutions. +Some features, like [StrictConcurrency][SE-0337], inherently require user +intervetion + +Adjusting to new behaviors or language requirements can demand research, +careful consideration, coordinated efforts, and manual code refactorings, +sometimes on a case-by-case basis. + +Currently best solution is to implement custom staging solutions. This approach +has limited applications (why?). + +UPCOMING_FEATURE(DynamicActorIsolation, 423, 6) +UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6) +UPCOMING_FEATURE(StrictConcurrency, 0337, 6) +UPCOMING_FEATURE(IsolatedDefaultValues, 411, 6) +UPCOMING_FEATURE(RegionBasedIsolation, 414, 6) + +## Proposed solution + +Introduce the notion of a "adoption" mode for individual experimental and +upcoming features. +The core idea behind adoption mode is a declaration of intent that can be +leveraged to build holistic supportive adoption experiences for developers. +If enabling a feature communicates an intent to *enact* rules, adoption mode +communicates an intent to *adopt* them. +An immediate benefit of adoption mode is the capability to deliver source +modifications that can be applied to preserve or improve the behavior of +existing code whenever the feature provides for them. + +> [!NOTE] +> The subject of this proposal is an enhancement to the Swift feature model. +> Applications of adoption mode to existing features are beyond its scope. + +## Detailed design + +### Behavior + +The action of enabling a previously disabled source-breaking feature in adoption +mode per se must never produce compilation errors. +Additionally, this action will have no effect on the state of the feature if +it does not implement the mode. +A corresponding warning will be emitted in this case to avoid the false +impression that the impacted source code is compatible with the feature. + +> [!NOTE] +> Experimental features can be both additive and source-breaking. +> Upcoming features are necessarily source-breaking. + +adoption mode will deliver guidance in the shape of warnings, notes, remarks, +and fix-its, as and when appropriate. + +When implemented, adoption mode for upcoming features is expected to anticipate +and call out any behavioral differences that will result from enacting the +feature, coupling diagnostic messages with counteracting source-compatible +changes and helpful alternatives whenever possible. +Adoption mode cannot guarantee to provide exclusively source-compatible +modifications because the impact of a change on dependent source code is +generally unpredictable. +Neither can it promise to always offer fix-its in the first place for the +same reason in regards to user intention. + +### Interface + +#### Compiler + +The `-enable-*-feature` frontend and driver command line options will start +supporting an optional mode specifier with `adoption` as the only valid mode: + +``` +-enable-upcoming-feature [:] +-enable-experimental-feature [:] + + := adoption +``` + +For example: + +``` +-enable-upcoming-feature InternalImportsByDefault:adoption +``` + +In a series of either of these options applied to a given feature, only the +last option will be honored. +If an upcoming feature is both implied by the effective language mode and +enabled in adoption mode using either of the aforementioned options, the latter +will be disregarded. + +#### Swift package manager + +The [`SwiftSetting.enableUpcomingFeature`] and +[`SwiftSetting.enableExperimentalFeature`] methods from the +[`PackageDescription`](https://developer.apple.com/documentation/packagedescription) +library will be augmented with a `mode` parameter defaulted to match the +current behavior: + +```swift +extension SwiftSetting { + @available(_PackageDescription, introduced: 6.2) + public enum SwiftFeatureMode { + case adoption + case on + } +} +``` +```diff + public static func enableUpcomingFeature( + _ name: String, ++ mode: SwiftFeatureMode = .on, + _ condition: BuildSettingCondition? = nil + ) -> SwiftSetting { ++ let argument = switch mode { ++ case .adoption: "\(name):adoption" ++ case .mode: name ++ } ++ + return SwiftSetting( +- name: "enableUpcomingFeature", value: [name], condition: condition) ++ name: "enableUpcomingFeature", value: [argument], condition: condition) + } +``` +```diff + public static func enableExperimentalFeature( + _ name: String, ++ mode: SwiftFeatureMode = .on, + _ condition: BuildSettingCondition? = nil + ) -> SwiftSetting { ++ let argument = switch mode { ++ case .adoption: "\(name):adoption" ++ case .mode: name ++ } ++ + return SwiftSetting( +- name: "enableExperimentalFeature", value: [name], condition: condition) ++ name: "enableExperimentalFeature", value: [argument], condition: condition) + } +``` + +For example: + +``` +SwiftSetting.enableUpcomingFeature("InternalImportsByDefault", mode: .adoption) +``` + +### Diagnostics + +Diagnostics emitted in relation to a specific feature in adoption mode must +belong to a diagnostic group named after the feature. +There are several reasons why this will be useful: +* Future feature-oriented adoption tooling can use the group identifier to + filter out relevant diagnostics. +* IDEs and other diagnostic consumers can integrate group identifiers into + their interfaces to, well, group diagnostics, as well as to communicate + relationships between diagnostics and features. This can prove especially + handy when multiple features are simultaneously enabled in adoption mode. + +## Source compatibility + +This proposal does not affect language rules. The described changes to the API +surface are source-compatible. + +## ABI compatibility + +This proposal does not affect binary compatibility or binary interfaces. + +## Implications on adoption + +Demoting an enabled source-breaking feature to adoption mode may affect +behavior and is therefore a potentially source-breaking action. + +## Future directions + +### Augment diagnostic metadata + + + +### Support baseline features + +Adoption mode can be extrapolated to baseline features, such as `TypedThrows` +or [opaque parameter types][SE-0341], with an emphasis on actionable adoption +tips and otherwise unsolicited educational notes. +These additive features are hard-enabled in all language modes and become an +integral part of the language as soon as they ship. +Baseline feature identifiers are currently kept around for the sole purpose of +supporting [feature availability checks][feature-detection] in conditional +compilation blocks. + +### `swift adopt` + +The Swift package manager could implement an `adopt` subcommand with an +interactive command line interface similar to `git add --patch` for selecting +and applying fix-its ... + +## Alternatives considered + +### Naming + + + +## Acknowledgements + +This proposal was inspired by documents prepared by [Allan Shortlidge][Allan] +and [Holly Borla][Holly]. +Special thanks to Holly for her feedback throughout the draft stage. + + + +[Holly]: https://github.com/hborla +[Allan]: https://github.com/tshortli + +[SE-0192]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0192-non-exhaustive-enums.md +[SE-0274]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0274-magic-file.md +[SE-0286]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0286-forward-scan-trailing-closures.md +[SE-0296]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0296-async-await.md +[SE-0335]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0335-existential-any.md +[SE-0337]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0337-support-incremental-migration-to-concurrency-checking.md +[SE-0341]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0341-opaque-parameters.md +[SE-0352]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md +[SE-0354]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0354-regex-literals.md +[SE-0362]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0362-piecemeal-future-features.md +[feature-detection]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0362-piecemeal-future-features.md#feature-detection-in-source-code +[SE-0383]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0383-deprecate-uiapplicationmain-and-nsapplicationmain.md +[SE-0401]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0401-remove-property-wrapper-isolation.md +[SE-0409]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md +[SE-0411]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0411-isolated-default-values.md +[SE-0412]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0412-strict-concurrency-for-global-variables.md +[SE-0418]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0418-inferring-sendable-for-methods.md +[SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md +[async-inherit-isolation-pitch]: https://forums.swift.org/t/pitch-inherit-isolation-by-default-for-async-functions/74862 From dafb468cba8eee563e65860151211efffc5eb165 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Fri, 14 Feb 2025 21:36:14 +0000 Subject: [PATCH 02/16] burp --- proposals/NNNN-migration-tooling-for-upcoming-features.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index 47097ba859..67da10cf4f 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -24,12 +24,12 @@ language mode explicitly. Once the time is right, old language modes together with the legacy behaviors they manifest will be proposed to be deprecated. -The cumulative source compatibility impact of the changes that were accreting -around a converging Swift 6 language mode gave rise to the +In Swift 5.8, the cumulative source compatibility impact of a still converging +Swift 6 language mode gave rise to the [Swift feature model][SE-0362], which enabled piecemeal adoption of individual features as opposed to an entire language mode. -Upcoming features facilitated sooner adoption of improvements and drastically -reduced the pressures in our evolutionary model. +Among other things, upcoming features facilitated earlier adoption of +improvements and drastically reduced the pressures in our evolutionary model. This proposal centers seeks to improve the experience of adopting individual features. From a7ea7aed14bf4f7612f762020973c3d79988f2cd Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Fri, 14 Feb 2025 22:15:04 +0000 Subject: [PATCH 03/16] burp --- proposals/NNNN-migration-tooling-for-upcoming-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index 67da10cf4f..d748799ab7 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -62,7 +62,7 @@ development and focus on other important tasks. ### Automation Many existing and prospective upcoming features imply or implement simple and -consistent code modifications to facilitate the adoption process: +consistent code modifications to facilitate adoption processes: * [`NonfrozenEnumExhaustivity`][SE-0192]: Restore exhaustivity with `@unknown default:`. From 80fa27863bf2dd33eeb591b0317ee96a4198b354 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Fri, 14 Feb 2025 22:41:05 +0000 Subject: [PATCH 04/16] burp --- ...NNNN-migration-tooling-for-upcoming-features.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index d748799ab7..becd83f9b3 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -15,7 +15,7 @@ expanding domains. Source-breaking changes to Swift were first staged behind the now obsolete Swift 3 language mode. -Each successive major release has since included a correponding language mode, +Each successive major release has since included a corresponding language mode, using the previous language mode as the default to maximize source compatibility. For example, Swift 6 compilers operate in the Swift 5 language mode by default. @@ -31,7 +31,7 @@ features as opposed to an entire language mode. Among other things, upcoming features facilitated earlier adoption of improvements and drastically reduced the pressures in our evolutionary model. -This proposal centers seeks to improve the experience of adopting individual +This proposal seeks to improve the experience of adopting individual features. The proposition is that the growing complexity and diversification of Swift calls for a flexible, integrated mechanism for supporting quality assistance @@ -89,8 +89,6 @@ consistent code modifications to facilitate adoption processes: * [Inherit isolation by default for async functions][async-inherit-isolation-pitch]: Mark nonisolated functions with the proposed attribute. -Feature - Extending diagnostic metadata to include information that allows for recognizing these diagnostics and distinguishing semantics-preserving fix-its from alternative source changes would open up numerous opportunities for @@ -124,7 +122,7 @@ UPCOMING_FEATURE(RegionBasedIsolation, 414, 6) ## Proposed solution -Introduce the notion of a "adoption" mode for individual experimental and +Introduce the notion of an "adoption" mode for individual experimental and upcoming features. The core idea behind adoption mode is a declaration of intent that can be leveraged to build holistic supportive adoption experiences for developers. @@ -142,6 +140,9 @@ existing code whenever the feature provides for them. ### Behavior +Adoption mode should deliver guidance in the shape of warnings, notes, remarks, +and fix-its, as and when appropriate. + The action of enabling a previously disabled source-breaking feature in adoption mode per se must never produce compilation errors. Additionally, this action will have no effect on the state of the feature if @@ -153,9 +154,6 @@ impression that the impacted source code is compatible with the feature. > Experimental features can be both additive and source-breaking. > Upcoming features are necessarily source-breaking. -adoption mode will deliver guidance in the shape of warnings, notes, remarks, -and fix-its, as and when appropriate. - When implemented, adoption mode for upcoming features is expected to anticipate and call out any behavioral differences that will result from enacting the feature, coupling diagnostic messages with counteracting source-compatible From 8707bf78f6e11d029948ad880e8a6971c8bacd0d Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Fri, 14 Feb 2025 19:11:51 -0800 Subject: [PATCH 05/16] Editorial pass over the introduction section. --- ...migration-tooling-for-upcoming-features.md | 39 +++++-------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index becd83f9b3..32e254c6a9 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -9,35 +9,16 @@ ## Introduction -The future we envision for Swift will take many more valiant evolutionary -decisions and major transformations with a proportional impact on its -expanding domains. - -Source-breaking changes to Swift were first staged behind the now obsolete -Swift 3 language mode. -Each successive major release has since included a corresponding language mode, -using the previous language mode as the default to maximize source -compatibility. -For example, Swift 6 compilers operate in the Swift 5 language mode by default. -Users that are not ready to adopt the new default can still specify an earlier -language mode explicitly. -Once the time is right, old language modes together with the legacy behaviors -they manifest will be proposed to be deprecated. - -In Swift 5.8, the cumulative source compatibility impact of a still converging -Swift 6 language mode gave rise to the -[Swift feature model][SE-0362], which enabled piecemeal adoption of individual -features as opposed to an entire language mode. -Among other things, upcoming features facilitated earlier adoption of -improvements and drastically reduced the pressures in our evolutionary model. - -This proposal seeks to improve the experience of adopting individual -features. -The proposition is that the growing complexity and diversification of Swift -calls for a flexible, integrated mechanism for supporting quality assistance -with feature adoption. -And that — in principle — comprehensive, code-aware assistance can be delivered -without breaking source and acted upon incrementally. +In Swift 5.8 introduced [upcoming features][SE-0362], +which enabled piecemeal adoption of individual source incompatible +changes that are enabled by default in a new langauge mode. +Many upcoming features have a mechanical migration, meaning the compiler can +determine the exact source changes necessary to allow the code to compile under +the upcoming feature while preserving the behavior of the code. +This proposal seeks to improve the experience of enabling individual +upcoming features by providing tools that produce the necessary source code +changes automatically for a given set of upcoming features that a programmer +wants to enable. ## Motivation From 593a0699ef6589cae292223221f416060c5b8756 Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Fri, 14 Feb 2025 20:03:42 -0800 Subject: [PATCH 06/16] Editorial pass over the automation section. --- ...migration-tooling-for-upcoming-features.md | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index 32e254c6a9..b816352c52 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -77,29 +77,14 @@ higher-level tools — ranging from the Swift package manager to IDEs — to implement powerful solutions for organizing, automating, and tuning code migration processes. -### Flexibility/Ergonomics +It's not always feasible for an upcoming feature to have a mechanical +migration path. For example, the following upcoming features require manual +migration: -> [!CAUTION] -> Still a draft. - -Although upcoming features should strive to facilitate code migration, - -language design principles may prevail over bespoke code migration solutions. -Some features, like [StrictConcurrency][SE-0337], inherently require user -intervetion - -Adjusting to new behaviors or language requirements can demand research, -careful consideration, coordinated efforts, and manual code refactorings, -sometimes on a case-by-case basis. - -Currently best solution is to implement custom staging solutions. This approach -has limited applications (why?). - -UPCOMING_FEATURE(DynamicActorIsolation, 423, 6) -UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6) -UPCOMING_FEATURE(StrictConcurrency, 0337, 6) -UPCOMING_FEATURE(IsolatedDefaultValues, 411, 6) -UPCOMING_FEATURE(RegionBasedIsolation, 414, 6) +* [`DynamicActorIsolation`][SE-0423] +* [`GlobalActorIsolatedTypesUsability`][SE-0434] +* [`StrictConcurrency`][SE-0337] +* [`IsolatedDefaultValues`][SE-0411] ## Proposed solution @@ -310,5 +295,7 @@ Special thanks to Holly for her feedback throughout the draft stage. [SE-0411]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0411-isolated-default-values.md [SE-0412]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0412-strict-concurrency-for-global-variables.md [SE-0418]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0418-inferring-sendable-for-methods.md +[SE-0423]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0423-dynamic-actor-isolation.md +[SE-0434]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0434-global-actor-isolated-types-usability.md [SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md [async-inherit-isolation-pitch]: https://forums.swift.org/t/pitch-inherit-isolation-by-default-for-async-functions/74862 From 78fd5a2efb32b36df133c8112fffc683387b20b3 Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Fri, 14 Feb 2025 20:08:45 -0800 Subject: [PATCH 07/16] Clarify that future proposals introducing upcoming features should include a migration. --- proposals/NNNN-migration-tooling-for-upcoming-features.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index b816352c52..7cd343e56f 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -98,9 +98,11 @@ An immediate benefit of adoption mode is the capability to deliver source modifications that can be applied to preserve or improve the behavior of existing code whenever the feature provides for them. -> [!NOTE] -> The subject of this proposal is an enhancement to the Swift feature model. -> Applications of adoption mode to existing features are beyond its scope. +This proposal will support the set of existing upcoming features that +have mechanical migrations, as described in the [Automation](#automation) +section. All future proposals that introduce new upcoming features should +include a mechanical migration via adoption mode in the Source compatibility +section of the proposal. ## Detailed design From 9bedf553f2806c6dbd764ed9b06a9de6dfe74a9c Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Mon, 17 Feb 2025 09:40:32 +0000 Subject: [PATCH 08/16] burp 0.9 --- ...migration-tooling-for-upcoming-features.md | 184 ++++++++++-------- 1 file changed, 106 insertions(+), 78 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index 7cd343e56f..d049330244 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -10,40 +10,48 @@ ## Introduction In Swift 5.8 introduced [upcoming features][SE-0362], -which enabled piecemeal adoption of individual source incompatible -changes that are enabled by default in a new langauge mode. +which enabled piecemeal adoption of individual source-incompatible changes that +are included in a language mode. Many upcoming features have a mechanical migration, meaning the compiler can -determine the exact source changes necessary to allow the code to compile under +determine the exact source changes necessary to allow the code to compile under the upcoming feature while preserving the behavior of the code. This proposal seeks to improve the experience of enabling individual -upcoming features by providing tools that produce the necessary source code -changes automatically for a given set of upcoming features that a programmer -wants to enable. +upcoming features by providing a mechanism for producing the necessary source +code changes automatically for a given set of upcoming features that a +programmer wants to enable. ## Motivation -Whether you are adjusting code to follow new language rules or researching ways -to apply new functionality, adopting features can be a time-consuming endeavor -at the least. - -Some source-breaking language features are anticipated to generate hundreds -of targeted errors in sizable projects. -Occasionally, errors will also cascade down the dependecy graph or fall out -from changes in behavior without a clear indication of the precise cause or source of -the issue, requiring further investigation. -Developers are left to either resolve all of these errors or address a subset -and take the risk of switching the feature back off before they can resume -development and focus on other important tasks. - -### User Intent - -> [!CAUTION] -> TODO: No way for users to declare an intetion to adopt a feature +Adopting certain features is a time-consuming endeavor at the least. +It is the responsibility of project maintainers to preserve source (and binary) +compatibility both internally and externally for library clients when enabling +an upcoming feature, which can be difficult or tedious without having tools to +help detect possibly inadvertent changes and perform monotonous migration +shenanigans for you. +*Our* responsibility is to make that an easier task for everybody. + +### User intent + +A primary limiting factor in how proactively and accurately the compiler can +assist developers with adopting a feature is a lack of comprehension of user +intent. +Is the developer expecting guidance on adopting an improvement? +All the compiler knows to do when a feature is enabled is to compile code +accordingly. +This suffices if a feature merely supplants an existing syntactical construct +or changes the behavior of existing code in strictly predictable ways because +Swift can infer the need to suggest a fix just from spotting certain code +patterns. + +Needless to say, not all upcoming features fall under these criteria (and not +all features are source-breaking in the first place). Consider +[`ConciseMagicFile`][SE-0274], which changes the meaning of an existing +literal. ### Automation Many existing and prospective upcoming features imply or implement simple and -consistent code modifications to facilitate adoption processes: +consistent source modifications to facilitate adoption: * [`NonfrozenEnumExhaustivity`][SE-0192]: Restore exhaustivity with `@unknown default:`. @@ -72,14 +80,15 @@ consistent code modifications to facilitate adoption processes: Extending diagnostic metadata to include information that allows for recognizing these diagnostics and distinguishing semantics-preserving fix-its -from alternative source changes would open up numerous opportunities for +from alternative source changes will open up numerous opportunities for higher-level tools — ranging from the Swift package manager to IDEs — to -implement powerful solutions for organizing, automating, and tuning code -migration processes. +implement powerful solutions for organizing, automating, and tuning feature +adoption processes. -It's not always feasible for an upcoming feature to have a mechanical -migration path. For example, the following upcoming features require manual -migration: +It is not always feasible or in line with language design principles for an +upcoming feature to have a mechanical migration path. +For example, the following upcoming features require manual migration to +preserve semantics: * [`DynamicActorIsolation`][SE-0423] * [`GlobalActorIsolatedTypesUsability`][SE-0434] @@ -91,7 +100,7 @@ migration: Introduce the notion of an "adoption" mode for individual experimental and upcoming features. The core idea behind adoption mode is a declaration of intent that can be -leveraged to build holistic supportive adoption experiences for developers. +leveraged to build better supportive adoption experiences for developers. If enabling a feature communicates an intent to *enact* rules, adoption mode communicates an intent to *adopt* them. An immediate benefit of adoption mode is the capability to deliver source @@ -100,21 +109,18 @@ existing code whenever the feature provides for them. This proposal will support the set of existing upcoming features that have mechanical migrations, as described in the [Automation](#automation) -section. All future proposals that introduce new upcoming features should -include a mechanical migration via adoption mode in the Source compatibility -section of the proposal. +section. +All future proposals that introduce a new upcoming feature and provide a +mechanical migration are expected to support adoption mode and detail its +behavior in the *Source compatibility* section of the proposal. ## Detailed design ### Behavior -Adoption mode should deliver guidance in the shape of warnings, notes, remarks, -and fix-its, as and when appropriate. - The action of enabling a previously disabled source-breaking feature in adoption -mode per se must never produce compilation errors. -Additionally, this action will have no effect on the state of the feature if -it does not implement the mode. +mode per se must not cause compilation errors . +Additionally, this action will have no effect if the mode is not supported. A corresponding warning will be emitted in this case to avoid the false impression that the impacted source code is compatible with the feature. @@ -122,15 +128,24 @@ impression that the impacted source code is compatible with the feature. > Experimental features can be both additive and source-breaking. > Upcoming features are necessarily source-breaking. -When implemented, adoption mode for upcoming features is expected to anticipate -and call out any behavioral differences that will result from enacting the -feature, coupling diagnostic messages with counteracting source-compatible -changes and helpful alternatives whenever possible. -Adoption mode cannot guarantee to provide exclusively source-compatible -modifications because the impact of a change on dependent source code is -generally unpredictable. -Neither can it promise to always offer fix-its in the first place for the -same reason in regards to user intention. +Adoption mode should deliver guidance in the shape of regular diagnostics. +For arbitrary upcoming features, adoption mode is expected to anticipate and +call out any compatibility issues that result from enacting the feature, +coupling diagnostic messages with counteracting compatible changes and helpful +alternatives whenever feasible. +Compatibility issues encompass both source and binary compatibility issues, +including behavioral changes. + +Note that adoption mode does not provide any new general guarantees in respect +to fix-its. +We cannot promise to offer exclusively compatible modifications. +Besides the impact of a change on dependent source code being generally +unpredictable, it can be reasonable to couple compatible fix-its with +potentially incompatible, albeit better, alternatives, as in `any P` → `some P`. +The same stands for provision of modifications — features might not have a +mechanical migration path, and the compiler remains inherently limited in the +extent to which it can make assumptions about what is helpful or best for the +programmer. ### Interface @@ -217,14 +232,10 @@ SwiftSetting.enableUpcomingFeature("InternalImportsByDefault", mode: .adoption) ### Diagnostics Diagnostics emitted in relation to a specific feature in adoption mode must -belong to a diagnostic group named after the feature. -There are several reasons why this will be useful: -* Future feature-oriented adoption tooling can use the group identifier to - filter out relevant diagnostics. -* IDEs and other diagnostic consumers can integrate group identifiers into - their interfaces to, well, group diagnostics, as well as to communicate - relationships between diagnostics and features. This can prove especially - handy when multiple features are simultaneously enabled in adoption mode. +belong to a diagnostic group named after the feature. The names of diagnostic +groups can be displayed along with diagnostic messages using +`-print-diagnostic-groups` and can be used to associate a message with a +particular feature. ## Source compatibility @@ -237,43 +248,59 @@ This proposal does not affect binary compatibility or binary interfaces. ## Implications on adoption -Demoting an enabled source-breaking feature to adoption mode may affect -behavior and is therefore a potentially source-breaking action. +Entering or exiting adoption mode may affect behavior and is therefore a +potentially source-breaking action. ## Future directions -### Augment diagnostic metadata - - - -### Support baseline features - -Adoption mode can be extrapolated to baseline features, such as `TypedThrows` -or [opaque parameter types][SE-0341], with an emphasis on actionable adoption -tips and otherwise unsolicited educational notes. -These additive features are hard-enabled in all language modes and become an -integral part of the language as soon as they ship. -Baseline feature identifiers are currently kept around for the sole purpose of -supporting [feature availability checks][feature-detection] in conditional -compilation blocks. +### Applications beyond migration + +Adoption mode can be extrapolated to additive features, such as +[typed `throws`][SE-0413] or [opaque parameter types][SE-0341], by providing +actionable adoption tips. +Additive features are hard-enabled and become an integral part of the language +as soon as they ship. +Many recent additive features are already integrated into the Swift feature +model and kept around for the sole purpose of supporting +[feature availability checks][feature-detection] in conditional compilation +blocks. + +Another potential direction for adoption mode is promotion of best practices. + +### Augmented diagnostic metadata + +The current serialization format for diagnostics does not include information +about diagnostic groups or whether a particular fix-it preserves semantics. +There are several reasons why this data is essential for future tools built +around adoption mode: +* The diagnostic group name can be used to, well, group diagnostics, as well as + to communicate relationships between diagnostics and features and filter out + relevant diagnostics. + This can prove especially handy when multiple features are simultaneously + enabled in adoption mode, or when similar diagnostic messages are caused by + distinct features. +* Fix-its that preserve semantics can be prioritized and auto-applied in + previews. ### `swift adopt` -The Swift package manager could implement an `adopt` subcommand with an -interactive command line interface similar to `git add --patch` for selecting -and applying fix-its ... +The Swift package manager could implement an `adopt` subcommand for interactive +review and application of adoption mode output for a given set of features, +with a command line interface similar to `git add --patch`. ## Alternatives considered ### Naming - +Perhaps the most intuitive alternative to "adoption" is "migration". We +settled on the former because there is no reason for this concept to be limited +to upcoming features or migrational changes. ## Acknowledgements This proposal was inspired by documents prepared by [Allan Shortlidge][Allan] and [Holly Borla][Holly]. -Special thanks to Holly for her feedback throughout the draft stage. +Special thanks to Holly for her guidance throughout the draft stage. @@ -295,6 +322,7 @@ Special thanks to Holly for her feedback throughout the draft stage. [SE-0401]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0401-remove-property-wrapper-isolation.md [SE-0409]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md [SE-0411]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0411-isolated-default-values.md +[SE-0413]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0413-typed-throws.md [SE-0412]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0412-strict-concurrency-for-global-variables.md [SE-0418]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0418-inferring-sendable-for-methods.md [SE-0423]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0423-dynamic-actor-isolation.md From 2c604947334c12e5e1fe20219dd09ab675151b46 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Mon, 17 Feb 2025 18:54:36 +0000 Subject: [PATCH 09/16] burp 0.10 --- ...NNN-migration-tooling-for-upcoming-features.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index d049330244..d922d37bbc 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -50,8 +50,8 @@ literal. ### Automation -Many existing and prospective upcoming features imply or implement simple and -consistent source modifications to facilitate adoption: +Many existing and prospective upcoming features come with simple and reliable +migration paths to facilitate adoption: * [`NonfrozenEnumExhaustivity`][SE-0192]: Restore exhaustivity with `@unknown default:`. @@ -119,7 +119,7 @@ behavior in the *Source compatibility* section of the proposal. ### Behavior The action of enabling a previously disabled source-breaking feature in adoption -mode per se must not cause compilation errors . +mode per se must not cause compilation errors. Additionally, this action will have no effect if the mode is not supported. A corresponding warning will be emitted in this case to avoid the false impression that the impacted source code is compatible with the feature. @@ -233,9 +233,8 @@ SwiftSetting.enableUpcomingFeature("InternalImportsByDefault", mode: .adoption) Diagnostics emitted in relation to a specific feature in adoption mode must belong to a diagnostic group named after the feature. The names of diagnostic -groups can be displayed along with diagnostic messages using -`-print-diagnostic-groups` and can be used to associate a message with a -particular feature. +groups can be displayed alongside diagnostic messages using +`-print-diagnostic-groups` and used to associate messages with features. ## Source compatibility @@ -271,8 +270,8 @@ Another potential direction for adoption mode is promotion of best practices. The current serialization format for diagnostics does not include information about diagnostic groups or whether a particular fix-it preserves semantics. -There are several reasons why this data is essential for future tools built -around adoption mode: +There are several reasons why this data can be valuable for users, and why it +is essential for future tools built around adoption mode: * The diagnostic group name can be used to, well, group diagnostics, as well as to communicate relationships between diagnostics and features and filter out relevant diagnostics. From 18300668513e01b4d1e35d5d9094de8299a847ca Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Mon, 17 Feb 2025 12:29:11 -0800 Subject: [PATCH 10/16] Use `DisableOutwardActorInference` in the example for the "User intent" section. --- ...NN-migration-tooling-for-upcoming-features.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index d922d37bbc..0b873eeeb9 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -45,8 +45,19 @@ patterns. Needless to say, not all upcoming features fall under these criteria (and not all features are source-breaking in the first place). Consider -[`ConciseMagicFile`][SE-0274], which changes the meaning of an existing -literal. +[`DisableOutwardActorInference`][SE-0401], which changes actor isolation +inference of a type that contains an actor-isolated property wrapper. There +is no way for the programmer to specify that they'd like compiler fix-its to +make the existing actor isolation inference explicit. If they enable the +upcoming feature, their code will simply behave differently. This was a +point of debate in the review of SE-0401, and the Language Steering Group +concluded that automatic migration tooling is the right way to address this +particular workflow, as [noted in the acceptance notes][SE-0401-acceptance: + +> the Language Steering Group believes that separate migration tooling to +> help programmers audit code whose behavior will change under Swift 6 mode +> would be beneficial for all upcoming features that can change behavior +> without necessarily emitting errors. ### Automation @@ -328,3 +339,4 @@ Special thanks to Holly for her guidance throughout the draft stage. [SE-0434]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0434-global-actor-isolated-types-usability.md [SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md [async-inherit-isolation-pitch]: https://forums.swift.org/t/pitch-inherit-isolation-by-default-for-async-functions/74862 +[SE-0401-acceptance]: https://forums.swift.org/t/accepted-with-modifications-se-0401-remove-actor-isolation-inference-caused-by-property-wrappers/66241 From 7d62c544c66c21f55202c95e4751fe16c1a01961 Mon Sep 17 00:00:00 2001 From: Holly Borla Date: Mon, 17 Feb 2025 12:39:55 -0800 Subject: [PATCH 11/16] Move source incompatible changes to Future directions. --- ...migration-tooling-for-upcoming-features.md | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-migration-tooling-for-upcoming-features.md index 0b873eeeb9..8e1f49c734 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-migration-tooling-for-upcoming-features.md @@ -52,7 +52,7 @@ make the existing actor isolation inference explicit. If they enable the upcoming feature, their code will simply behave differently. This was a point of debate in the review of SE-0401, and the Language Steering Group concluded that automatic migration tooling is the right way to address this -particular workflow, as [noted in the acceptance notes][SE-0401-acceptance: +particular workflow, as [noted in the acceptance notes][SE-0401-acceptance]: > the Language Steering Group believes that separate migration tooling to > help programmers audit code whose behavior will change under Swift 6 mode @@ -127,18 +127,19 @@ behavior in the *Source compatibility* section of the proposal. ## Detailed design -### Behavior +Upcoming features that have mechanical migrations will support an adoption +mode, which is a a new mode of building a project that will produce compiler +warnings with attached fix-its that can be applied to preserve the behavior +of the code when the upcoming feature is enabled. Adoption mode must not +cause any new compiler errors, and the fix-its produced must preserve the +source compatibility and behavior of the code. -The action of enabling a previously disabled source-breaking feature in adoption -mode per se must not cause compilation errors. -Additionally, this action will have no effect if the mode is not supported. +Additionally, this action will have no effect if the mode is not supported +for a given upcoming feature, i,e. because the upcoming feature does not +have a mechanical migration. A corresponding warning will be emitted in this case to avoid the false impression that the impacted source code is compatible with the feature. -> [!NOTE] -> Experimental features can be both additive and source-breaking. -> Upcoming features are necessarily source-breaking. - Adoption mode should deliver guidance in the shape of regular diagnostics. For arbitrary upcoming features, adoption mode is expected to anticipate and call out any compatibility issues that result from enacting the feature, @@ -147,17 +148,6 @@ alternatives whenever feasible. Compatibility issues encompass both source and binary compatibility issues, including behavioral changes. -Note that adoption mode does not provide any new general guarantees in respect -to fix-its. -We cannot promise to offer exclusively compatible modifications. -Besides the impact of a change on dependent source code being generally -unpredictable, it can be reasonable to couple compatible fix-its with -potentially incompatible, albeit better, alternatives, as in `any P` → `some P`. -The same stands for provision of modifications — features might not have a -mechanical migration path, and the compiler remains inherently limited in the -extent to which it can make assumptions about what is helpful or best for the -programmer. - ### Interface #### Compiler @@ -263,6 +253,15 @@ potentially source-breaking action. ## Future directions +### Producing source incompatible fix-its + +For some upcoming features, a source change which alters the semantics of +the program is a more desirable approach to addressing an error that comes +from enabling an upcoming feature. For example, programmers might want to +replace cases of `any P` with `some P`. Adoption tooling could support the +option to produce source incompatible fix-its in cases where the compiler +can detect that a different behavior might be more beneficial. + ### Applications beyond migration Adoption mode can be extrapolated to additive features, such as From 036815c53d796212eb25a53b328c35eb7bf6242c Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Mon, 17 Feb 2025 23:00:47 +0000 Subject: [PATCH 12/16] burp 1.0 --- ...NN-adoption-tooling-for-swift-features.md} | 157 ++++++++---------- 1 file changed, 70 insertions(+), 87 deletions(-) rename proposals/{NNNN-migration-tooling-for-upcoming-features.md => NNNN-adoption-tooling-for-swift-features.md} (67%) diff --git a/proposals/NNNN-migration-tooling-for-upcoming-features.md b/proposals/NNNN-adoption-tooling-for-swift-features.md similarity index 67% rename from proposals/NNNN-migration-tooling-for-upcoming-features.md rename to proposals/NNNN-adoption-tooling-for-swift-features.md index 8e1f49c734..c51aa9b38d 100644 --- a/proposals/NNNN-migration-tooling-for-upcoming-features.md +++ b/proposals/NNNN-adoption-tooling-for-swift-features.md @@ -9,25 +9,23 @@ ## Introduction -In Swift 5.8 introduced [upcoming features][SE-0362], -which enabled piecemeal adoption of individual source-incompatible changes that -are included in a language mode. +Swift 5.8 introduced [upcoming features][SE-0362], which enabled piecemeal +adoption of individual source-incompatible changes that are included in a +language mode. Many upcoming features have a mechanical migration, meaning the compiler can determine the exact source changes necessary to allow the code to compile under the upcoming feature while preserving the behavior of the code. -This proposal seeks to improve the experience of enabling individual -upcoming features by providing a mechanism for producing the necessary source -code changes automatically for a given set of upcoming features that a -programmer wants to enable. +This proposal seeks to improve the experience of enabling individual Swift +features by providing an integrated mechanism for producing these source code +modifications automatically. ## Motivation -Adopting certain features is a time-consuming endeavor at the least. It is the responsibility of project maintainers to preserve source (and binary) -compatibility both internally and externally for library clients when enabling -an upcoming feature, which can be difficult or tedious without having tools to -help detect possibly inadvertent changes and perform monotonous migration -shenanigans for you. +compatibility both internally and for library clients when enabling an upcoming +feature, which can be difficult or tedious without having tools to help detect +possibly inadvertent changes or perform monotonous migration shenanigans for +you. *Our* responsibility is to make that an easier task for everybody. ### User intent @@ -38,21 +36,22 @@ intent. Is the developer expecting guidance on adopting an improvement? All the compiler knows to do when a feature is enabled is to compile code accordingly. -This suffices if a feature merely supplants an existing syntactical construct -or changes the behavior of existing code in strictly predictable ways because -Swift can infer the need to suggest a fix just from spotting certain code -patterns. +If an upcoming feature supplants an existing grammatical construct or +invalidates an existing behavior, the language rules alone suffice because +Swift can consistently infer the irrefutable need to diagnose certain code +patterns just by spotting them. Needless to say, not all upcoming features fall under these criteria (and not -all features are source-breaking in the first place). Consider -[`DisableOutwardActorInference`][SE-0401], which changes actor isolation -inference of a type that contains an actor-isolated property wrapper. There -is no way for the programmer to specify that they'd like compiler fix-its to -make the existing actor isolation inference explicit. If they enable the -upcoming feature, their code will simply behave differently. This was a -point of debate in the review of SE-0401, and the Language Steering Group -concluded that automatic migration tooling is the right way to address this -particular workflow, as [noted in the acceptance notes][SE-0401-acceptance]: +all features are source-breaking in the first place). +Consider [`DisableOutwardActorInference`][SE-0401], which changes actor +isolation inference rules with respect to wrapped properties. +There is no way for the programmer to specify that they'd like compiler fix-its +to make the existing actor isolation inference explicit. +If they enable the upcoming feature, their code will simply behave differently. +This was a point of debate in the review of [SE-0401], and the Language +Steering Group concluded that automatic migration tooling is the right way to +address this particular workflow, as +[noted in the acceptance notes][SE-0401-acceptance]: > the Language Steering Group believes that separate migration tooling to > help programmers audit code whose behavior will change under Swift 6 mode @@ -61,7 +60,7 @@ particular workflow, as [noted in the acceptance notes][SE-0401-acceptance]: ### Automation -Many existing and prospective upcoming features come with simple and reliable +Many existing and prospective upcoming features account for simple and reliable migration paths to facilitate adoption: * [`NonfrozenEnumExhaustivity`][SE-0192]: Restore exhaustivity with @@ -79,32 +78,17 @@ migration paths to facilitate adoption: * [`DisableOutwardActorInference`][SE-0401]: Specify global actor isolation explicitly. * [`InternalImportsByDefault`][SE-0409]: `import X` → `public import X`. -* [`GlobalConcurrency`][SE-0412]: - - Convert the global variable to a `let` (or) - - `@MainActor`-isolate it (or) - - Mark it with `nonisolated(unsafe)` +* [`GlobalConcurrency`][SE-0412]: Convert the global variable to a `let`, or + `@MainActor`-isolate it, or mark it with `nonisolated(unsafe)`. * [`MemberImportVisibility`][SE-0444]: Add explicit imports appropriately. * [`InferSendableFromCaptures`][SE-0418]: Suppress inference with coercions and type annotations. * [Inherit isolation by default for async functions][async-inherit-isolation-pitch]: Mark nonisolated functions with the proposed attribute. -Extending diagnostic metadata to include information that allows for -recognizing these diagnostics and distinguishing semantics-preserving fix-its -from alternative source changes will open up numerous opportunities for -higher-level tools — ranging from the Swift package manager to IDEs — to -implement powerful solutions for organizing, automating, and tuning feature -adoption processes. - -It is not always feasible or in line with language design principles for an -upcoming feature to have a mechanical migration path. -For example, the following upcoming features require manual migration to -preserve semantics: - -* [`DynamicActorIsolation`][SE-0423] -* [`GlobalActorIsolatedTypesUsability`][SE-0434] -* [`StrictConcurrency`][SE-0337] -* [`IsolatedDefaultValues`][SE-0411] +Application of these adjustments can be fully automated in favor of preserving +behavior, saving time for more important tasks, such as identifying, auditing, +and testing code where a change in behavior is preferable. ## Proposed solution @@ -115,39 +99,35 @@ leveraged to build better supportive adoption experiences for developers. If enabling a feature communicates an intent to *enact* rules, adoption mode communicates an intent to *adopt* them. An immediate benefit of adoption mode is the capability to deliver source -modifications that can be applied to preserve or improve the behavior of -existing code whenever the feature provides for them. +modifications that can be applied to preserve compatibility whenever a feature +provides for them. This proposal will support the set of existing upcoming features that have mechanical migrations, as described in the [Automation](#automation) section. -All future proposals that introduce a new upcoming feature and provide a -mechanical migration are expected to support adoption mode and detail its -behavior in the *Source compatibility* section of the proposal. +All future proposals that intend to introduce an upcoming feature and +provide for a mechanical migration should include an adoption mode and detail +its behavior alongside the migration paths in the *Source compatibility* +section. ## Detailed design Upcoming features that have mechanical migrations will support an adoption -mode, which is a a new mode of building a project that will produce compiler +mode, which is a new mode of building a project that will produce compiler warnings with attached fix-its that can be applied to preserve the behavior -of the code when the upcoming feature is enabled. Adoption mode must not -cause any new compiler errors, and the fix-its produced must preserve the -source compatibility and behavior of the code. +of the code once the upcoming feature is enacted. +The action of enabling a previously disabled upcoming feature in adoption +mode must not cause any new compiler errors or behavioral changes, and the +fix-its produced must preserve compatibility. +Compatibility here refers to both source and binary compatibility, as well as +to behavior. Additionally, this action will have no effect if the mode is not supported -for a given upcoming feature, i,e. because the upcoming feature does not +for a given upcoming feature, i.e., because the upcoming feature does not have a mechanical migration. A corresponding warning will be emitted in this case to avoid the false impression that the impacted source code is compatible with the feature. -Adoption mode should deliver guidance in the shape of regular diagnostics. -For arbitrary upcoming features, adoption mode is expected to anticipate and -call out any compatibility issues that result from enacting the feature, -coupling diagnostic messages with counteracting compatible changes and helpful -alternatives whenever feasible. -Compatibility issues encompass both source and binary compatibility issues, -including behavioral changes. - ### Interface #### Compiler @@ -233,14 +213,14 @@ SwiftSetting.enableUpcomingFeature("InternalImportsByDefault", mode: .adoption) ### Diagnostics Diagnostics emitted in relation to a specific feature in adoption mode must -belong to a diagnostic group named after the feature. The names of diagnostic -groups can be displayed alongside diagnostic messages using -`-print-diagnostic-groups` and used to associate messages with features. +belong to a diagnostic group named after the feature. +The names of diagnostic groups can be displayed alongside diagnostic messages +using `-print-diagnostic-groups` and used to associate messages with features. ## Source compatibility -This proposal does not affect language rules. The described changes to the API -surface are source-compatible. +This proposal does not affect language rules. +The described changes to the API surface are source-compatible. ## ABI compatibility @@ -248,21 +228,22 @@ This proposal does not affect binary compatibility or binary interfaces. ## Implications on adoption -Entering or exiting adoption mode may affect behavior and is therefore a +Entering or exiting adoption mode will affect behavior and is therefore a potentially source-breaking action. ## Future directions ### Producing source incompatible fix-its -For some upcoming features, a source change which alters the semantics of +For some features, a source change that alters the semantics of the program is a more desirable approach to addressing an error that comes -from enabling an upcoming feature. For example, programmers might want to -replace cases of `any P` with `some P`. Adoption tooling could support the -option to produce source incompatible fix-its in cases where the compiler -can detect that a different behavior might be more beneficial. +from enabling the feature. +For example, programmers might want to replace cases of `any P` with `some P`. +Adoption tooling could support the option to produce source incompatible +fix-its in cases where the compiler can detect that a different behavior might +be more beneficial. -### Applications beyond migration +### Applications beyond mechanical migration Adoption mode can be extrapolated to additive features, such as [typed `throws`][SE-0413] or [opaque parameter types][SE-0341], by providing @@ -270,9 +251,9 @@ actionable adoption tips. Additive features are hard-enabled and become an integral part of the language as soon as they ship. Many recent additive features are already integrated into the Swift feature -model and kept around for the sole purpose of supporting -[feature availability checks][feature-detection] in conditional compilation -blocks. +model, and their metadata is kept around either to support +[feature availability checks][SE-0362-feature-detection] in conditional +compilation blocks or because they started off as experimental features. Another potential direction for adoption mode is promotion of best practices. @@ -288,22 +269,24 @@ is essential for future tools built around adoption mode: This can prove especially handy when multiple features are simultaneously enabled in adoption mode, or when similar diagnostic messages are caused by distinct features. -* Fix-its that preserve semantics can be prioritized and auto-applied in - previews. +* Exposing the purpose of a fix-it can help developers make quicker decisions + when offered multiple fix-its. + Furthermore, tools can take advantage of this information by favoring and + auto-applying source-compatible fix-its. ### `swift adopt` The Swift package manager could implement an `adopt` subcommand for interactive review and application of adoption mode output for a given set of features, -with a command line interface similar to `git add --patch`. +with a command-line interface similar to `git add --patch`. ## Alternatives considered ### Naming -Perhaps the most intuitive alternative to "adoption" is "migration". We -settled on the former because there is no reason for this concept to be limited -to upcoming features or migrational changes. +Perhaps the most intuitive alternative to "adoption" is "migration". +We settled on the former because there is no reason for this concept to be +limited to upcoming features or migrational changes. ## Acknowledgements @@ -326,9 +309,10 @@ Special thanks to Holly for her guidance throughout the draft stage. [SE-0352]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md [SE-0354]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0354-regex-literals.md [SE-0362]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0362-piecemeal-future-features.md -[feature-detection]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0362-piecemeal-future-features.md#feature-detection-in-source-code +[SE-0362-feature-detection]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0362-piecemeal-future-features.md#feature-detection-in-source-code [SE-0383]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0383-deprecate-uiapplicationmain-and-nsapplicationmain.md [SE-0401]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0401-remove-property-wrapper-isolation.md +[SE-0401-acceptance]: https://forums.swift.org/t/accepted-with-modifications-se-0401-remove-actor-isolation-inference-caused-by-property-wrappers/66241 [SE-0409]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md [SE-0411]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0411-isolated-default-values.md [SE-0413]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0413-typed-throws.md @@ -338,4 +322,3 @@ Special thanks to Holly for her guidance throughout the draft stage. [SE-0434]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0434-global-actor-isolated-types-usability.md [SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md [async-inherit-isolation-pitch]: https://forums.swift.org/t/pitch-inherit-isolation-by-default-for-async-functions/74862 -[SE-0401-acceptance]: https://forums.swift.org/t/accepted-with-modifications-se-0401-remove-actor-isolation-inference-caused-by-property-wrappers/66241 From 24e26bb795a92c59b888153dc571b25213aa8431 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 19 Feb 2025 05:43:50 +0000 Subject: [PATCH 13/16] Add link to pitch --- proposals/NNNN-adoption-tooling-for-swift-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/NNNN-adoption-tooling-for-swift-features.md b/proposals/NNNN-adoption-tooling-for-swift-features.md index c51aa9b38d..e3cce3289b 100644 --- a/proposals/NNNN-adoption-tooling-for-swift-features.md +++ b/proposals/NNNN-adoption-tooling-for-swift-features.md @@ -5,7 +5,7 @@ * Review Manager: TBD * Status: **Awaiting implementation** * Implementation: TBD -* Review: TBD +* Review: [pitch](https://forums.swift.org/t/pitch-adoption-tooling-for-upcoming-features/77936) ## Introduction @@ -294,7 +294,7 @@ This proposal was inspired by documents prepared by [Allan Shortlidge][Allan] and [Holly Borla][Holly]. Special thanks to Holly for her guidance throughout the draft stage. - + [Holly]: https://github.com/hborla [Allan]: https://github.com/tshortli From c6039af6146b466a121de35c17a1bf10c862ac8d Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 19 Feb 2025 06:09:32 +0000 Subject: [PATCH 14/16] Minor clarification for naming rationale --- proposals/NNNN-adoption-tooling-for-swift-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/NNNN-adoption-tooling-for-swift-features.md b/proposals/NNNN-adoption-tooling-for-swift-features.md index e3cce3289b..e9a6b9d230 100644 --- a/proposals/NNNN-adoption-tooling-for-swift-features.md +++ b/proposals/NNNN-adoption-tooling-for-swift-features.md @@ -285,8 +285,8 @@ with a command-line interface similar to `git add --patch`. ### Naming Perhaps the most intuitive alternative to "adoption" is "migration". -We settled on the former because there is no reason for this concept to be -limited to upcoming features or migrational changes. +We settled on the former because there is no reason for this concept to remain +limited to upcoming features or mechanical migration. ## Acknowledgements From 31ff6788affe981b60e76ca9b8661e6e3092e7cd Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 19 Feb 2025 18:45:34 +0000 Subject: [PATCH 15/16] Describe the behavior for specifying invalid mode --- proposals/NNNN-adoption-tooling-for-swift-features.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/NNNN-adoption-tooling-for-swift-features.md b/proposals/NNNN-adoption-tooling-for-swift-features.md index e9a6b9d230..e68f1750b3 100644 --- a/proposals/NNNN-adoption-tooling-for-swift-features.md +++ b/proposals/NNNN-adoption-tooling-for-swift-features.md @@ -148,6 +148,9 @@ For example: -enable-upcoming-feature InternalImportsByDefault:adoption ``` +If the specified mode is invalid, the flag will be ignored, and a warning will +be emitted. This warning will belong to the `StrictLanguageFeatures` diagnostic +group. In a series of either of these options applied to a given feature, only the last option will be honored. If an upcoming feature is both implied by the effective language mode and From 8ae57e809cfbe17a549fff127b006bf54cbecfdd Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 20 Feb 2025 23:32:34 +0000 Subject: [PATCH 16/16] Clarify diagnostic group for a proposed warning --- proposals/NNNN-adoption-tooling-for-swift-features.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/NNNN-adoption-tooling-for-swift-features.md b/proposals/NNNN-adoption-tooling-for-swift-features.md index e68f1750b3..a7b69dd356 100644 --- a/proposals/NNNN-adoption-tooling-for-swift-features.md +++ b/proposals/NNNN-adoption-tooling-for-swift-features.md @@ -127,6 +127,7 @@ for a given upcoming feature, i.e., because the upcoming feature does not have a mechanical migration. A corresponding warning will be emitted in this case to avoid the false impression that the impacted source code is compatible with the feature. +This warning will belong to the diagnostic group `StrictLanguageFeatures`. ### Interface @@ -149,8 +150,8 @@ For example: ``` If the specified mode is invalid, the flag will be ignored, and a warning will -be emitted. This warning will belong to the `StrictLanguageFeatures` diagnostic -group. +be emitted. +This warning will belong to the diagnostic group `StrictLanguageFeatures`. In a series of either of these options applied to a given feature, only the last option will be honored. If an upcoming feature is both implied by the effective language mode and