somu
(somu)
1
Hi,
I am a bit confused with Sendable conformance
Overview
I am not sure why all the code below compiles, particularly the class with a mutable state.
Environment
- Xcode command line project
- Xcode Version 14.0 beta 3 (14A5270f))
- macOS 13.0 Beta (22A5295i)
Questions
- Do all value types conform to
Sendable by default?
- Why is a
class with a mutable state allowed to be assigned to a Sendable?
- Or am I missing something?
Code
struct S {}
enum E { case ok }
actor A {}
class Engine {}
class Car {
var engine: Engine
init(engine: Engine) {
self.engine = engine
}
}
var c1 = Car(engine: Engine()) //class with a mutable state
let s1: Sendable = S()
let s2: Sendable = E.ok
let s3: Sendable = A()
let s4: Sendable = c1 //Why is this allowed?
Gero
(Gero Herkenrath)
2
That's weird and afaik should not happen.
A quick check with fresh Xcode 13.4.1 iOS and macOS playgrounds gives the expected error message Value of type 'Car' does not conform to specified type 'Sendable'.
I don't have a newer Xcode handy atm to test, but perhaps this is a bug you should report? I'd be very surprised if there was a recent change that actually gives that class implicit conformance as I don't think that's even feasible...
It could also be that it is related to your previous post (I just noticed it's you), in that due to this being a command line project it "overlooks" this also concurrency related error, but then I'm surprised it catches on in a simple playground this time...
1 Like
somu
(somu)
3
Thanks a lot @Gero, it doesn't work when defined within a scope (example: do { })
I will try to file a bug and post the bug ID.
Question:
- Do value types conform to
Sendable by default?
Observations:
Using the following:
- Xcode Version 14.0 beta 3 (14A5270f))
- macOS 13.0 Beta (22A5295i)
Compiles fine (without warnings / errors) on the following projects on:
- SwiftUI multiplatform app
- iOS playground
- Command line project
1 Like
Gero
(Gero Herkenrath)
4
It depends a bit, the Swift 5.7 version of TSPL has a new section about this, specifically the very last paragraph explains this via an example:
Because TemperatureReading is a structure that has only sendable properties, and the structure isn’t marked public or @usableFromInline , it’s implicitly sendable. Here’s a version of the structure where conformance to the Sendable protocol is implied:
In short, if your type has no mutable properties or if all its mutable properties conform to Sendable and it's neither marked as public or @usableFromInline then Sendable conformance is implicit.
For your initial example that means that S, E, and A are implicitly Sendable.
I guess the main rationale for allowing this was that value types specifically (but probably often enough also reference types with only let properties) were used by people to cross thread/queue boundaries already in existing code (if you ever had to read something from a Core Data stack in a background queue and then needed to pass it to the UI thread without shooting yourself in the foot you had to basically come up with something like a helper type for that reason).
It would suck if all your code now needed to adopt Sendable explicitly although you were already a good developer taking care of this, so I personally welcome that even if it looks weird when you come at it from the other direction.
2 Likes
somu
(somu)
5
Thanks a lot @Gero for the reference and explanation
I have filed a bug, would be great if someone could review it
1 Like
xwu
(Xiaodi Wu)
6
This is intentional—most warnings about Sendable were backed out because they are too noisy:
You should re-enable the warnings explicitly if you want them:
https://twitter.com/olebegemann/status/1421144304127463427
If you compile your test example with -warn-concurrency enabled, you will be warned that Car does not conform to Sendable, as expected.
To check it out, I put your reduced example from the GitHub bug in a file named “test.swift”, and on the command line I ran:
swiftc test.swift
# No diagnostic output, compiles as expected
swiftc -Xfrontend -warn-concurrency test.swift
test.swift:10:19: warning: type 'Car' does not conform to the 'Sendable' protocol
let s: Sendable = car
^
test.swift:2:7: note: class 'Car' does not conform to the 'Sendable' protocol
class Car {
^
4 Likes
somu
(somu)
7
Thanks a lot @xwu for clarifying that.
I am able to see the warning after turning on the other swift flags (-Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks)
From Sendable-related warnings (SE-0302) backed out of Swift 5.6, it seems that they would continue to refine for Swift 5.7, so is the issue that I pointed out worth the review? (should I leave the bug open for it to be considered or should I close the bug?)
xwu
(Xiaodi Wu)
8
I think it’s reasonable to leave the bug open (just my own opinion); the relevant people can triage and determine what they want to do about it.
1 Like
somu
(somu)
10
In Eliminate data races using Swift Concurrency - WWDC22 - Videos - Apple Developer (24:41 min) they mention the Build Setting > Strict Concurrency Checking (SWIFT_STRICT_CONCURRENCY)
Setting SWIFT_STRICT_CONCURRENCY = complete; throws the warning Type 'Car' does not conform to the 'Sendable' protocol
1 Like