While wrestling with eliminating some concurrency warnings, I noticed that if I mark a type as frozen, the warnings disappear. This is a bit confusing as the docs state:
When the compiler isn’t in library evolution mode, all structures and enumerations are implicitly frozen, and this attribute is ignored.
The affected project is an iOS app which organises its code into modules using a local swift package, and, afaict, library evolution mode isn't on. (BUILD_LIBRARY_FOR_DISTRIBUTION
= No)
This can be reproduced with the following types and module hierarchy:
Module 1
import Module2
@MainActor final class Container {
let a1 = A1()
let a2 = A2()
deinit {
a1.cleanup() // This is fine.
a2.cleanup() // WARNING: Cannot access property 'a2' with a non-sendable type 'A2' from non-isolated deinit; this is an error in Swift 6
}
}
internal struct A1 {
internal init() {}
internal func cleanup() {}
}
Module 2
public struct A2 {
public init() {}
public func cleanup() {}
}
When A2
isn't annotated with @frozen
, a warning is raised in the deinit. However, when A2
is annotated with the @frozen
attribute, the warning disappears.
So are we safe to assume that the @frozen
attribute does have utility outside of library evolution? Or is it that the implicitly frozen status of non-evolution mode types isn't being picked up by the compiler?