protocol Animal {} protocol Cat: Animal {} protocol Owner { associatedtype Pet var pet: Pet { get } } func callBark(_ animal: Animal){} func callPetBark<T: Owner>(_ t: T) where T.Pet : Animal { callBark(t.pet) } struct Lion: Cat {} struct GenericBreeder<T>: Owner { typealias Pet = T init(pet: T) { self.pet = pet } var pet: T } struct AnyAnimal : Animal { var value: Animal } struct AnyAnimalBreeder : Owner { init<X: Animal>(pet: X) { self.pet = AnyAnimal(value: pet) } var pet: AnyAnimal } struct ConcreteLionBreeder : Owner { typealias Pet = Lion var pet: Lion { return Lion() } } let o1 = GenericBreeder<Lion>(pet: Lion()) callPetBark(o1) let o2 = AnyAnimalBreeder(pet: Lion()) callPetBark(o2) let o3 = ConcreteLionBreeder() callPetBark(o3)