mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[SE-0466] Under main actor default isolation, explicit nonisolated is not special
Given an explicitly-nonisolated type such as
nonisolated struct S { }
all extensions of S were also being treated as nonisolated. This meant
that being implicitly nonisolated (i.e., when you're using nonisolated
default isolation) was different from explicitly-writing nonisolated,
which is unfortunate and confusing. Align the rules, such that an
extension of S will get default isolation:
extension S {
func f() { } // @MainActor if we're in main actor default isolation
}
This commit is contained in:
@@ -127,6 +127,7 @@ UNINTERESTING_FEATURE(MacrosOnImports)
|
||||
UNINTERESTING_FEATURE(ExtensibleEnums)
|
||||
UNINTERESTING_FEATURE(NonisolatedNonsendingByDefault)
|
||||
UNINTERESTING_FEATURE(KeyPathWithMethodMembers)
|
||||
UNINTERESTING_FEATURE(NoExplicitNonIsolated)
|
||||
|
||||
static bool usesFeatureNonescapableTypes(Decl *decl) {
|
||||
auto containsNonEscapable =
|
||||
|
||||
@@ -1878,8 +1878,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
Opts.DefaultIsolationBehavior = DefaultIsolation::Nonisolated;
|
||||
}
|
||||
|
||||
if (Opts.DefaultIsolationBehavior == DefaultIsolation::MainActor)
|
||||
if (Opts.DefaultIsolationBehavior == DefaultIsolation::MainActor) {
|
||||
Opts.enableFeature(Feature::InferIsolatedConformances);
|
||||
Opts.enableFeature(Feature::NoExplicitNonIsolated);
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) && SWIFT_ENABLE_EXPERIMENTAL_PARSER_VALIDATION
|
||||
/// Enable round trip parsing via the new swift parser unless it is disabled
|
||||
|
||||
@@ -6297,6 +6297,39 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
|
||||
return {{ActorIsolation::forUnspecified(), {}}, nullptr, {}};
|
||||
}
|
||||
|
||||
/// Determines when the given "self" isolation should override default
|
||||
/// isolation.
|
||||
static bool shouldSelfIsolationOverrideDefault(
|
||||
ASTContext &ctx, const DeclContext *dc,
|
||||
const ActorIsolation &selfIsolation) {
|
||||
switch (selfIsolation) {
|
||||
case ActorIsolation::ActorInstance:
|
||||
case ActorIsolation::Erased:
|
||||
case ActorIsolation::GlobalActor:
|
||||
// Actor isolation always overrides.
|
||||
return true;
|
||||
|
||||
case ActorIsolation::Unspecified:
|
||||
// Unspecified isolation never overrides.
|
||||
return false;
|
||||
|
||||
case ActorIsolation::Nonisolated:
|
||||
case ActorIsolation::NonisolatedUnsafe:
|
||||
case ActorIsolation::CallerIsolationInheriting:
|
||||
// Explicit nonisolated used to overwrite default isolation all the time,
|
||||
// but under NoExplicitNonIsolated it doesn't affect extensions.
|
||||
if (isa<NominalTypeDecl>(dc))
|
||||
return true;
|
||||
|
||||
// The NoExplicitNonIsolated feature
|
||||
if (ctx.LangOpts.hasFeature(Feature::NoExplicitNonIsolated))
|
||||
return false;
|
||||
|
||||
// Suppress when the default isolation is nonisolated.
|
||||
return getDefaultIsolationForContext(dc) == DefaultIsolation::Nonisolated;
|
||||
}
|
||||
}
|
||||
|
||||
static InferredActorIsolation computeActorIsolation(Evaluator &evaluator,
|
||||
ValueDecl *value) {
|
||||
// If this declaration has actor-isolated "self", it's isolated to that
|
||||
@@ -6629,7 +6662,8 @@ static InferredActorIsolation computeActorIsolation(Evaluator &evaluator,
|
||||
// has isolation, use that.
|
||||
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
|
||||
auto selfTypeIsolation = getInferredActorIsolation(selfTypeDecl);
|
||||
if (selfTypeIsolation.isolation) {
|
||||
if (shouldSelfIsolationOverrideDefault(
|
||||
ctx, value->getDeclContext(), selfTypeIsolation.isolation)) {
|
||||
auto isolation = selfTypeIsolation.isolation;
|
||||
|
||||
if (ctx.LangOpts.hasFeature(Feature::NonisolatedNonsendingByDefault) &&
|
||||
|
||||
Reference in New Issue
Block a user