Skip to content

Commit

Permalink
Add the swift.enable_v6 feature to support migration to the Swift 6…
Browse files Browse the repository at this point in the history
… 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
(cherry picked from commit 86f356c , f1765e6, 8065c86, and 3cb393f)
Signed-off-by: Brentley Jones <github@brentleyjones.com>
  • Loading branch information
allevato authored and brentleyjones committed Oct 15, 2024
1 parent 57ebd88 commit ccc5a71
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 2 deletions.
13 changes: 13 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,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"
Expand Down Expand Up @@ -365,6 +373,11 @@ SWIFT_FEATURE_DISABLE_AVAILABILITY_CHECKING = "swift.disable_availability_checki
# 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"

# Disables Swift sandbox which prevents issues with nested sandboxing when Swift code contains system-provided macros.
# If enabled '#Preview' macro provided by SwiftUI fails to build and probably other system-provided macros.
# Enabled by default for Swift 5.10+ on macOS.
Expand Down
57 changes: 56 additions & 1 deletion swift/internal/features.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ load(
"SWIFT_FEATURE_ENABLE_BATCH_MODE",
"SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_ENABLE_TESTING",
"SWIFT_FEATURE_ENABLE_V6",
"SWIFT_FEATURE_FILE_PREFIX_MAP",
"SWIFT_FEATURE_FULL_DEBUG_INFO",
"SWIFT_FEATURE_INTERNALIZE_AT_LINK",
Expand All @@ -39,6 +40,7 @@ load(
"SWIFT_FEATURE_REMAP_XCODE_PATH",
"SWIFT_FEATURE_USE_GLOBAL_MODULE_CACHE",
"SWIFT_FEATURE__FORCE_ALWAYSLINK_TRUE",
"SWIFT_FEATURE__SUPPORTS_V6",
)
load(":package_specs.bzl", "label_matches_package_specs")
load(":target_triples.bzl", "target_triples")
Expand Down Expand Up @@ -480,4 +482,57 @@ 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.experimental.StrictConcurrency=complete", # same as above on older compilers
"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

# The upcoming feature flags only emit warnings about things that will
# become errors in Swift 6. We want the `swift.enable_v6` flag specifically
# to enforce the same error behavior.
"swift.werror.error_in_future_swift_version",
]
20 changes: 19 additions & 1 deletion swift/internal/swift_autoconfiguration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ load(
"SWIFT_FEATURE_USE_AUTOLINK_EXTRACT",
"SWIFT_FEATURE_USE_MODULE_WRAP",
"SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES",
"SWIFT_FEATURE__SUPPORTS_V6",
)
load(":toolchain_utils.bzl", "SWIFT_TOOLCHAIN_TYPE")

Expand Down Expand Up @@ -71,8 +72,24 @@ def _swift_succeeds(repository_ctx, swiftc_path, *args):
swift_result = repository_ctx.execute([swiftc_path] + list(args))
return swift_result.return_code == 0

def _check_supports_language_mode_6(repository_ctx, swiftc_path, _temp_dir):
"""Returns True if the swift compiler supports language mode 6."""
result = repository_ctx.execute([swiftc_path, "-version"])
if result.return_code == 0:
_, _, almost_version = result.stdout.partition("swiftlang-")
if not almost_version:
return False

major_version, _, _ = almost_version.parition(".")
if not major_version:
return False

return int(major_version) >= 6

return False

def _check_supports_lld_gc_workaround(repository_ctx, swiftc_path, temp_dir):
"""Returns True if lld is being used and it supports nostart-stop-gc"""
"""Returns True if lld is being used and it supports nostart-stop-gc."""
source_file = _scratch_file(
repository_ctx,
temp_dir,
Expand Down Expand Up @@ -175,6 +192,7 @@ _FEATURE_CHECKS = {
SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES: (
_check_supports_upcoming_features
),
SWIFT_FEATURE__SUPPORTS_V6: _check_supports_language_mode_6,
}

def _normalized_linux_cpu(cpu):
Expand Down
12 changes: 12 additions & 0 deletions swift/toolchains/config/compile_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ load(
"SWIFT_FEATURE_ENABLE_LIBRARY_EVOLUTION",
"SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES",
"SWIFT_FEATURE_ENABLE_TESTING",
"SWIFT_FEATURE_ENABLE_V6",
"SWIFT_FEATURE_FASTBUILD",
"SWIFT_FEATURE_FILE_PREFIX_MAP",
"SWIFT_FEATURE_FULL_DEBUG_INFO",
Expand Down Expand Up @@ -81,6 +82,7 @@ load(
"SWIFT_FEATURE_VFSOVERLAY",
"SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS",
"SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES",
"SWIFT_FEATURE__SUPPORTS_V6",
"SWIFT_FEATURE__WMO_IN_SWIFTCOPTS",
)
load(":action_config.bzl", "ActionConfigInfo", "ConfigResultInfo", "add_arg")
Expand Down Expand Up @@ -1166,6 +1168,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,
Expand Down
4 changes: 4 additions & 0 deletions swift/toolchains/xcode_swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ load(
"SWIFT_FEATURE_MODULE_MAP_HOME_IS_CWD",
"SWIFT_FEATURE_REMAP_XCODE_PATH",
"SWIFT_FEATURE__SUPPORTS_UPCOMING_FEATURES",
"SWIFT_FEATURE__SUPPORTS_V6",
)
load(
"//swift/internal:features.bzl",
Expand Down Expand Up @@ -628,6 +629,9 @@ def _xcode_swift_toolchain_impl(ctx):
if _is_xcode_at_least_version(xcode_config, "15.3"):
requested_features.append(SWIFT_FEATURE_DISABLE_SWIFT_SANDBOX)

if _is_xcode_at_least_version(xcode_config, "16.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()
generated_header_rewriter = ctx.executable.generated_header_rewriter
Expand Down

0 comments on commit ccc5a71

Please sign in to comment.