Protocol assosiatedtype conformance confussion

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 by where 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 assigning firstVar to ThirdClass 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

Terms of Service

Privacy Policy

Cookie Policy