cal
(Cal Stephens)
1
When comparing a non-optional type to nil, the compiler emits a warning:
let value = "non-optional"
// warning: comparing non-optional value of type 'String' to 'nil' always returns false
if value == nil {
print("value is nil")
}
Interestingly, when performing an equivalent check using Optional.none instead of nil, the compiler doesn't emit a warning:
let value = "non-optional"
if value == .none {
print("nil")
}
Is this a bug / oversight? Since these two checks are functionally equivalent I would expect them to both emit a warning.
I see this warning is implemented here. If this seems like a bug / oversight, could this be updated to warn on redundant == .none comparisons (like it does for == nil) without running an evolution proposal?
1 Like
Jon_Shier
(Jon Shier)
2
This is likely one of the various differences in handling .none and nil across the language, especially in automatic promotion as you've seen. I think they're considered bugs but I'll let one of the language developers speak to that.
There are also some other areas where .none and nil aren’t treated the same, for example failable inits:
class C1 {
init?() {
return .none // error: 'nil' is the only return value permitted in an initializer
}
}
class C2 {
init?() {
return nil // ok
}
}
Avi
4
This seems like a valid difference. The compiler has no way to be certain you mean Optional.none in C1.init.
Jon_Shier
(Jon Shier)
5
How so? The only valid return from a failable init is an Optional, no?
4 Likes
cal
(Cal Stephens)
6
3 Likes
Mordil
(Nathan Harris)
7
I think it's the automatic promotion of types inside of a critical object lifecycle section of code that the language rules forbid it for crystal-clear intentions and understanding
YOCKOW
(YOCKOW)
8
I think, theoretically, that value == .none should emit an error because String has no member named none.
I understand that that will be a breaking change, though.
2 Likes
GreatApe
(Gustaf Kugelberg)
9
Is that even a real return statement? I mean you can't return a C2, so I'd say that when you write return nil it doesn't mean anything like return Optional<C2>.none, it simply means failed to init, but instead of inventing a new syntax for that they use return nil.
1 Like
tera
10
By the same logic "return .none" from an init couldn't possibly mean anything other than "return nil" (and IMHO should be allowed).
If we removed "nil" from the language altogether (not I'm saying we should, just that we could) and use ".none" in all places we currently use nil - swift would not be any less swifty.
1 Like