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
Consider a hypothetical SwiftPM package (a tarball containing a sample package is attached) that has two modules, First and Second. The module Second defines a type called Test with the following definition:
publicstructTest {
publicinit(vals: [(Bool, Bool)] = []) {
print("Initialized with one argument")
}
}
The module First defines an extension to Test to conform it to ExpressibleByDictionaryLiteral, and then runs some code:
Imagine, then, that the source code of Second is changed to be this instead:
publicstructTest {
publicinit(_vals: [(Bool, Bool)] = [], _other: Bool = false) {
print("Initialized with two arguments")
}
}
When the new program, whose only difference is the addition of an argument with a default value in its only initializer, is compiled and run, the following compile error occurs:
It seems to me that this behaviour is inconsistent. The situation is, to my eye, no more ambiguous than it was before. It's clear to see that any of the functions in question may be selected as an implementation of a zero-argument initializer. It's even clear enough that needing to provide two default arguments instead of one should make the new initializer in Second a lower priority choice than the old one.
What is less clear is why having two-or-more optional arguments is considered the same level of fittedness to calling a variadic initialiser with zero entries. I would make the case that either both of the initializers in Second should be considered higher priority than the variadic initializer in First, or neither of them should.
There are multiple workarounds for this, but in general this has the effect of meaning that if you create a type that:
has at least one initializer that takes two or more arguments, all of which are optional; AND
has no initializers that take fewer than two arguments
can never safely be given a variadic initializer, and so can never safely be conformed to almost any of the ExpressibleBy family of protocols.
The text was updated successfully, but these errors were encountered:
@Lukasa I think I actually fixed this issue couple of month ago and it's supposed to prefer overloads with fewer defaults which means that it second case it's going to prefer `init(dictionaryLiteral: )`, that does work on master right now in the single file setup, but I haven't tried putting declaration and extension in different modules before, going to give it a try.
Attachment: Download
Environment
Swift 4.1, macOS
Additional Detail from JIRA
md5: 19d9fd7011045b280429da1adce83a41
Issue Description:
Bumped into on the SwiftNIO 1.4.0 release.
Consider a hypothetical SwiftPM package (a tarball containing a sample package is attached) that has two modules, First and Second. The module Second defines a type called
Test
with the following definition:The module First defines an extension to
Test
to conform it toExpressibleByDictionaryLiteral
, and then runs some code:When compiled and run, this program outputs:
Imagine, then, that the source code of Second is changed to be this instead:
When the new program, whose only difference is the addition of an argument with a default value in its only initializer, is compiled and run, the following compile error occurs:
It seems to me that this behaviour is inconsistent. The situation is, to my eye, no more ambiguous than it was before. It's clear to see that any of the functions in question may be selected as an implementation of a zero-argument initializer. It's even clear enough that needing to provide two default arguments instead of one should make the new initializer in Second a lower priority choice than the old one.
What is less clear is why having two-or-more optional arguments is considered the same level of fittedness to calling a variadic initialiser with zero entries. I would make the case that either both of the initializers in Second should be considered higher priority than the variadic initializer in First, or neither of them should.
There are multiple workarounds for this, but in general this has the effect of meaning that if you create a type that:
has at least one initializer that takes two or more arguments, all of which are optional; AND
has no initializers that take fewer than two arguments
can never safely be given a variadic initializer, and so can never safely be conformed to almost any of the
ExpressibleBy
family of protocols.The text was updated successfully, but these errors were encountered: