Hello,
i've came across an unexpected behaviour with protocols which i'd like to discuss.
Consider properly working example:
protocol FirstProtocol {
associatedtype Associatedtype
var firstVar: Associatedtype? { get }
}
protocol SecondProtocol: FirstProtocol where Associatedtype == ThirdProtocol { }
protocol ThirdProtocol: class { }
protocol FourthProtocol: FirstProtocol{ }
protocol FifthProtocol: class { }
// ----
final class FirstClass: SecondProtocol {
weak var firstVar: ThirdProtocol?
}
final class SecondClass: FourthProtocol {
typealias Associatedtype = FifthProtocol
weak var firstVar: FifthProtocol?
}
// ----
final class ThirdClass {
func firstFunc() {
let firstClass = FirstClass()
firstClass.firstVar = self
}
func secondFunc() {
let secondClass = SecondClass()
secondClass.firstVar = self
}
}
extension ThirdClass: FirstClass.Associatedtype { }
extension ThirdClass: SecondClass.Associatedtype { }
Whole structure should be self explanatory, but these marked classes are crucial here, i'm using protocols as existential types.
-
FirstClass
is conforming to protocol which has its assosiatedtype determined bywhere
constrain so we dont need to specify it within its body. -
SecondClass
has to specify its assosiatedtype explicitly because it doesnt know what that type would be. -
ThirdClass
is where we initializing both mentioned classes within separate functions and assigningfirstVar
toThirdClass
instance as it's conforming to both Associatedtypes in its extension by referencing them as classes nested types
Now, the part that gets me confused, whenever we try to move that marked piece od code (both classes) to a separate swift file, ThirdClass
is not conforming anymore to FirstClass.Associatedtype
, which occurs like this:
protocol FirstProtocol {
associatedtype Associatedtype
var firstVar: Associatedtype? { get }
}
protocol SecondProtocol: FirstProtocol where Associatedtype == ThirdProtocol { }
protocol ThirdProtocol: class { }
protocol FourthProtocol: FirstProtocol{ }
protocol FifthProtocol: class { }
final class ThirdClass {
func firstFunc() {
let firstClass = FirstClass()
firstClass.firstVar = self // ERROR: Cannot assign value of type 'ThirdClass' to type 'ThirdProtocol?'
}
func secondFunc() {
let secondClass = SecondClass()
secondClass.firstVar = self
}
}
extension ThirdClass: FirstClass.Associatedtype { }
extension ThirdClass: SecondClass.Associatedtype { }
Well, autocompletion is showing FirstClass.Associatedtype
as ThirdProtocol
.
Why it's happening only with where
clause declaration while moved to separate file?
Many thanks