[swift-evolution] Binding generic types using a metatype parameter

Joanna Carter joanna at carterconsulting.org.uk
Thu Mar 24 18:04:34 CDT 2016


Hi Joe

> Sorry for not getting back to you sooner.

Hey, I'm guessing you're busier than I am ;-)

> What's necessary here is a way to "open" the type of Any.Type, turning it back into something the compiler considers as a type instead of a value.

Yes, that's what I had in mind

> This is something we've discussed having better support for, but right now there's only a sneaky way to do it using protocol extensions. If you constrain Property's type parameter to a protocol:
> 
> protocol PropertyType {}
> struct Property<T: PropertyType>: PropertyProtocol {}
> 
> then you can add a static method to PropertyType in an extension, which can use Self as the opened dynamic type:
> 
> extension PropertyType {
>   private static func create() -> Property<Self> {
>     return Property<Self>.init()
>   }
> }

Unfortunately, this doesn't compile…

extension PropertyType
{
  private static func create() -> Property<Self>
  {
    return Property<Self>.init()
                                        ^ '>' is not a postfix unary operator
  }
}

Which is why I found it necessary to add a typealias like so…

extension PropertyType
{
  private static func create() -> Property<Self>
  {
    typealias SelfType = Self
    
    return Property<SelfType>.init()
  }
}

> and delegate to that extension method in your factory function:
> 
> struct PropertyFactory {
>   static func createBoundPropertywithValueType(valueType: PropertyType.Type) -> PropertyProtocol
>   {
>     return valueType.create()
>   }
> }

This doesn't compile either…

struct PropertyFactory
{
  static func createBoundPropertywithValueType(valueType: PropertyType.Type) -> PropertyProtocol
  {
    return valueType.create()
                ^ Member 'create' cannot be used on value of protocol type 'PropertyType'; use a generic constraint instead
  }
}

For some reason, as soon as you change the PropertyType extension static func to return PropertyProtocol…

extension PropertyType
{
  private static func create() -> PropertyProtocol
  {
    typealias SelfType = Self
    
    return Property<SelfType>.init()
  }
}

… then, and only then, the factory's method compiles correctly.

Am I really finding bugs or am I still doing something wrong?

Joanna

--
Joanna Carter
Carter Consulting



More information about the swift-evolution mailing list