-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Sendable checking for an an isolated witnesses to a nonisolated requirement #40560
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// RUN: %target-typecheck-verify-swift | ||
// REQUIRES: concurrency | ||
|
||
@available(SwiftStdlib 5.1, *) | ||
class NotSendable { // expected-note 8{{class 'NotSendable' does not conform to the 'Sendable' protocol}} | ||
} | ||
|
||
@available(SwiftStdlib 5.1, *) | ||
@available(*, unavailable) | ||
extension NotSendable: Sendable { } | ||
|
||
@available(SwiftStdlib 5.1, *) | ||
protocol IsolatedWithNotSendableRequirements: Actor { | ||
func f() -> NotSendable | ||
var prop: NotSendable { get } | ||
} | ||
|
||
// Okay, everything is isolated the same way | ||
@available(SwiftStdlib 5.1, *) | ||
actor A1: IsolatedWithNotSendableRequirements { | ||
func f() -> NotSendable { NotSendable() } | ||
var prop: NotSendable { NotSendable() } | ||
} | ||
|
||
// Okay, sendable checking occurs when calling through the protocol | ||
// and also inside the bodies. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A2: IsolatedWithNotSendableRequirements { | ||
nonisolated func f() -> NotSendable { NotSendable() } | ||
nonisolated var prop: NotSendable { NotSendable() } | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so in this case we get warnings on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we don't need warnings on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah because nonisolated, right... Thanks! |
||
|
||
@available(SwiftStdlib 5.1, *) | ||
protocol AsyncProtocolWithNotSendable { | ||
func f() async -> NotSendable | ||
var prop: NotSendable { get async } | ||
} | ||
|
||
// Sendable checking required because calls through protocol cross into the | ||
// actor's domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A3: AsyncProtocolWithNotSendable { | ||
func f() async -> NotSendable { NotSendable() } // expected-warning{{cannot call function returning non-sendable type 'NotSendable' across actors}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the error message is super confusing here...? There is no call here 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we aren't customizing these diagnostics well as a general thing. |
||
|
||
var prop: NotSendable { // expected-warning{{cannot use property 'prop' with a non-sendable type 'NotSendable' across actors}} | ||
get async { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking required because calls through protocol cross into the | ||
// actor's domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A4: AsyncProtocolWithNotSendable { | ||
func f() -> NotSendable { NotSendable() } // expected-warning{{cannot call function returning non-sendable type 'NotSendable' across actors}} | ||
|
||
var prop: NotSendable { // expected-warning{{cannot use property 'prop' with a non-sendable type 'NotSendable' across actors}} | ||
get { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking not required because we never cross into the actor's | ||
// domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A5: AsyncProtocolWithNotSendable { | ||
nonisolated func f() async -> NotSendable { NotSendable() } | ||
|
||
nonisolated var prop: NotSendable { | ||
get async { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking not required because we never cross into the actor's | ||
// domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A6: AsyncProtocolWithNotSendable { | ||
nonisolated func f() -> NotSendable { NotSendable() } | ||
|
||
nonisolated var prop: NotSendable { | ||
get { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
@available(SwiftStdlib 5.1, *) | ||
protocol AsyncThrowingProtocolWithNotSendable { | ||
func f() async throws -> NotSendable | ||
var prop: NotSendable { get async throws } | ||
} | ||
|
||
// Sendable checking required because calls through protocol cross into the | ||
// actor's domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A7: AsyncThrowingProtocolWithNotSendable { | ||
func f() async -> NotSendable { NotSendable() } // expected-warning{{cannot call function returning non-sendable type 'NotSendable' across actors}} | ||
|
||
var prop: NotSendable { // expected-warning{{cannot use property 'prop' with a non-sendable type 'NotSendable' across actors}} | ||
get async { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking required because calls through protocol cross into the | ||
// actor's domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A8: AsyncThrowingProtocolWithNotSendable { | ||
func f() -> NotSendable { NotSendable() } // expected-warning{{cannot call function returning non-sendable type 'NotSendable' across actors}} | ||
|
||
var prop: NotSendable { // expected-warning{{cannot use property 'prop' with a non-sendable type 'NotSendable' across actors}} | ||
get { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking not required because we never cross into the actor's | ||
// domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A9: AsyncThrowingProtocolWithNotSendable { | ||
nonisolated func f() async -> NotSendable { NotSendable() } | ||
|
||
nonisolated var prop: NotSendable { | ||
get async { | ||
NotSendable() | ||
} | ||
} | ||
} | ||
|
||
// Sendable checking not required because we never cross into the actor's | ||
// domain. | ||
@available(SwiftStdlib 5.1, *) | ||
actor A10: AsyncThrowingProtocolWithNotSendable { | ||
nonisolated func f() -> NotSendable { NotSendable() } | ||
|
||
nonisolated var prop: NotSendable { | ||
get { | ||
NotSendable() | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the fix here, explicitly annotating it with @mainactor? If so, can we get a fixit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix here would have to be to turn it into a non-isolated computed property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, makes sense 👍 Could also be a fixit i guess