Unable to use associatedType as method returnType in swift as compiler throws "Ambiguous inference of associated type"

314 Views Asked by At

Was playing with associatedType. Compiler is not recognising the return type of the method when using associatedType.

Here is the code sample,

protocol DummyOffice {
}

struct EmptyOffice: DummyOffice {
}

protocol  Office {
    associatedtype SubBranch: DummyOffice
    var subBranch: SubBranch { get }
    func getSubBranch() -> SubBranch
}

struct Apple: Office {
    let emptyOffice = EmptyOffice()
    func getSubBranch() -> some DummyOffice {
        return EmptyOffice()
    }
    
    var subBranch: some DummyOffice {
        return EmptyOffice()
    }
}

and compiler throws this error.

enter image description here

Questions:

(1) Error is not occurring for the property "subBranch". Thats is if I didn't create a method that returns associatedType in the protocol, everything works smooth.

2

There are 2 best solutions below

1
jshapy8 On BEST ANSWER

Using an opaque return type (i.e. some) is not required for what you want to do. When you go to implement the Office protocol, just return the actual type from the function and computed property you specified and the compiler will infer the associatedtype for you:

protocol DummyOffice {}

struct EmptyOffice: DummyOffice {}

protocol Office {
    associatedtype SubBranch: DummyOffice
    var subBranch: SubBranch { get }
    func getSubBranch() -> SubBranch
}

struct Apple: Office {
    let emptyOffice = EmptyOffice()
    func getSubBranch() -> EmptyOffice {
        return EmptyOffice()
    }
    
    var subBranch: EmptyOffice {
        return EmptyOffice()
    }
}
0
Sujananth On

As @zaitsman suggested , replacing associatedTypes with typealias is working good.

But typealias cannot be used as psuedo generic constraint,

protocol DummyOffice {
}

struct EmptyOffice: DummyOffice {
}

protocol  Office {
    typealias SubBranch =  DummyOffice
    var subBranch: SubBranch { get }
    func getSubBranch() -> SubBranch
}

struct Apple: Office {
    var subBranch: Self.SubBranch
    
    func getSubBranch() -> Self.SubBranch {
        return EmptyOffice()
    }
    
}