Skip to content

Commit

Permalink
[Concurrency] Un-gate implicit nonisolated access to struct vars and …
Browse files Browse the repository at this point in the history
…isolated

subclassing.

These features are additive, and they don't need to be gated behind the
`GlobalActorIsolatedTypesUsability` upcoming feature. The other inference
changes, including `@Sendable` inference for global-actor-isolated function
types, and global-actor inference on protocol refinements, remain gated
behind the upcoming flag.
  • Loading branch information
hborla committed May 14, 2024
1 parent 387580c commit 29b8e6e
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 26 deletions.
29 changes: 11 additions & 18 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,16 +512,14 @@ static bool varIsSafeAcrossActors(const ModuleDecl *fromModule,

if (!var->isLet()) {
ASTContext &ctx = var->getASTContext();
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability)) {
// A mutable storage of a value type accessed from within the module is
// okay.
if (dyn_cast_or_null<StructDecl>(var->getDeclContext()->getAsDecl()) &&
!var->isStatic() &&
var->hasStorage() &&
var->getTypeInContext()->isSendableType() &&
accessWithinModule) {
return true;
}
// A mutable storage of a value type accessed from within the module is
// okay.
if (dyn_cast_or_null<StructDecl>(var->getDeclContext()->getAsDecl()) &&
!var->isStatic() &&
var->hasStorage() &&
var->getTypeInContext()->isSendableType() &&
accessWithinModule) {
return true;
}
// Otherwise, must be immutable.
return false;
Expand Down Expand Up @@ -4808,12 +4806,7 @@ static bool checkClassGlobalActorIsolation(
case ActorIsolation::Unspecified:
case ActorIsolation::Nonisolated:
case ActorIsolation::NonisolatedUnsafe: {
auto &ctx = classDecl->getASTContext();
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability))
return false;

downgradeToWarning = true;
break;
return false;
}

case ActorIsolation::Erased:
Expand Down Expand Up @@ -6054,8 +6047,8 @@ ProtocolConformance *swift::deriveImplicitSendableConformance(

// Classes that add global actor isolation to non-Sendable
// superclasses cannot be 'Sendable'.
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability) &&
nominal->getGlobalActorAttr()) {
auto superclassDecl = classDecl->getSuperclassDecl();
if (nominal->getGlobalActorAttr() && !superclassDecl->isNSObject()) {
return nullptr;
}
}
Expand Down
4 changes: 3 additions & 1 deletion test/ClangImporter/objc_async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class BarFrame: PictureFrame {
@available(SwiftStdlib 5.5, *)
@SomeGlobalActor
class BazFrame: NotIsolatedPictureFrame {
// expected-warning@-1 {{global actor 'SomeGlobalActor'-isolated class 'BazFrame' has different actor isolation from nonisolated superclass 'NotIsolatedPictureFrame'; this is an error in the Swift 6 language mode}}
// expected-note@-1 2 {{class 'BazFrame' does not conform to the 'Sendable' protocol}}
init() {
super.init(size: 0)
}
Expand All @@ -322,10 +322,12 @@ func check() async {
_ = await BarFrame()
_ = await FooFrame()
_ = await BazFrame()
// expected-warning@-1 {{non-sendable type 'BazFrame' returned by call to global actor 'SomeGlobalActor'-isolated function cannot cross actor boundary; this is an error in the Swift 6 language mode}}

_ = await BarFrame(size: 0)
_ = await FooFrame(size: 0)
_ = await BazFrame(size: 0)
// expected-warning@-1 {{non-sendable type 'BazFrame' returned by call to global actor 'SomeGlobalActor'-isolated function cannot cross actor boundary; this is an error in the Swift 6 language mode}}
}

@available(SwiftStdlib 5.5, *)
Expand Down
9 changes: 5 additions & 4 deletions test/Concurrency/sendable_checking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func testConversionsAndSendable(a: MyActor, s: any Sendable, f: @Sendable () ->

@available(SwiftStdlib 5.1, *)
final class NonSendable {
// expected-note @-1 3 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
// expected-note @-1 4 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
// TransferNonSendable emits 3 fewer errors here.
// expected-targeted-and-complete-note @-3 5 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
// expected-complete-and-tns-note @-4 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
Expand Down Expand Up @@ -397,12 +397,13 @@ struct DowngradeForPreconcurrency {
}
}

var x: Int
func createStream() -> AsyncStream<Int> {
AsyncStream<Int> {
var x: NonSendable
func createStream() -> AsyncStream<NonSendable> {
AsyncStream<NonSendable> {
self.x
// expected-warning@-1 {{expression is 'async' but is not marked with 'await'; this is an error in the Swift 6 language mode}}
// expected-note@-2 {{property access is 'async'}}
// expected-warning@-3 {{non-sendable type 'NonSendable' in implicitly asynchronous access to main actor-isolated property 'x' cannot cross actor boundary; this is an error in the Swift 6 language mode}}
}
}
}
4 changes: 1 addition & 3 deletions test/SILGen/hop_to_executor_async_prop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,8 @@ struct Container {
// CHECK: [[SOME_BB]]:
// CHECK: [[DATA_ADDR:%[0-9]+]] = unchecked_take_enum_data_addr [[ACCESS]] : $*Optional<Container>, #Optional.some!enumelt
// CHECK: [[ELEM_ADDR:%[0-9]+]] = struct_element_addr [[DATA_ADDR]] : $*Container, #Container.iso
// CHECK: hop_to_executor {{%[0-9]+}} : $Cat
// CHECK: {{%[0-9]+}} = load [trivial] [[ELEM_ADDR]] : $*Float
// CHECK: hop_to_executor [[GENERIC_EXEC]] :
// CHECK: hop_to_executor [[GENERIC_EXEC]] :
// CHECK: } // end sil function '$s4test9ContainerV10getOrCrashSfyYaFZ'
static func getOrCrash() async -> Float {
return await this!.iso
Expand Down Expand Up @@ -628,7 +626,7 @@ struct Container {

@propertyWrapper
struct StateObject<ObjectType> {
@MainActor(unsafe)
@preconcurrency @MainActor
var wrappedValue: ObjectType {
fatalError()
}
Expand Down

0 comments on commit 29b8e6e

Please sign in to comment.