From 86f356cc3ab35d02edd3efe972a76e1d0a6a7261 Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Tue, 30 Apr 2024 06:41:24 -0700 Subject: [PATCH] Add the `swift.enable_v6` feature to support migration to the Swift 6 language mode. This flag is designed with ease of migration in mind. On toolchains that directly support the Swift 6 language mode (none have been released yet), enabling this feature on a target will simply pass `-swift-version 6` to the compiler. On older compilers however, it will instead pass the equivalent set of `-enable-upcoming-feature` flags as defined inside the compiler. This allows code to begin migrating to Swift 6 mode even before they switch to a Swift 6 toolchain. PiperOrigin-RevId: 629396220 --- swift/internal/feature_names.bzl | 13 ++++++ swift/internal/features.bzl | 51 +++++++++++++++++++++- swift/toolchains/config/compile_config.bzl | 12 +++++ swift/toolchains/xcode_swift_toolchain.bzl | 7 +++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/swift/internal/feature_names.bzl b/swift/internal/feature_names.bzl index b26172260..1b6122293 100644 --- a/swift/internal/feature_names.bzl +++ b/swift/internal/feature_names.bzl @@ -34,6 +34,14 @@ SWIFT_FEATURE_DBG = "swift.dbg" SWIFT_FEATURE_FASTBUILD = "swift.fastbuild" SWIFT_FEATURE_OPT = "swift.opt" +# If this feature is enabled, the toolchain should enable the features that are +# available in Swift 6 language mode. If the toolchain supports +# `-swift-version 6`, it will do so using that flag. If it is older, it will +# enable the set of upcoming features that will be on by default in Swift 6, +# allowing users to prepare their code base by opting in to the full set of +# Swift 6 features even before switching to a Swift 6 compiler. +SWIFT_FEATURE_ENABLE_V6 = "swift.enable_v6" + # If True, transitive C headers will be always be passed as inputs to Swift # compilation actions, even when building with explicit modules. SWIFT_FEATURE_HEADERS_ALWAYS_ACTION_INPUTS = "swift.headers_always_action_inputs" @@ -246,3 +254,8 @@ SWIFT_FEATURE__SUPPORTS_PACKAGE_MODIFIER = "swift._supports_package_modifier" # `-enable-{experimental,upcoming}-feature` flag (Swift 5.8 and above). Users # should never manually, enable, disable, or query this feature. SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES = "swift._supports_upcoming_features" + +# A private feature that is set by the toolchain if it supports +# `-swift-version 6` (Swift 6.0 and above). Users should never manually enable, +# disable, or query this feature. +SWIFT_FEATURE__SUPPORTS_V6 = "swift._supports_v6" diff --git a/swift/internal/features.bzl b/swift/internal/features.bzl index 483b116ed..4a6e62d31 100644 --- a/swift/internal/features.bzl +++ b/swift/internal/features.bzl @@ -24,9 +24,11 @@ load( "SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX", "SWIFT_FEATURE_ENABLE_BATCH_MODE", "SWIFT_FEATURE_ENABLE_TESTING", + "SWIFT_FEATURE_ENABLE_V6", "SWIFT_FEATURE_FULL_DEBUG_INFO", "SWIFT_FEATURE_INTERNALIZE_AT_LINK", "SWIFT_FEATURE_NO_GENERATED_MODULE_MAP", + "SWIFT_FEATURE__SUPPORTS_V6", ) load(":package_specs.bzl", "label_matches_package_specs") load(":target_triples.bzl", "target_triples") @@ -455,4 +457,51 @@ def _compute_features( # Features that are unsupported by the toolchain override any requests for those features. feature_updater.update_features([], swift_toolchain.unsupported_features) - return (feature_updater.requested_features(), feature_updater.disabled_features()) + all_disabled_features = feature_updater.disabled_features() + all_requested_features = _compute_implied_features( + requested_features = feature_updater.requested_features(), + unsupported_features = all_disabled_features, + ) + return (all_requested_features, all_disabled_features) + +def _compute_implied_features(requested_features, unsupported_features): + """Compute additional features that should be implied by combinations. + + To avoid an explosion of generalized complexity, this is being done only for + features related to language mode support, instead of building it out as a + feature for use elsewhere in the toolchain. + """ + + # If a user requests Swift language mode 6 on a compiler that doesn't + # support `-swift-version 6`, we instead enable all of the upcoming features + # that will be on by default in Swift 6 mode. This provides an early + # migration path for those users. + if (SWIFT_FEATURE_ENABLE_V6 in requested_features and + SWIFT_FEATURE__SUPPORTS_V6 not in requested_features): + for feature in _SWIFT_6_EQUIVALENT_FEATURES: + # Only add it if the user did not explicitly ask for it to be + # suppressed. + if feature not in unsupported_features: + requested_features.append(feature) + + return requested_features + +# The list below is taken from the feature definitions in the compiler, at +# https://github.com/apple/swift/blob/release/6.0/include/swift/Basic/Features.def#L180-L193. +# TODO: b/336996662 - Confirm that this is the final set of features enabled by +# default in Swift 6 language mode when the compiler is released. +_SWIFT_6_EQUIVALENT_FEATURES = [ + "swift.upcoming.ConciseMagicFile", # SE-0274 + "swift.upcoming.ForwardTrailingClosures", # SE-0286 + "swift.upcoming.StrictConcurrency", # SE-0337 + "swift.upcoming.BareSlashRegexLiterals", # SE-0354 + "swift.upcoming.DeprecateApplicationMain", # SE-0383 + "swift.upcoming.ImportObjcForwardDeclarations", # SE-0384 + "swift.upcoming.DisableOutwardActorInference", # SE-0401 + "swift.upcoming.IsolatedDefaultValues", # SE-0411 + "swift.upcoming.GlobalConcurrency", # SE-0412 + "swift.upcoming.InferSendableFromCaptures", # SE-0418 + "swift.upcoming.ImplicitOpenExistentials", # SE-0352 + "swift.upcoming.RegionBasedIsolation", # SE-0414 + "swift.upcoming.DynamicActorIsolation", # SE-0423 +] diff --git a/swift/toolchains/config/compile_config.bzl b/swift/toolchains/config/compile_config.bzl index 13b2c5b8a..b16bb91bc 100644 --- a/swift/toolchains/config/compile_config.bzl +++ b/swift/toolchains/config/compile_config.bzl @@ -37,6 +37,7 @@ load( "SWIFT_FEATURE_ENABLE_BATCH_MODE", "SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION", "SWIFT_FEATURE_ENABLE_TESTING", + "SWIFT_FEATURE_ENABLE_V6", "SWIFT_FEATURE_FASTBUILD", "SWIFT_FEATURE_FILE_PREFIX_MAP", "SWIFT_FEATURE_FULL_DEBUG_INFO", @@ -61,6 +62,7 @@ load( "SWIFT_FEATURE__SUPPORTS_MACROS", "SWIFT_FEATURE__SUPPORTS_PACKAGE_MODIFIER", "SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES", + "SWIFT_FEATURE__SUPPORTS_V6", "SWIFT_FEATURE__WMO_IN_SWIFTCOPTS", ) load(":action_config.bzl", "ActionConfigInfo", "ConfigResultInfo", "add_arg") @@ -844,6 +846,16 @@ def compile_action_configs( SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES, ], ), + ActionConfigInfo( + actions = [ + SWIFT_ACTION_COMPILE, + ], + configurators = [add_arg("-swift-version", "6")], + features = [ + SWIFT_FEATURE_ENABLE_V6, + SWIFT_FEATURE__SUPPORTS_V6, + ], + ), ] # NOTE: The positions of these action configs in the list are important, diff --git a/swift/toolchains/xcode_swift_toolchain.bzl b/swift/toolchains/xcode_swift_toolchain.bzl index 55ac1f831..5f7ee7e82 100644 --- a/swift/toolchains/xcode_swift_toolchain.bzl +++ b/swift/toolchains/xcode_swift_toolchain.bzl @@ -47,6 +47,7 @@ load( "SWIFT_FEATURE__SUPPORTS_MACROS", "SWIFT_FEATURE__SUPPORTS_PACKAGE_MODIFIER", "SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES", + "SWIFT_FEATURE__SUPPORTS_V6", ) load( "@build_bazel_rules_swift//swift/internal:features.bzl", @@ -653,6 +654,12 @@ def _xcode_swift_toolchain_impl(ctx): SWIFT_FEATURE__SUPPORTS_PACKAGE_MODIFIER, ]) + # TODO: b/336996662 - Use a very high Xcode version number until we've + # confirmed the actual Xcode release that ships with a compiler that + # supports `-swift-version 6`. + if _is_xcode_at_least_version(xcode_config, "999.0"): + requested_features.append(SWIFT_FEATURE__SUPPORTS_V6) + env = _xcode_env(target_triple = target_triple, xcode_config = xcode_config) execution_requirements = xcode_config.execution_info()