Open bjhomer opened 3 weeks ago
I found the following workaround:
public class C {}
public protocol P1 {
associatedtype PetType: P2 where PetType.OwnerType == Self
}
// ⚠️ Protocol '_P2' should be declared to refine 'P2' due to a same-type constraint on 'Self'
public protocol _P2: AnyObject {
associatedtype OwnerType: P1 where OwnerType.PetType == Self
}
public protocol P2: _P2, C {}
Declaring _P2
to refine "AnyObject" instead of "C" resolves the conflict. And then P2
refines _P2
by adding an additional constraint for the class we actually care about.
This does produce a warning, but the code appears to compile correctly.
cc @slavapestov
class C {}
public protocol P1 {
associatedtype PetType: P2 where PetType.OwnerType == Self
}
public protocol P2: C {
associatedtype OwnerType: P1 where OwnerType.PetType == Self
}
This is actually invalid because it forces P2's Self to be exactly C
, and not just a subclass, via the same-type requirement.
However, it shouldn't crash!
FWIW, in 5.10, this diagnoses:
class C {}
protocol P1 {
associatedtype PetType: P2 where PetType.OwnerType == Self
}
protocol P2: C {
associatedtype OwnerType: P1 where OwnerType.PetType == Self
}
class D: C, P2 { // warning: non-final class 'D' cannot safely conform to protocol 'P2', which requires that 'Self.OwnerType.PetType' is exactly equal to 'Self'; this is an error in Swift 6
typealias OwnerType = O
}
struct O: P1 {
typealias PetType = D
}
Thanks for the update.
This is actually invalid because it forces P2's Self to be exactly C, and not just a subclass, via the same-type requirement.
Is it that it's exactly equal to C
? Or just that it must a final
class to rule out subclasses? I'm not following how the constraints would require it to be exactly C. In your last example, if class D
were final
, does it still diagnose?
Description
We have two protocols that describe two related types, which have associatedtype declarations that tie them to each other. In the Swift 6.0 compiler in Xcode 16.0 (b1), the compiler crashes when compiling this code. The Swift 5.10 compiler did not crash on this code.
Motivation: In our particular use case, this code is describing two related types: a type that represents the JSON structure of a particular object, and another type that represents the type used to represent this in our local database.
Reproduction
Removing the class constraint (
P2: C
) or either of thewhere
clauses avoids the crash.Stack dump
Expected behavior
The two protocols should be constrained so types can only conform if they come in pairs.
Environment
Apple Swift version 6.0 (swiftlang-6.0.0.3.300 clang-1600.0.20.10)
Additional information
No response