After converting from Swift 2.2 to 3.0 my Array
extension does not compile anymore, because it contains a call to global standard library function min<T>(T,T)
and shows compiler error extra argument in call
.
Here's a simple way to reproduce the error:
extension Array {
func smallestInt(first: Int, second: Int) -> Int {
return min(first, second) // compiler error: "Extra argument in call"
}
}
I get the same error when adding the same function to an extension of Dictionary
, while the exact same code compiles just fine in an extension of other types (e.g. String
or AudioBuffer
):
Looking at the documentation of Array
and Dictionary
, I find that there are instance methods on Sequence
named public func min() -> Element?
and public func min(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element?
. While both String
and AudioBuffer
do not have any kind of min(...)
function.
Is it possible that this is the reason why I can't call the global function? The compiler can't distinguish between global func min<T>(T,T)
and self.min(...)
although they have completely different signatures?
Is this a bug or a feature? What am I doing wrong? How can I call min(T,T)
correctly inside an Array
extension?
I see no reason why the compiler shouldn't be able to resolve this function call, therefore I would consider it a bug (it has already been filed – see SR-2450).
It seems to occur whenever attempting to call a top-level function with the same name, but unambiguously different signature to a method or property that's accessible from the same scope in a given type (instance or static).
An even simpler example would be:
Until fixed, a simple solution would be to prefix the call with the name of the module in which it resides in order to disambiguate that you're referring to the top-level function, rather than the instance one. For the standard library, that's
Swift
:In Swift 4, the compiler has a better diagnostic for this error (though the fact that it's still an error is a bug IMO):
Although what's interesting is that the compiler will now also warn on attempting to call a standard library method with the same name as a stdlib top-level function:
In this case, as the warning says, you can silence it by using an explicit
self.
:Although what's really curious about this warning is it doesn't appear to extend to non-stdlib defined functions: