Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2104] Calling through to other ObjC methods in a subscript shouldn't require reifying the generic params #44712

Open
jessesquires opened this issue Jul 18, 2016 · 11 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@jessesquires
Copy link

Previous ID SR-2104
Radar None
Original Reporter @jessesquires
Type Bug
Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: cb424a02266daae33d6db3d626d1d262

Issue Description:

The warnings "extension of a generic Objective-C class cannot access the class's generic parameters at runtime" seem to be too strict

See discussions here:
https://twitter.com/jesse_squires/status/755063937805148160
https://twitter.com/slava_pestov/status/755061319456260096

Fails to compile:

private extension Cache {

    subscript(key: KeyType) -> ObjectType? {
        get {
            return object(forKey: key)
        }
        set {
            if let value = newValue {
                setObject(value, forKey: key)
            } else {
                removeObject(forKey: key)
            }
        }
    }
}

Version 8.0 beta (8S128d)

@jessesquires
Copy link
Author

/cc @slavapestov @jckarter – not sure if this is the best title/description

@jckarter
Copy link
Member

I think this is related to subscripts (unless you're seeing the same in regular methods too).

@jessesquires
Copy link
Author

I'm seeing this in regular methods, too. Generally speaking, I'm running into a lot of issues with ObjC classes that have newly added lightweight generics. In particular: `NSFetchRequest` and `NSFetchedResultsController`

@jessesquires
Copy link
Author

Another failing example:

extension NSFetchedResultsController {

    public func items(inSection section: Int) -> [ResultType]? {
        return sections?[section].objects as! [ResultType]?
    }

}

@jckarter
Copy link
Member

Ah, that might be a related issue with bridged types such as Array. The bridging does require reified generic params as currently implemented; we haven't correctly implemented it in a way that avoids that.

@swift-ci
Copy link
Collaborator

Comment by Marcas Burnett (JIRA)

Same issue with PHFetchResult in PhotoKit:

extension PHFetchResult {
public func toArray<T>() -> [T] {
var array = [T]()
array.reserveCapacity(count)

// can't use trailing closure syntax due to compiler complaints of ambiguity due to method renaming in Swift 3
enumerateObjects({ (obj, _, _) in
array.append(obj as! T)
})

return array
}
}

Error on func declaration line: Extension of a generic Objective-C class cannot access the class's generic parameters at runtime.

1) This is a compile time error, not a run time one, and I'm not casting the type at all.
2) I'm not even accessing the generic type from objc in the signature or as the array type.
3) When rewritten not to be a generic function at all (just return [PHObject]), it still fails to compile, giving the same error.

@jckarter
Copy link
Member

mburnett (JIRA User) In that case the error is correct. Building [T] and performing the as! T cast both require having the type metadata for T available at runtime.

@swift-ci
Copy link
Collaborator

Comment by Marcas Burnett (JIRA)

@jckarter I actually played around with it some more: I changed array to be [PHObject] and the function to return the same, commented out the array.append(...) line altogether and still had the same error. I changed PHObject to Any: same error. By process of elimination, I actually found out that it's the use of enumerateObjects( _ : ) that causes the error. The block parameter's type uses ObjectType, PHFetchResult's generic parameter. When I remove the call to enumerateObjects( _ : ), the error disappears.

However, I'm still at a loss as to what to do. This worked fine in Swift 2.2 (or iOS SDK v9). It seems like introducing more type information in iOS 10 has made it impossible to call this method from Swift at all. Furthermore, after the renaming of SDK methods in Swift 3, the compiler complains of ambiguity when calling this method with trailing closure syntax.

@swift-ci
Copy link
Collaborator

Comment by Marcas Burnett (JIRA)

Also, in the previous version of the function, T was my own generic parameter, not ObjectType which is declared as a type parameter of PHFetchResult. So it seems like the type metadata for T would be available, since T was declared in Swift. I don't understand why introducing my own generic parameter necessitates knowledge of the type's generic parameter, but I'm sure I'm missing something.

@jckarter
Copy link
Member

mburnett (JIRA User) I may have misinterpreted the code. In any case, being able to call enumerateObjects should be fine. The ambiguity sounds like a separate bug that deserves filing, if you haven't already.

You can try casting away the generic parameter on PHFetchResult by saying let nongenericSelf = self as! PHFetchResult<PHObject> first thing, which should allow operations on `nongenericSelf` without requiring PHFetchResult's generic parameter info.

@swift-ci
Copy link
Collaborator

Comment by Marcas Burnett (JIRA)

I will file one.

Your suggestion made sense and looked promising until I typed this much and got the same error:

extension PHFetchResult {
func toArray<T>() -> [T] {

}
}

I guess I will just make a utility class that takes the specialized type of PHFetchResult for now. Thanks for the help.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

3 participants