You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For a generic struct Foo(T) equality with another generic instance type like Foo(U)#==(other : Foo(V)) with different T and V always returns false. The reason is the type restriction to self in Struct#== which strictly compares generic type arguments.
There might be cases where this behaviour is correct, but usually the equality operator is not strict about types (1 == 1.0 is true) and structs should be expected to have equality defined by actual values. Even if generic type arguments mismatch: For example 1..1 == 1.0..1.0 should be true (the specific example with Range is detailed in #10309).
The solution would be to replace the type restriction to self (which is the generic instance type) with a broader restriction to the generic class type.
This can be implemented with is_a?({{ @type.name(generic_args: false) }}).
However, this doesn't work for private types because of #4269:
A workaround could be to use self for non-generic types. That would leave only private generic types to fail, which is probably very rare. It's still hacky, though.
I think this serves as an encouragement to lift restricions on private type references as proposed in #4269 (comment).
The text was updated successfully, but these errors were encountered:
For a generic struct
Foo(T)
equality with another generic instance type likeFoo(U)#==(other : Foo(V))
with differentT
andV
always returnsfalse
. The reason is the type restriction toself
inStruct#==
which strictly compares generic type arguments.There might be cases where this behaviour is correct, but usually the equality operator is not strict about types (
1 == 1.0
is true) and structs should be expected to have equality defined by actual values. Even if generic type arguments mismatch: For example1..1 == 1.0..1.0
should be true (the specific example withRange
is detailed in #10309).The solution would be to replace the type restriction to
self
(which is the generic instance type) with a broader restriction to the generic class type.This can be implemented with
is_a?({{ @type.name(generic_args: false) }})
.However, this doesn't work for private types because of #4269:
A workaround could be to use
self
for non-generic types. That would leave only private generic types to fail, which is probably very rare. It's still hacky, though.I think this serves as an encouragement to lift restricions on private type references as proposed in #4269 (comment).
The text was updated successfully, but these errors were encountered: