abstract struct A; end
struct B < A; end
struct C < A; end
(B.new || C.new) == B.new
p C.new == C.new #=> false
abstract struct A; end
struct B < A; end
struct C < A; end
B.new
p C.new == C.new #=> true
Crystal 0.23.1 (2017-09-08) LLVM 4.0.1
OS X 10.11.6 (15G1611)
Suggested title:
Reduced:
[`false`](https://carc.in/#/r/2t3t)
|
[`true`](https://carc.in/#/r/2t3u)
|
@oprypin thanks!
"Reduced" a bit more:
struct Value
def foo(other)
"BAD"
end
end
struct Struct
def foo(other : self)
{{@type}}
"GOOD"
end
end
abstract struct A
end
struct B < A
end
struct C < A
end
p (B.new || C.new).foo(C.new) # => "BAD"
It seems a macro def with self restriction isn't matched here for some reason.
Not sure if this is the same problem. I tried to implement singleton and encounter the following error
abstract class A(T); end
class C < A(Int32); end
class B < A(Nil)
@@instance = uninitialized B
def self.new
@@instance ||= B.allocate.tap(&.initialize)
end
end
(B.new || C.new) == B.new
puts B.new == B.new
Fails with error
>crystal spec/test.cr
Invalid memory access (signal 11) at address 0x0
[0x10773ddeb] *CallStack::print_backtrace:Int32 +107
[0x1077297cc] __crystal_sigfault_handler +60
[0x7fff8d3c152a] _sigtramp +26
[0x10771956f] __crystal_main +1279
[0x1077296c8] main +40
but this works as expected:
C.new
puts B.new == B.new #=> true
by the way I managed to implement singleton this way:
class B < A(String)
@@instance : Nil | B
@@instance = nil
def self.new
@@instance ||= B.allocate.tap(&.initialize)
@@instance.as(B)
end
end
(B.new || C.new) == B.new
puts B.new == B.new #=> true
Most helpful comment
Suggested title:
Comparing union of sub-structs affects comparison of other structs
Reduced: