3

Say I have the following code:

protocol A {}
struct B: A {}

func b() -> A {
    return B()
}

func f<T where T: A>(t: T) -> T {
    return t
}

f(b())

This results in the following error (Xcode 6.3 beta 3):

Playground execution failed: Test.playground:12:1: error: generic parameter 'T' cannot be bound to non-@objc protocol type 'A'

f(b())
^
Test.playground:8:6: note: in call to function 'f'
func f<T where T: A>(t: T) -> T {
     ^

I feel like this is a shortcoming with the implementation of generics in Swift. Is there a way to nicely work around this issue while still keeping the generics?

In my code f() has additional type requirements; I could just forget about protocols and generics altogether, but I don't accept defeat that easy ;-).

Bouke
  • 11,768
  • 7
  • 68
  • 102

2 Answers2

0

Implicite down casting might not be allowed here, you need to force it in the implementation of method b() :

func b () -> A {
return B() as A

}

Shripada
  • 6,296
  • 1
  • 30
  • 30
0

If you mark the protocol with @objc and change the struct to a class it will work, because then you will be in Objective C compatible territory for which different rules exist.

The reason is that in Swift protocols are not considered to be concrete implementations of themselves due to possible static requirements of the protocol and/or associated types. In my point of view this is indeed a (very annoying) shortcoming of Swift. See also issue:

Protocol doesn't conform to itself?

Werner Altewischer
  • 10,080
  • 4
  • 53
  • 60