You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SR-55 non-@objc protocol existentials do not conform to their own protocol type
Issue Description:
The following code that makes an Array to conform to Protocol only if all its elements conform to that same protocol fails to compile when trying to assign such array to variable declared as the protocol's type. The following is an example that reproduces the error
publicprotocolQueryStringConvertible {
varasQueryString: String { get }
}
extensionArray: QueryStringConvertiblewhereElement: QueryStringConvertible {
publicvarasQueryString: String {
returnself.reduce("") { $0.isEmpty ? $1.asQueryString : "\($0)&\($1.asQueryString)" }
}
}
extensionDictionary: QueryStringConvertiblewhereKey == String, Value: CustomStringConvertible {
publicvarasQueryString: String {
returnself.reduce("") { ($0.isEmpty ? "" : "\($0)&") + "\($1.key)=\($1.value)" }
}
}
structPerson: QueryStringConvertible {
letfirstName: StringletlastName: StringpublicvarasQueryString: String {
return"firstName=\(firstName)&lastName=\(lastName)"
}
}
funcbar<Q: QueryStringConvertible>(query: Q) -> String{
return"QUERY: " + query.asQueryString
}
funcbaz(query: QueryStringConvertible) -> String {
return"QUERY: " + query.asQueryString
}
letdictionary = [ "param1" : "value1", "param2" : "value2" ]dictionary.asQueryStringlet person = Person(firstName: "John", lastName: "Doe")
person.asQueryString
bar(query: dictionary)
bar(query: person)
bar(query: [dictionary])
bar(query: [person])
// THIS does not compile -> '<Q where Q : QueryStringConvertible> (query: Q) -> String' requires that 'Any' conform to 'QueryStringConvertible'
bar(query: [dictionary, person])
baz(query: dictionary)
baz(query: person)
baz(query: [dictionary])
baz(query: [person])
// This does not compile -> Contextual type 'QueryStringConvertible' cannot be used with array literal
baz(query: [dictionary, person])
The text was updated successfully, but these errors were encountered:
Protocol values (the type QueryStringConvertible) aren't the same as "a type that conforms to QueryStringConvertible", and the conditional conformance machinery doesn't actually look at the values in the array, just the declared element type of the Array itself. You can see SR-55 for more information, although it's not quite the same problem.
If this will work in a future version why this can be resolved at runtime but not at compile time. Are there any other restrictions that makes this harder or impossible to be implemented at compile time. I know nothing about compilers but it is quite not intuitive to me that if I declared a conditional conformance to a protocol to an Array I cannot bind it to variable of that protocol's type
It won't work in the future version. The message you're getting is saying that it can't even ask the question at the moment; once it is able to ask the question, it will not work.
@belkadan thanks for clarifying that! Can you point me to any resource that may explain the design decision behind why the compiler cannot, in this example, declare `[dictionary as QueryStringConvertible, person as QueryStringConvertible]` as type `QueryStringConvertible`. I'm curious about the design decisions or limitations.
Environment
macOS 10.13.3 (17D102)
Xcode Version 9.3 (9E145)
Additional Detail from JIRA
md5: 2d22a25cc9169583760be101f06e3eaf
relates to:
Issue Description:
The following code that makes an Array to conform to Protocol only if all its elements conform to that same protocol fails to compile when trying to assign such array to variable declared as the protocol's type. The following is an example that reproduces the error
The text was updated successfully, but these errors were encountered: