Skip to content

Super-level sendable checking for function parameters in overrides and conformances #66640

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 1 commit into from
Jun 20, 2023

Conversation

JTurcotti
Copy link
Contributor

@JTurcotti JTurcotti commented Jun 14, 2023

Sendable checking for overrides and protocol conformances ensures that if the override crosses an isolation domain the parameters and results of the overriding method are sendable. This is technically too strict, as only the parameters of the overridden method need be sendable. This PR fixes this for override and conformance checks by splitting the sendable checking to check Sensibility of parameters of the overridden method, and results of the overriding method.

The test sendable_checking.swift ensures that new code now typechecks such as:

class Super {
    @MainActor
    func g<T : Sendable>(x: T) async {}
}

class Sub : Super {
    override nonisolated func g<T>(x: T) async {}
}

for overrides, and

protocol P {
  func foo(x : @Sendable () -> ()) async -> ()
}

actor A : P {
  func foo(x : () -> ()) -> () {}
}

for conformances.

note: this PR supplants #66605.

// requirement parameters not witness parameters
@available(SwiftStdlib 5.1, *)
actor A : P {
func foo(x : () -> ()) -> () {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the lack of a diagnostic here is 1 of the 2 features added by this PR

// of superclass parameters not subclass parameters
@available(SwiftStdlib 5.1, *)
class Sub : Super {
override nonisolated func foo<T>(x: T) async {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the lack of a diagnostic here is 1 of the 2 features added by this PR

@kavon kavon self-requested a review June 14, 2023 19:37
Copy link
Member

@kavon kavon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks like a great fix! Just some small nits since it's your first PR.

@JTurcotti
Copy link
Contributor Author

@swift-ci please smoke test

1 similar comment
@kavon
Copy link
Member

kavon commented Jun 15, 2023

@swift-ci please smoke test

// make sure conformance to protocols checks sendability of
// requirement parameters not witness parameters
@available(SwiftStdlib 5.1, *)
actor A : P {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: funny formatting here, the leading spaces

protocol P {
func foo (x : @Sendable () -> ()) async -> ()

func bar(x : () -> ()) async -> ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually wonder if the warning can be emitted always already when we see such func in a protocol on an async func? Since an async func, in a class/struct will execute on global pool, and on an actor "on the actor", so in any case this will cross an async boundary so needs to be sendable always, doesn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

methods of classes can also be async, so this protocol could also be used to allow one class's async method to call another class's async method without crossing an isolation boundary. This I believe is a valid use case for a protocol requirement for an async method without sendable parameters.

return 0
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny nit, missing newline at the end of the file.

Copy link
Member

@kavon kavon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few suggestions

@JTurcotti JTurcotti force-pushed the protocol-variance branch from d84d80a to f9a2b00 Compare June 16, 2023 17:51
@JTurcotti JTurcotti force-pushed the protocol-variance branch 2 times, most recently from d866f09 to 5b5e654 Compare June 16, 2023 17:58
@kavon
Copy link
Member

kavon commented Jun 16, 2023

@swift-ci please smoke test

@JTurcotti JTurcotti force-pushed the protocol-variance branch 2 times, most recently from 31cde0c to 1be4155 Compare June 16, 2023 20:34
…he past, both the results and parameters of overriding (resp. conforming) functions were checked for Sendability. This is overly restrictive. For safety, the parameters of the overridden (resp. requiring) function should be checked for Sendability and the results of the overriding (resp. conforming) should be checked. This commit implements that change.
@JTurcotti JTurcotti force-pushed the protocol-variance branch from 1be4155 to eb78da2 Compare June 16, 2023 20:39
@kavon
Copy link
Member

kavon commented Jun 16, 2023

@swift-ci smoke test

@JTurcotti
Copy link
Contributor Author

@swift-ci please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants