-
Notifications
You must be signed in to change notification settings - Fork 50
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
Swift 5.7/6 and Non-Final Class Opt-In to AtomicReference #53
Comments
|
I'm looking into this a little in some spare time to see what I might be able to do to help. Karoy's suggestion on the forums was to explore a direction like public protocol AtomicReference: AnyObject, AtomicOptionalWrappable
{
associatedtype AtomicBaseClass: AtomicReference = Self
where
Self: AtomicBaseClass,
AtomicRepresentation == AtomicReferenceStorage<AtomicBaseClass>,
AtomicOptionalRepresentation == AtomicOptionalReferenceStorage<AtomicBaseClass>
}I think this semantically represents our intentions, but the compiler can't accept where
Self: AtomicBaseClass
// 🛑 Constraint with subject type of 'Self' is not supported; consider adding requirement to protocol inheritance clause instead
// 🛑 Type 'Self' constrained to non-protocol, non-class type 'Self.AtomicBaseClass'(Moving the If we drop this self requirement but leave the other requirements as-is, we still get legit warnings when building, because the compiler isn't satisfied: class LockFreeQueue<Element> {
class Node: AtomicReference {
// ⚠️ Non-final class 'LockFreeQueue<Element>.Node' cannot safely conform to protocol 'AtomicReference', which requires that 'Self.AtomicBaseClass' is exactly equal to 'Self'; this is an error in Swift 6
// ⚠️ Non-final class 'LockFreeQueue<Element>.Node' cannot safely conform to protocol 'AtomicOptionalWrappable', which requires that 'Self.AtomicOptionalRepresentation.Value' is exactly equal to 'Self?'; this is an error in Swift 6
// ⚠️ Non-final class 'LockFreeQueue<Element>.Node' cannot safely conform to protocol 'AtomicValue', which requires that 'Self.AtomicRepresentation.Value' is exactly equal to 'Self'; this is an error in Swift 6
The first warning is due to the In general, I'm not sure there are any constraints we can put on I'll keep thinking on this; we may need to inject some more |
|
I will also add that these warnings are also present in |
|
It seems that theoretically, we might be able to make some progress with something like public protocol AtomicReference: AnyObject, AtomicOptionalWrappable
{
associatedtype AtomicBaseClass: AtomicReference = Self
where
AtomicRepresentation: AtomicBaseClass,
AtomicOptionalRepresentation: AtomicBaseClass?
}and drop the hard requirements on equality, except the compiler won't accept inheritance requirements using |
|
A minimized representation of the problem for anyone who might want to play along at home: struct S<T>: X {}
protocol X {
associatedtype T
}
protocol Y {
associatedtype U: X
where U.T == Self
}
protocol Z: AnyObject, Y {
associatedtype V: Z = Self
where U == S<V>
}
class C: Z {} |
|
I think the best way forward is to push the public protocol AtomicValue {
/// The atomic storage representation for this value.
associatedtype AtomicRepresentation: AtomicStorage
/* where Self is a subtype of AtomicRepresentation.Value */
}
public protocol AtomicReference: AnyObject, AtomicOptionalWrappable
where
AtomicRepresentation == AtomicReferenceStorage<_AtomicBase>,
AtomicOptionalRepresentation == AtomicOptionalReferenceStorage<_AtomicBase>
{
associatedtype _AtomicBase: AnyObject = Self
}
@frozen
public struct UnsafeAtomic<Value: AtomicValue>
where Value.AtomicRepresentation.Value == Value { ... }
@_fixed_layout
public class ManagedAtomic<Value: AtomicValue>
where Value.AtomicRepresentation.Value == Value { ... }This will allow class hierarchies to conform to class Base: AtomicReference {}
class Child: Base {}
let ref: ManagedAtomic<Child>
// error: 'ManagedAtomic' requires the types 'Derived' and 'Child' be equivalentThis aligns this package with the newly enforced type system restrictions in Swift 5.7+. |
|
Thanks for taking care of this, Karoy! I haven't gotten to test in production, but the fix here seems entirely reasonable. |
From Itai on the forum: (https://forums.swift.org/t/swift-5-7-6-and-non-final-class-opt-in-to-atomicreference/58509)
Consider a class
Cls, to which we'd like to be able to make an atomic reference viaManagedAtomic. This class is intentionally the root of a class hierarchy, and we'd like to be able to make references to it, and its subclasses:This works without complaint in Swift 5.5/5.6, but in Swift 5.7, new warnings are introduced by the conformance above:
These warnings make perfect sense: as written, the constraints on the
Atomic*types all require type equality, which will clearly be violated by subclasses. (In practice, I don't believe this matters, because as stored,Clsand its subclasses all have identical layouts—just a pointer to actual storage—but happy to be corrected if this is a nontrivial mistake.)Is there guidance going forward on what to do here?
swift-atomicsno longer be able to do this?final class AtomicWrapper<T: AnyObject>: AtomicReferenceto handle this type of storage, and make references to that? Drop down toAtomicReferenceStorage/AtomicOptionalReferenceStoragedirectly? Something else?Apologies if there is already official guidance somewhere on how to handle this — in my searching, I haven't found anything definitive.
rdar://100626316
The text was updated successfully, but these errors were encountered: