swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.36k forks source link

[SR-3085] ObjC generics are not converted via id to Any conversion #45675

Open phausler opened 8 years ago

phausler commented 8 years ago
Previous ID SR-3085
Radar None
Original Reporter @phausler
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, ClangImporter | |Assignee | None | |Priority | Medium | md5: 5dcb560a7062b4fc2511fe48e1216ddd

is duplicated by:

Issue Description:

When inspecting the generated interface of an objc class to see what it looks like in swift generics are imported as AnyObject not Any, which is inconsistent to the id to Any conversion.

@interface SomethingGeneric<AGenericType> : NSObject

- (void)doSomething:(AGenericType)aGenericThing;

@end

imports to swift as:

open class SomethingGeneric<AGenericType : AnyObject> : NSObject {
    open func doSomething(_ aGenericThing: AGenericType!)
}

Additionally the case of returning a sub-generic of a collection type incorrectly emits the reference counterparts:

@interface SomethingGeneric<AGenericType> : NSObject

- (SomethingGeneric<NSArray<NSString *> *> *)arrayOfArrayOfStrings;

@end

imports to swift as:

open class SomethingGeneric<AGenericType : AnyObject> : NSObject {
    open func arrayOfArrayOfStrings() -> SomethingGeneric<NSArray>!
}
belkadan commented 8 years ago

This is "expected" behavior in that there were reasons why this wasn't implemented other than time but I don't remember what they were. @jckarter, @DougGregor?

jckarter commented 8 years ago

The bridging generally requires type metadata, which isn't necessarily available for ObjC generic parameters, so it might be tricky to implement this.

phausler commented 8 years ago

I guess my issue with this is that the generic parameter of the class is `id` which should be imported as Any. Since all cases specifically of Any are already converted to `_SwiftValue` objects or their bridged counterpart it seems that they already emit the correct argument syntax.

The method

- (void)doSomething:(AGenericType)aGenericThing;

should be implemented as

- (void)doSomething:(id)aGenericThing;