I am using Xcode Version 11.3.1 (11C504)
I am trying to create a generic function in Swift that will reject its parameter unless such a parameter is Optional.
In the following code, I was expecting the system to report errors in all calls to onlyCallableByAnOptable()
made inside test()
, because none of them provide an optional value as a parameter.
However, the system only reports non-protocol conformance if I remove the Optional
extension that conforms to Optable
!
Which to me, it means that the system is regarding any and all values as Optional
, regardless!
Am I doing something wrong?
(By the way, the following code used to be working as expected in earlier versions of Swift. I just recently found out that it stopped working, for it was letting a non-Optional
go through.)
protocol Optable {
func opt()
}
func onlyCallableByAnOptable<T>( _ value: T) -> T where T: Optable {
return value
}
// Comment the following line to get the errors
extension Optional: Optable { func opt() {} }
class TestOptable {
static func test()
{
let c = UIColor.blue
let s = "hi"
let i = Int(1)
if let o = onlyCallableByAnOptable(c) { print("color \(o)") }
//^ expected ERROR: Argument type 'UIColor' does not conform to expected type 'Optable'
if let o = onlyCallableByAnOptable(s) { print("string \(o)") }
//^ expected ERROR: Argument type 'String' does not conform to expected type 'Optable'
if let o = onlyCallableByAnOptable(i) { print("integer \(o)") }
//^ expected ERROR: Argument type 'Int' does not conform to expected type 'Optable'
}
}
Since you've made all Optional
s conform to Optable
and you are using the if let
syntax to unwrap the result of the call to onlyCallableByAnOptable
(which means the return type must be some kind of Optional
, which means the parameter must also be that same type of Optional
because both the parameter and the return type are of type T
in your generic method), Swift is inferring the types being passed in as UIColor?
, String?
, and Int?
(implicitly wrapping them in Optional
s) instead of UIColor
, String
and Int
.