Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Concurrency] SE-0466: Replace UnspecifiedMeansMainActorIsolated flag with -default-isolation #80219

Merged
merged 2 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,6 @@ EXPERIMENTAL_FEATURE(ImportNonPublicCxxMembers, true)
// Isolated deinit
SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedDeinit, 371, "isolated deinit")

// When a parameter has unspecified isolation, infer it as main actor isolated.
EXPERIMENTAL_FEATURE(UnspecifiedMeansMainActorIsolated, false)

/// modify/read single-yield coroutines
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CoroutineAccessors, true)

Expand Down
8 changes: 8 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ namespace swift {
TaskToThread,
};

enum class DefaultIsolation : uint8_t {
MainActor,
Nonisolated
};

/// Describes the code size optimization behavior for code associated with
/// declarations that are marked unavailable.
enum class UnavailableDeclOptimization : uint8_t {
Expand Down Expand Up @@ -632,6 +637,9 @@ namespace swift {
/// Disables `DynamicActorIsolation` feature.
bool DisableDynamicActorIsolation = false;

/// Defines the default actor isolation.
DefaultIsolation DefaultIsolationBehavior = DefaultIsolation::Nonisolated;

/// Whether or not to allow experimental features that are only available
/// in "production".
#ifdef NDEBUG
Expand Down
9 changes: 9 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,15 @@ def strict_concurrency : Joined<["-"], "strict-concurrency=">,
"concurrency model, or 'complete' ('Sendable' and other checking is "
"enabled for all code in the module)">;

def default_isolation : Separate<["-"], "default-isolation">,
Flags<[FrontendOption]>,
HelpText<"Specify the default actor isolation: MainActor or nonisolated. "
"Defaults to nonisolated.">,
MetaVarName<"MainActor|nonisolated">;
def default_isolation_EQ : Joined<["-"], "default-isolation=">,
Flags<[FrontendOption]>,
Alias<default_isolation>;

def enable_experimental_feature :
Separate<["-"], "enable-experimental-feature">,
Flags<[FrontendOption, ModuleInterfaceOption]>,
Expand Down
1 change: 0 additions & 1 deletion lib/AST/FeatureSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ UNINTERESTING_FEATURE(StaticExclusiveOnly)
UNINTERESTING_FEATURE(ExtractConstantsFromMembers)
UNINTERESTING_FEATURE(GroupActorErrors)
UNINTERESTING_FEATURE(SameElementRequirements)
UNINTERESTING_FEATURE(UnspecifiedMeansMainActorIsolated)

static bool usesFeatureSendingArgsAndResults(Decl *decl) {
auto isFunctionTypeWithSending = [](Type type) {
Expand Down
24 changes: 21 additions & 3 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,9 +969,6 @@ static bool ParseEnabledFeatureArgs(LangOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_strict_memory_safety))
Opts.enableFeature(Feature::StrictMemorySafety);

if (Opts.hasFeature(Feature::UnspecifiedMeansMainActorIsolated))
Opts.enableFeature(Feature::InferIsolatedConformances);

return HadError;
}

Expand Down Expand Up @@ -1817,6 +1814,27 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.DisableDynamicActorIsolation |=
Args.hasArg(OPT_disable_dynamic_actor_isolation);

if (const Arg *A = Args.getLastArg(options::OPT_default_isolation)) {
auto behavior =
llvm::StringSwitch<std::optional<DefaultIsolation>>(A->getValue())
.Case("MainActor", DefaultIsolation::MainActor)
.Case("nonisolated", DefaultIsolation::Nonisolated)
.Default(std::nullopt);

if (behavior) {
Opts.DefaultIsolationBehavior = *behavior;
} else {
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
A->getAsString(Args), A->getValue());
HadError = true;
}
} else {
Opts.DefaultIsolationBehavior = DefaultIsolation::Nonisolated;
}

if (Opts.DefaultIsolationBehavior == DefaultIsolation::MainActor)
Opts.enableFeature(Feature::InferIsolatedConformances);

#if !defined(NDEBUG) && SWIFT_ENABLE_EXPERIMENTAL_PARSER_VALIDATION
/// Enable round trip parsing via the new swift parser unless it is disabled
/// explicitly. The new Swift parser can have mismatches with C++ parser -
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5798,7 +5798,7 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {

// If we are required to use main actor... just use that.
if (!ignoreUnspecifiedMeansMainActorIsolated &&
ctx.LangOpts.hasFeature(Feature::UnspecifiedMeansMainActorIsolated))
ctx.LangOpts.DefaultIsolationBehavior == DefaultIsolation::MainActor)
if (auto result =
globalActorHelper(ctx.getMainActorType()->mapTypeOutOfContext()))
return *result;
Expand Down
3 changes: 1 addition & 2 deletions test/Concurrency/Runtime/unspecified_is_main_actor.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -swift-version 6 -g -import-objc-header %S/Inputs/RunOnMainActor.h %import-libdispatch -enable-experimental-feature UnspecifiedMeansMainActorIsolated )
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -swift-version 6 -g -import-objc-header %S/Inputs/RunOnMainActor.h %import-libdispatch -Xfrontend -default-isolation=MainActor )

// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// REQUIRES: libdispatch
// REQUIRES: asserts
// REQUIRES: swift_feature_UnspecifiedMeansMainActorIsolated

// UNSUPPORTED: freestanding

Expand Down
8 changes: 3 additions & 5 deletions test/Concurrency/assume_mainactor.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// RUN: %target-swift-frontend -swift-version 6 -emit-silgen -enable-experimental-feature UnspecifiedMeansMainActorIsolated %s | %FileCheck %s
// RUN: %target-swift-frontend -swift-version 6 -emit-sil -enable-experimental-feature UnspecifiedMeansMainActorIsolated %s -verify

// REQUIRES: swift_feature_UnspecifiedMeansMainActorIsolated
// RUN: %target-swift-frontend -swift-version 6 -emit-silgen -default-isolation MainActor %s | %FileCheck %s
// RUN: %target-swift-frontend -swift-version 6 -emit-sil -default-isolation MainActor %s -verify

// READ THIS! This test is meant to FileCheck the specific isolation when
// UnspecifiedMeansMainActorIsolated is enabled. Please do not put other types
// `-default-isolation` is set to `MainActor`. Please do not put other types
// of tests in here.

class Klass {
Expand Down
6 changes: 2 additions & 4 deletions test/Concurrency/assume_mainactor_typechecker_errors.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// RUN: %target-swift-frontend -swift-version 6 -emit-sil -enable-experimental-feature UnspecifiedMeansMainActorIsolated %s -verify

// REQUIRES: swift_feature_UnspecifiedMeansMainActorIsolated
// RUN: %target-swift-frontend -swift-version 6 -emit-sil -default-isolation MainActor %s -verify

// READ THIS! This test is meant to check the specific isolation when
// UnspecifiedMeansMainActorIsolated is enabled in combination with validating
// `-default-isolation` is set to `MainActor` in combination with validating
// behavior around explicitly non-Sendable types that trigger type checker
// specific errors. Please do not put other types of tests in here.

Expand Down
3 changes: 1 addition & 2 deletions test/Concurrency/isolated_conformance_default_actor.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -enable-experimental-feature UnspecifiedMeansMainActorIsolated %s
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -default-isolation MainActor %s

// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: swift_feature_UnspecifiedMeansMainActorIsolated
// REQUIRES: concurrency

nonisolated
Expand Down
5 changes: 2 additions & 3 deletions test/Concurrency/swiftsettings_defaultIsolation.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// RUN: %target-swift-frontend -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -verify-additional-prefix nonisolated- -disable-availability-checking %s
// RUN: %target-swift-frontend -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -verify-additional-prefix main-actor- -disable-availability-checking -DSWIFT_SETTINGS_MAIN_ACTOR %s
// RUN: %target-swift-frontend -enable-experimental-feature UnspecifiedMeansMainActorIsolated -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -disable-availability-checking -verify-additional-prefix main-actor- %s
// RUN: %target-swift-frontend -enable-experimental-feature UnspecifiedMeansMainActorIsolated -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -disable-availability-checking -verify-additional-prefix nonisolated- -DSWIFT_SETTINGS_NONISOLATED %s
// RUN: %target-swift-frontend -default-isolation MainActor -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -disable-availability-checking -verify-additional-prefix main-actor- %s
// RUN: %target-swift-frontend -default-isolation MainActor -enable-experimental-feature SwiftSettings -c -verify -swift-version 6 -disable-availability-checking -verify-additional-prefix nonisolated- -DSWIFT_SETTINGS_NONISOLATED %s

// REQUIRES: asserts
// REQUIRES: concurrency
// REQUIRES: swift_feature_UnspecifiedMeansMainActorIsolated
// REQUIRES: swift_feature_SwiftSettings

#if SWIFT_SETTINGS_MAIN_ACTOR
Expand Down