[SR-1297] Method parameters list interpreted as a single tuple (tuple "unsplat"), making behavior disturbing #43905
Labels
bug
A deviation from expected or documented behavior. Also: expected but undesirable behavior.
compiler
The Swift compiler in itself
type checker
Area → compiler: Semantic analysis
Environment
Swift 2.2 & Swift 3.0
Tested in Swift REPL 2.2
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
Target: x86_64-apple-macosx10.9
Tested in IBM Swift Sandbox 3.0
https://swiftlang.ng.bluemix.net/
"Ver. 3.0 (Mar 24, 2016)"
Additional Detail from JIRA
md5: c93d61c824e21df530ad3b1e7dc31e2c
is duplicated by:
relates to:
Issue Description:
Description
When there exists a method that takes an unnamed, unconstrained generic argument, like
foo<T>(x: T)
, calling that method with any number of named or unnamed arguments is interpreted as being a single tuple argument, which makes it very confusing.Typical example:
String(format:…)
The typical example that made me first encounter this behavior is using
String(format: )
without importingFoundation
.After some investigation I realized it's because
String(format: )
is not defined without importingFoundation
but instead of having a compiler error, it interprets that call as:Thus interpreting the expression as a single tuple argument and converting it to its string representation.
This is because the compiler matches the call with the definition of
String.init<T>(_ v: T)
, which is possible only because the compiler allows itself to interpret the arguments as a tuple being "unsplatted" — and makingT
match that tuple type.This means that any similar call with arbitrary arguments, like
String(foo: 5, bar: true, baz: "whoops")
also compiles, instead of being reported as a compilation error.How to Reproduce
Actual Result
The parameter list is interpreted as a single argument of type tuple, like a "tuple unsplat" operation, making the behavior disturbing, and the compiler magic masking what should be reported as a compilation error.
Expected Result
The compiler should not auto-wrap the parameters in a tuple implicitly, and instead generate a compilation error stating that there is no method
String.init(format: )
defined (or suggesting to use an explicit tuple).Note: don't confuse w/ Swift 3 removal of tuple splatting
I know that tuple splatting will be removed in Swift 3.0, but this behavior is kinda the opposite of tuple splatting, as it implicitly wraps a parameters list into a tuple, instead of unwrapping a tuple into a parameter list.
Tuple splatting (passing a tuple of 2 values a a single argument to a function expecting 2 arguments) already do produce a proper depreciation warning in Swift 3.0. But the code described above in this issue (which is the opposite, passing 2 arguments to a method expecting one tuple) does NOT produce any warning.
That's why I'm not sure the removal of tuple splatting in Swift 3.0 will fix this behavior too — being somehow a different (even the opposite) mechanism — and if this opposite behavior (tuple "unsplatting") was also considered for removal too already or not.
The text was updated successfully, but these errors were encountered: