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-7343] Generic constraint fails to infer type when expecting sub protocol #49891

Closed
igorcferreira opened this issue Apr 3, 2018 · 3 comments
Closed
Assignees

Comments

@igorcferreira
Copy link

@igorcferreira igorcferreira commented Apr 3, 2018

Previous ID SR-7343
Radar rdar://problem/39215862
Original Reporter @igorcferreira
Type Bug
Status Resolved
Resolution Done
Environment

Xcode Version 9.3 (9E145)

$ swift --version
Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
Target: x86_64-apple-darwin17.5.0
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug
Assignee @igorcferreira
Priority Medium

md5: 84b2a530941991d3fb156f636ab75f11

relates to:

  • SR-55 non-@objc protocol existentials do not conform to their own protocol type

Issue Description:

When trying to receive a sub-protocol from a generic method constrained by a parent protocol, the compiler fails, returning an error saying that the "Generic parameter 'T' could not be inferred":

 protocol Parent {
     var title: String { get }
 }

protocol Child: Parent {
     var subtitle: String { get }
 }

func genericConstraint<T: Parent>(options: [String: Any], completion: (T)->Void) {
     //Create concrete implementation based on options passed
 }

//The compiler fails to accept 'Child' as type with the error message "Generic parameter 'T' could not be inferred"
 genericConstraint(options: [:]) { (child:Child) in
     //The compiler mistakenly throws the error "Ambiguous reference to member 'print(_:separator:terminator)'"
     print(response.subtitle)
 }

This constraints could be useful when having multiple types (like structs Child1, and Child2) that could be create based on different options, also, when "hidding" types under protocol, like abstracting CoreData implementation from other app layers.

@belkadan
Copy link
Contributor

@belkadan belkadan commented Apr 5, 2018

It's a bad error message, but it's correct that this doesn't compile: the type Child doesn't itself conform to the protocol Parent. You have to use a concrete type here.

(I don't know if the language has a way to spell what you're trying to do, "any protocol value where the protocol inherits from the original type".)

cc @huonw for the feature and @xedin for the diagnostic

@xedin
Copy link
Member

@xedin xedin commented Apr 5, 2018

@swift-ci create

@xedin
Copy link
Member

@xedin xedin commented Sep 10, 2021

The diagnostic for this issue has been improved in Xcode 13 (changing `response` to `child.subtitle` because it doesn't exist):

 error: protocol 'Child' as a type cannot conform to 'Parent'
 genericConstraint(options: [:]) { (child:Child) in
 ^
 note: only concrete types such as structs, enums and classes can conform to protocols
 genericConstraint(options: [:]) { (child:Child) in
 ^
note: required by global function 'genericConstraint(options:completion:)' where 'T' = 'Child'
func genericConstraint<T: Parent>(options: [String: Any], completion: (T)->Void) {
     ^

Please use either Xcode 13 or main branch snapshot to verify and close this issue.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants