I seem to be running into what appears to be a compiler inconsistency when passing arguments to a generic function that has a protocol restriction. I can pass a concrete argument, but not an argument as a protocol type
protocol Selectable {
func select()
}
protocol Log : Selectable {
func write()
}
class DefaultLog : Log {
func select() {
print("selecting")
}
func write() {
print("writing")
}
}
let concrete = DefaultLog()
let proto: Log = DefaultLog()
func myfunc<T: Selectable>(arg: T) {
arg.select()
}
myfunc(concrete) // <-- This works
myfunc(proto) // <-- This causes a compiler error
proto.write() // <-- This works fine
The compiler reports:
error: cannot invoke 'myfunc' with an argument list of type '(Log)'
myfunc(proto)
^
note: expected an argument list of type '(T)'
myfunc(proto)
^
If I restrict the function to the Selectable or Log protocol it still fails.
Is this a compiler bug? Any thoughts?
If you are using a protocol, it doesn't need to be generic:
func myfunc(arg: Selectable) {
arg.select()
}
I believe that T
needs to be a concrete type for generics.