Instantiating a generic class with a protocol type


(Matthias Zenger) #1

Hi everyone,

I'm puzzled by the following behaviour in Swift 2.2. This code compiles and
behaves as expected:

  protocol Executable {}
  class Box<T: Any> {}
  let box = Box<Executable>()

If I now replace the type constraint on T with Executable, I'm getting a
compiler error:

  protocol Executable {}
  class Box<T: *Executable*> {}
  let box = Box<Executable>()

From a type-theoretic perspective, I can't see why instantiating class Box

with type Executable should be prohibited. Also the corresponding error
message isn't really providing more insights: "Using 'Executable' as a
concrete type conforming to protocol 'Executable' is not supported".

Where can I find more about this behaviour in the Swift Language
Specification? Is this a known bug?

Thanks,
  Matthias


(Joe Groff) #2

It's a known limitation. Protocol types aren't yet considered to conform to their own protocol as generic constraints. There are some language design difficulties here that need to be addressed before we can support this, since a type-erased protocol value isn't always a model of its protocol; for instance, if it has static or initializer requirements, the protocol type itself has no type-level operations, so can't satisfy those requirements itself. With resilience, a public protocol has the ability to introduce new requirements in the future that may break its self-conformance as well.

-Joe

···

On Apr 11, 2016, at 9:33 AM, Matthias Zenger via swift-users <swift-users@swift.org> wrote:

Hi everyone,

I'm puzzled by the following behaviour in Swift 2.2. This code compiles and behaves as expected:

  protocol Executable {}
  class Box<T: Any> {}
  let box = Box<Executable>()

If I now replace the type constraint on T with Executable, I'm getting a compiler error:

  protocol Executable {}
  class Box<T: Executable> {}
  let box = Box<Executable>()

From a type-theoretic perspective, I can't see why instantiating class Box with type Executable should be prohibited. Also the corresponding error message isn't really providing more insights: "Using 'Executable' as a concrete type conforming to protocol 'Executable' is not supported".

Where can I find more about this behaviour in the Swift Language Specification? Is this a known bug?