Data race when capturing let assigned object in @Sendable closure

SE-0302 defines a few compiler checking rules, first 2 being:

  1. [....] . Any captures must also conform to Sendable .
  2. Closures that have @Sendable function type can only use by-value captures. Captures of immutable values introduced by let are implicitly by-value

In result the code below is allowed

class C {
   var i = 0
}

let c = C() 
var i = 0

for _ in 1...1000 {
   // Task's operation is defined as @Sendable @escaping () async -> Success
   Task {
      //i = i + 1 //ERROR: referencing and mutating not allowed 
      c.i = c.i + 1  // OK!
   }
}

which is quite basic example of race condition.

So it seems like it's not allowed to capture reference to variable i (that's OK), but it's perfectly allowed to capture constant value c, being reference to not Sendable class C (the fact, compiler is aware of). It seems quite strange to me.

Shouldn't such potential problems be captured by compiler as errors (or at least warnings)?


I'm not freqent reader of this forum, so sorry if I'm repeaiting topic similiar to other(s) already discussed which I couldn't find.
And yes, I know that using actor with incrementer instead of class would solve the problem, but the threat of using class may not be always as visible as in this example.

Full Sendable checking is not enabled in the Swift 5.5 compiler. If you want better diagnostics, trying the new Xcode 13.3 beta with Swift 5.6, or one of the 5.6 or main toolchains, which have much more checking enabled by default.

I'll try it out, thx. I'm still not sure what to expect - is it an error at all?. Reading SE-0302 literally it seems like let constant should be accepted by @Sendable clousure ( values introduced by let are implicitly by-value).