Skip to content

[Concurrency] Change TypeBase::isSendable() to return false for unavailable conformances. #72231

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

Merged
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
13 changes: 3 additions & 10 deletions lib/AST/ConformanceLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,16 +852,9 @@ bool TypeBase::isSendableType() {
if (auto *fas = getAs<AnyFunctionType>())
return fas->isSendable();

auto conformance = proto->getParentModule()->checkConformance(this, proto);
if (conformance.isInvalid())
return false;

// Look for missing Sendable conformances.
return !conformance.forEachMissingConformance(
[](BuiltinProtocolConformance *missing) {
return missing->getProtocol()->isSpecificProtocol(
KnownProtocolKind::Sendable);
});
auto conformance = proto->getParentModule()->checkConformance(
this, proto, false /*allow missing*/);
return conformance && !conformance.hasUnavailableConformance();
}

///
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 @@ -96,6 +96,8 @@ public actor MyActor: MyProto {

func g(ns1: NS1) async {
await nonisolatedAsyncFunc1(ns1) // expected-targeted-and-complete-warning{{passing argument of non-sendable type 'NS1' outside of actor-isolated context may introduce data races}}
// expected-tns-warning @-1 {{transferring 'ns1' may cause a race}}
// expected-tns-note @-2 {{transferring actor-isolated 'ns1' to nonisolated callee could cause races between nonisolated and actor-isolated uses}}
_ = await nonisolatedAsyncFunc2() // expected-warning{{non-sendable type 'NS1' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary}}
}
}
Expand Down Expand Up @@ -352,13 +354,12 @@ func testPointersAreNotSendable() {
extension SynthesizedConformances.NotSendable: Sendable {}

enum SynthesizedConformances {
// expected-note@+1 2 {{consider making struct 'NotSendable' conform to the 'Sendable' protocol}}
struct NotSendable: Equatable {}

// expected-warning@+2 2{{non-sendable type 'SynthesizedConformances.NotSendable' in asynchronous access to main actor-isolated property 'x' cannot cross actor boundary}}
// expected-note@+1 2 {{in derived conformance to 'Equatable'}}
// expected-warning@+2 2{{main actor-isolated property 'x' can not be referenced from a non-isolated context}}
// expected-note@+1 2{{in static method '==' for derived conformance to 'Equatable'}}
@MainActor struct Isolated: Equatable {
let x: NotSendable
let x: NotSendable // expected-note 2{{property declared here}}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: %target-swift-frontend -emit-sil -strict-concurrency=complete -enable-upcoming-feature RegionBasedIsolation -disable-availability-checking -verify %s -o /dev/null

// REQUIRES: concurrency
// REQUIRES: asserts

// This test makes sure that we treat types with an unavailable Sendable
// conformance as being non-Sendable.

public class NonSendable {
func foo() {
}
}

@available(*, unavailable)
extension NonSendable: Sendable {}

actor Bar {
init(_ _: NonSendable) {
}
func bar() async {
let ns = NonSendable() // expected-note {{variable defined here}}
_ = Bar(ns) // expected-warning {{transferring 'ns' may cause a race}}
// TODO: This needs to be:
// disconnected 'ns' is transferred to actor-isolated callee. Later local uses could race with uses in callee.
// expected-note @-3 {{'ns' is transferred from actor-isolated caller to actor-isolated callee. Later uses in caller could race with potential uses in callee}}
ns.foo() // expected-note {{access here could race}}
}
}