Possible compiler bug? Unable to extend a type whose name clashes


(E. Maloney) #1

I recently ran into a situation where I needed to import a symbol with the same name from two different modules, and noticed that the usual Swift technique of disambiguating using the package name doesn't work when used with extensions.

In my case, I have a package 'LegacyStore' and a package 'AppleTart', both of which contain a type named 'User'.

In the case of LegacyStore, User is an Objective-C class, and in the case of AppleTart, User is a Swift struct.

Normally, I'd be able to refer to one as 'LegacyStore.User' and the other as 'AppleTart.User', but when using this notation for an extension:

    extension AppleTart.User
    {
        public var legacyUser: LegacyStore.User {
            // implementation
        }
    }

...I get a compiler error on the extension declaration line:

    error: 'User' is not a member type of 'AppleTart'

Note that the 'LegacyStore.User' notation used in the var declaration never triggers a compiler error, so I'm assuming the notation just isn't supported yet in the context of declaring an extension.

Fortunately, there's a (somewhat cumbersome) work-around, which is to create two separate files, one for each module. Within each file import just that one module, and create a typealias for each clashing name using package-qualified name of the type.

For example, here's the relevant part of my AppleTartTypeDisambiguation.swift file:

    import AppleTart

    public typealias AppleTartUser = User

And here's my LegacyStoreTypeDisambiguation.swift file:

    import LegacyStore

    public typealias LegacyUser = User

I can then use the typealiases to extend either type. For example, here's how I successfully extended AppleTart.User:

    extension AppleTartUser
    {
        public var legacyUser: LegacyStore.User {
            // implementation
        }
    }

Should the inability to extend a type using the qualified type name be considered a compiler bug? I'm assuming yes. If so, I'll file a ticket.


(Jordan Rose) #2

Hi, Evan. Just a suspicion: do you also have a type named AppleTart? In that case you'd be hitting SR-898 <https://bugs.swift.org/browse/SR-898>, rather than a specific issue with extensions.

Jordan

···

On Mar 8, 2016, at 14:26, Evan Maloney via swift-users <swift-users@swift.org> wrote:

I recently ran into a situation where I needed to import a symbol with the same name from two different modules, and noticed that the usual Swift technique of disambiguating using the package name doesn't work when used with extensions.

In my case, I have a package 'LegacyStore' and a package 'AppleTart', both of which contain a type named 'User'.

In the case of LegacyStore, User is an Objective-C class, and in the case of AppleTart, User is a Swift struct.

Normally, I'd be able to refer to one as 'LegacyStore.User' and the other as 'AppleTart.User', but when using this notation for an extension:

   extension AppleTart.User
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

...I get a compiler error on the extension declaration line:

   error: 'User' is not a member type of 'AppleTart'

Note that the 'LegacyStore.User' notation used in the var declaration never triggers a compiler error, so I'm assuming the notation just isn't supported yet in the context of declaring an extension.

Fortunately, there's a (somewhat cumbersome) work-around, which is to create two separate files, one for each module. Within each file import just that one module, and create a typealias for each clashing name using package-qualified name of the type.

For example, here's the relevant part of my AppleTartTypeDisambiguation.swift file:

   import AppleTart

   public typealias AppleTartUser = User

And here's my LegacyStoreTypeDisambiguation.swift file:

   import LegacyStore

   public typealias LegacyUser = User

I can then use the typealiases to extend either type. For example, here's how I successfully extended AppleTart.User:

   extension AppleTartUser
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

Should the inability to extend a type using the qualified type name be considered a compiler bug? I'm assuming yes. If so, I'll file a ticket.

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(E. Maloney) #3

Thanks a lot, Jordan; your suspicion is correct! That appears to be the issue I'm having--although unlike what's captured in the JIRA ticket, in my case there are no generics involved.

Would you mind if I updated this ticket with the additional info related to the scenario I hit?

···

On Mar 8, 2016, at 5:41 PM, Jordan Rose <jordan_rose@apple.com> wrote:

Hi, Evan. Just a suspicion: do you also have a type named AppleTart? In that case you'd be hitting SR-898 <https://bugs.swift.org/browse/SR-898>, rather than a specific issue with extensions.

Jordan

On Mar 8, 2016, at 14:26, Evan Maloney via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I recently ran into a situation where I needed to import a symbol with the same name from two different modules, and noticed that the usual Swift technique of disambiguating using the package name doesn't work when used with extensions.

In my case, I have a package 'LegacyStore' and a package 'AppleTart', both of which contain a type named 'User'.

In the case of LegacyStore, User is an Objective-C class, and in the case of AppleTart, User is a Swift struct.

Normally, I'd be able to refer to one as 'LegacyStore.User' and the other as 'AppleTart.User', but when using this notation for an extension:

   extension AppleTart.User
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

...I get a compiler error on the extension declaration line:

   error: 'User' is not a member type of 'AppleTart'

Note that the 'LegacyStore.User' notation used in the var declaration never triggers a compiler error, so I'm assuming the notation just isn't supported yet in the context of declaring an extension.

Fortunately, there's a (somewhat cumbersome) work-around, which is to create two separate files, one for each module. Within each file import just that one module, and create a typealias for each clashing name using package-qualified name of the type.

For example, here's the relevant part of my AppleTartTypeDisambiguation.swift file:

   import AppleTart

   public typealias AppleTartUser = User

And here's my LegacyStoreTypeDisambiguation.swift file:

   import LegacyStore

   public typealias LegacyUser = User

I can then use the typealiases to extend either type. For example, here's how I successfully extended AppleTart.User:

   extension AppleTartUser
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

Should the inability to extend a type using the qualified type name be considered a compiler bug? I'm assuming yes. If so, I'll file a ticket.

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Jordan Rose) #4

Sure, go ahead. (The associated Radar also deals with a non-generic type; sorry I didn't include that in the SR.)

Jordan

···

On Mar 9, 2016, at 8:23 , Evan Maloney <emaloney@gilt.com> wrote:

Thanks a lot, Jordan; your suspicion is correct! That appears to be the issue I'm having--although unlike what's captured in the JIRA ticket, in my case there are no generics involved.

Would you mind if I updated this ticket with the additional info related to the scenario I hit?

On Mar 8, 2016, at 5:41 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

Hi, Evan. Just a suspicion: do you also have a type named AppleTart? In that case you'd be hitting SR-898 <https://bugs.swift.org/browse/SR-898>, rather than a specific issue with extensions.

Jordan

On Mar 8, 2016, at 14:26, Evan Maloney via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I recently ran into a situation where I needed to import a symbol with the same name from two different modules, and noticed that the usual Swift technique of disambiguating using the package name doesn't work when used with extensions.

In my case, I have a package 'LegacyStore' and a package 'AppleTart', both of which contain a type named 'User'.

In the case of LegacyStore, User is an Objective-C class, and in the case of AppleTart, User is a Swift struct.

Normally, I'd be able to refer to one as 'LegacyStore.User' and the other as 'AppleTart.User', but when using this notation for an extension:

   extension AppleTart.User
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

...I get a compiler error on the extension declaration line:

   error: 'User' is not a member type of 'AppleTart'

Note that the 'LegacyStore.User' notation used in the var declaration never triggers a compiler error, so I'm assuming the notation just isn't supported yet in the context of declaring an extension.

Fortunately, there's a (somewhat cumbersome) work-around, which is to create two separate files, one for each module. Within each file import just that one module, and create a typealias for each clashing name using package-qualified name of the type.

For example, here's the relevant part of my AppleTartTypeDisambiguation.swift file:

   import AppleTart

   public typealias AppleTartUser = User

And here's my LegacyStoreTypeDisambiguation.swift file:

   import LegacyStore

   public typealias LegacyUser = User

I can then use the typealiases to extend either type. For example, here's how I successfully extended AppleTart.User:

   extension AppleTartUser
   {
       public var legacyUser: LegacyStore.User {
           // implementation
       }
   }

Should the inability to extend a type using the qualified type name be considered a compiler bug? I'm assuming yes. If so, I'll file a ticket.

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users