- Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
Description
When I pass a literal expression as an argument to a generic function and compare its return value to another literal with a binary operator, the == case is not a problem, but ! = causes the type inference failure and a compilation error.
I have confirmed that some cases compile correctly in Swift 4.2.3. Also, the difference between == and ! = operators gives different type inference results on either side, which seems odd. So this seems to be some kind of regression in Swift 5.
Steps to reproduce
- Define the following generic function:
func f<T>(_ val: T) -> T { return val }- Use the function in the following code segments a and b:
let i = 0 _ = f([0]).firstIndex(of: 0) == i // a _ = f([0]).firstIndex(of: 0) != i // b // ErrorThe Swift compiler produces a compilation error for code segment b, while code segment a compiles without any issues. The only difference between the two is which binary operator is used. The error message is Value of optional type 'Int?' must be unwrapped to a value of type 'Int'. The only difference between the two segments is the binary operator. It seems odd that it would cause an error in one of them.
Both codes compile correctly in Swift 4.2.3. It appears to be a regression that probably occurred in Swift 5.
See https://swiftfiddle.com/ky3flhj6wnc3hkxw6ft4lfnx7q
Expected behavior
Both code segments a and b should compile without errors, as the only difference between them is the binary operator.
Environment
- Swift compiler version info
- from
Swift version 5.0 (swift-5.0-RELEASE)toSwift version 5.8 (swift-5.8-RELEASE)and5.9-dev (LLVM 8ef0b2ab8e410d9, Swift 76d60fde58eab47)
- from
- Xcode version info
Xcode 14.3 Build version 14E222b
Additional context
As a temporary workaround, defining an overloaded function as follows fixes the compilation error:
func f<T>(_ val: [T]) -> [T] { return val }This indicates that the issue might be related to the compiler's inability to infer the type from the literals correctly.
Similar cases
Float literals
This happens not only with array literals but also with float and string literals.
The following code causes a compile error Ambiguous use of operator '==' for line a.
This problem does not occur in the Linux environment but only in the Mac environment, resulting in a compile error.
_ = f(0.0) == 1 // a _ = f(0.0) != 1 // bThis problem does not occur if the following overloads are provided:
func f(_ val: Float) -> Float { return val }String literals
The following code causes a compile error Value of optional type 'String.Element?' (aka 'Optional<Character>') must be unwrapped to a value of type 'String.Element' (aka 'Character') for line b.
let c: Character = "a" _ = f("").first == c // a _ = f("").first != c // bThis issue occurs in both Linux and Mac environments.
Also, as in the first example, it does not occur in a Swift 4.2.4 environment. See https://swiftfiddle.com/b2o6hyjbfjdhre47tkovyq4oja
As with the other examples, this problem does not occur if you provide the following overloads:
func f(_ val: String) -> String { return val }