erg-lang / erg

A statically typed language compatible with Python
http://erg-lang.org
Apache License 2.0
2.7k stars 55 forks source link

`OptionEq` is broken #498

Open mtshiba opened 8 months ago

mtshiba commented 8 months ago

Describe the behavior?

OptionEq is a patch that allows comparison of optional types. However, the current implementation is broken.

Reproducible code

C = Class { .x = Int }
C|<: Eq|.
    __eq__ self, other: C = self.x == other.x

c as C or NoneType = C.new { .x = 1 }
print! c == None

Expected result

False

Actual result

AttributeError: 'NoneType' object has no attribute 'x'

Additional context

It should be:

C|<: Eq|.
    __eq__ self, other: C = hasattr(other, "x") and self.x == other.x

But this doesn't mean the original implementation was wrong. It is an implementation mistake that OptionEq allows T or NoneType <: Eq for T <: Eq.

To allow this, we need to inject an implementation like, for example:

OptionEq.
    __eq__ slf, other =
        classof(slf) == classof(other) and slf.__eq__ other

c as C or NoneType = C.new { .x = 1 }
print! OptionEq.__eq__ c, None

Erg version

0.6.33

Python version

None

OS

None