Optional enum with case none

(Sergo) #1
enum AnimationType {
    case none
    case something

class MyClass {
    var type_one: AnimationType = .none
    var type_two: AnimationType = .something

let object: MyClass? = MyClass()

print(object?.type_one == .none) // false, it compares with Optional.none - the value is not nil and returns false
print(object?.type_one == AnimationType.none) // true

print(object?.type_two == .something) // true
print(object?.type_two == AnimationType.something) // true

In Swift it is possible to omit type names when accessing enum cases ( and other static members ).
Optional also has case none and we can just type .none to access it.

The problem might occur when there is an optional enum that might also have a none case.

In the code above, the first comparison compares to Optional.none instead of AnimationType.none.
Since it is possible to compare it to other cases without typing full type ( == .something ), it might lead to confusion/bugs when developer changes one case to another and gets completely different behaviour.

Could we have a warning for this situation ( maybe requiring to fully provide Type ), when an optional is compared to .none and the Optional.Wrapped also has a case .none ?

(Ben Rimmington) #2

This has been reported by @kelan as starter bug SR-2176.

(Suyash Srijan) #3

Literally faced the same issue a few weeks back - one of the unit tests in my project was failing because of this exact issue, so I had to explicitly specify the enum type with the case (i.e. Foo.none instead of .none).

I guess I'll pick this issue and fix it because it annoyed me a bit lol.

(Suyash Srijan) #4

Fixed on master: https://github.com/apple/swift/pull/21621

I'll cherry pick this to the swift-5.0 branch!