-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
proposal: Allow comparison (==/!=) of ?T with U if T and U are comparable #5155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Clarification on how optional comparison to optional would work: // assuming T is the child type of the optional, and U is the type of the other argument
?i32 == ?i32 // optional compared to something else, compiler just picks which one is T
^^^ T ^^^^ U
// are T and U comparable?
i32 == ?i32 // new T and U are determined
^^^ U' ^^^ T'
// are U' and T' comparable?
i32 == i32 // i32 is comparable with itself, so ?i32 is comparable with ?i32 |
Would this mean that |
I suppose that would be a natural result as well. Would that be a problem if it did exist? Multiple-wrapped optionals are very uncommon anyway. It wouldn't be difficult to special-case though, and I believe andrew said he wouldnt want ??T == T to work. I just don't see why it shouldn't, The special casing could be as simple as: we select the optional child type |
I'm not sure the idea of "f T and U are comparable" is well defined in Zig. These kinds of recursive definitions are scary. The pattern matches so many scenarios that it will lead to surprising results that have already been brought up in this discussion, like Your example in the OP is a very good example: const x: ?i32 = 10;
if (x == 10) { ... } // ERROR
if (x == @as(i32, 10)) { ... } // OK That's a strong argument that something needs to change, but this proposal is not the only way. Here's another proposal:
This would forbid comparing two optional types Another idea is to restrict the proposal for when I think the fundamental problem with this is the double-variable pattern matching with |
Equality comparison (
==
or!=
) should be allowed between?T
andU
, as long asT
andU
can be compared the same way.This is an extension of issue #1332 , which is accepted to only allow comparison between
?T
andT
if T is comparable to itself. This proposal aims to extend this to the next logical step, and avoid language inconsistencies. #1332 would allow something like this:but, surprisingly, not this:
Because
x
is a?i32
, and10
is acomptime_int
, so the original proposal doesn't cover that case of different (yet still compatible) types. You would need to use an@as
or something, which seems wrong in this case. In addition to the ability to utilize peer-type resolution and various special cases (like comparing an enum literal to a tagged union), this proposal solves another useful problem as a side-effect:Comparison of two different optionals!
This would work because, in this case,
T = i32
(from the lhs), andU = ?i32
from the rhs. Then, the compiler would check if those two types are comparable: yes they are! The original goal of this proposal was to allow?T
to be compared withT
, and that's what we have with T and U in this case.This proposal brings further consistency and ergonomics to the language, that the original proposal missed. It also solves the other issue of comparing two optionals with each other, without heavy overhead or special-casing.
The text was updated successfully, but these errors were encountered: