Skip to content
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

Add explicit Sendable unavailability and add missing Sendable conformances #2578

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dnadoba
Copy link
Member

@dnadoba dnadoba commented Oct 27, 2023

Found with -require-explicit-sendable compiler flag. We may want to enable this flag in CI but it currently warns also for internal types that are @usableFromInline but we could mark them explicitly as well if we wanted.

…formances

Found with `-require-explicit-sendable` compiler flag.
We may want to enable this flag in CI but it currently warns also for internal types that are @usableFromInline but we could mark them explicitly as well if we wanted.
Copy link
Contributor

@FranzBusch FranzBusch left a comment

Choose a reason for hiding this comment

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

Overall, before we mark more things as explicitly not Sendable we should check how that interacts with region based isolation. Can an explicitly not Sendable value still be send across regions?

@@ -147,7 +147,7 @@ public struct NIOAsyncWriter<
/// This struct contains two properties:
/// 1. The ``sink`` which should be retained by the consumer and is used to set the writability.
/// 2. The ``writer`` which is the actual ``NIOAsyncWriter`` and should be passed to the producer.
public struct NewWriter {
public struct NewWriter: @unchecked Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Unsure about that one the Sink is not Sendable right now because we expect it to be only held in one isolation domain at any given time even though it is fully thread-safe. We certainly can't make this type unchecked Sendable then. So we either make the Sink Sendable as well or don't make this one Sendable

@@ -93,7 +93,7 @@ let SO_TIMESTAMP = CNIOLinux_SO_TIMESTAMP
let SO_RCVTIMEO = CNIOLinux_SO_RCVTIMEO
#endif

public enum NIOBSDSocket {
public enum NIOBSDSocket: Sendable{
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we can make a socket Sendable it is the same as FileHandle

Copy link
Contributor

Choose a reason for hiding this comment

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

This is just a namespace.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah good catch. Then my comments from below apply. Should we really make namespaces Sendable?

Copy link
Contributor

Choose a reason for hiding this comment

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

I can't see any reason to do so.

@@ -378,7 +378,7 @@ extension ChannelError: Equatable { }
/// The removal of a `ChannelHandler` using `ChannelPipeline.removeHandler` has been attempted more than once.
public struct NIOAttemptedToRemoveHandlerMultipleTimesError: Error {}

public enum DatagramChannelError {
public enum DatagramChannelError: Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is just a namespace right? We probably shouldn't make it Sendable right now

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay, I will mark it then as non-sendable. I don't think it really matters though.

@@ -64,7 +64,7 @@ public typealias ConnectTimeoutOption = ChannelOptions.Types.ConnectTimeoutOptio
public typealias AllowRemoteHalfClosureOption = ChannelOptions.Types.AllowRemoteHalfClosureOption

extension ChannelOptions {
public enum Types {
public enum Types: Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here. This is just a namespace right?

@dnadoba
Copy link
Member Author

dnadoba commented Oct 30, 2023

@FranzBusch eventually everything is either Sendable or not Sendable. We have this grey zone right now where the diagnostics severity is influenced by explicit or implicit marking but in Swift 6 mode this should no longer be the case.

@FranzBusch
Copy link
Contributor

@FranzBusch eventually everything is either Sendable or not Sendable.

I am unsure if that's true. In my head there are three distinct constraints Sendable not-Sendable and unavailable Sendable. The latter has some special treatment in the compiler right now and I am wondering if the region based isolation diagnostic also treats it differently or not. If it doesn't treat it differently then I am fine with marking everything as either Sendable or unavailable Sendable

@Lukasa
Copy link
Contributor

Lukasa commented Oct 30, 2023

@FranzBusch eventually everything is either Sendable or not Sendable.

I think this is fundamentally not true. Uninhabited types are neither Sendable nor not Sendable. They can certainly conform, but as a practical semantic matter they aren't Sendable or not Sendable because no values of them exist.

Similarly, Never conforms to Sendable, but you cannot send a Never.

@dnadoba
Copy link
Member Author

dnadoba commented Oct 30, 2023

Uninhabited types are neither Sendable nor not Sendable

I can't follow. You say yourself that Never is Sendable and Never is an uninhabited type which contradicts your statement above.

The only way a Type can "maybe" conform to a Protocol is through retroactive conformance. However, this isn't relevant as Sendable is a marker protocol and is checked at compile time only. Generics are another possible case where the concrete type might conform to Sendable but as Sendable is only checked at compile time this doesn't matter either.

@Lukasa
Copy link
Contributor

Lukasa commented Oct 30, 2023

I'm not saying uninhabited types can't conform to Sendable, I'm saying they can't be Sendable. That is, they can never satisfy the semantic requirement of the protocol. There are no values of uninhabited types, so you can never Send one.

Similarly, Never conforms to Equatable but you can never equate them.

This is why it's simply not worth arguing about whether they conform or not: their conformance is meaningless, and no correct code could possibly rely on it.

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.

None yet

3 participants