I'm having trouble assigning to a closure variable with type erased arguments. It seems to me that something like this should work:
class TypeErasedKeyPaths {
var root:AnyObject?
var keypath:AnyKeyPath?
var action:((AnyObject,AnyKeyPath)->Void)?
func takeit<T:AnyObject>(r:T,
kp:PartialKeyPath<T>,
a:@escaping (T,PartialKeyPath<T>)->Void)
{
self.root = r // works
self.keypath = kp // works
self.action = a // Cannot assign value of type '(T, PartialKeyPath<T>) -> Void' to type '((AnyObject, AnyKeyPath) -> Void)?'
}
}
Is this the same bug as SR-6740/SR-5667?
Is there any trick I can use to make this work?
I think the compiler is right. Consider a simpler example:
protocol Animal {
var weapon: String { get } // All animals have a weapon of some sort.
}
struct Slug: Animal {
var weapon: String { return "poison" }
}
struct Cat: Animal {
var weapon: String { return "claws" }
var noise: String { return "meow" } // Not all animals make a noise.
}
func weapon(a: Animal) -> String { return a.weapon }
func noise(c: Cat) -> String { return c.noise }
struct ApplyLater {
let a: Animal
let f: (Animal) -> String
var apply: String { return f(a) }
}
let slugWeapon = ApplyLater(a: Slug(), f: weapon(a:)) // OK
let catWeapon = ApplyLater(a: Cat(), f: weapon(a:)) // OK
// let slugNoise = ApplyLater(a: Slug(), f: noise(c:)) // ERROR: Obvious that this doesn't work because a slug doesn't make a noise.
// let catNoise = ApplyLater(a: Cat(), f: noise(c:)) // ERROR: Not so obvious that this doesn't work because a cat does make a noise. However it is typed as an `Animal` and an animal doesn't necessarily make a noise.
You are doing the equivalent of the catNoise example and it fails because not all animals can make a noise.
For future reference, you declare variables with wider type than the things you assign to them (e.g. put a dog into an Animal type), but when you have closures, the arguments you declare must be equal to or narrower than what you assign to them. (e.g. declared to accept Dog, so you can assign a function that takes an Animal).