haxe icon indicating copy to clipboard operation
haxe copied to clipboard

Enum comparison checking depends on inexplicable conditions

Open acarioni opened this issue 3 years ago • 3 comments

Environment macOS 12.4 haxe 4.3.0-rc.a49b191

Take the following snippet:

enum Foo {
  A(s: String); B(i: Int);
}

class Main {
  static function main() {
    var f1 = A("");
    var f2 = B(0);
    // var m = [1 => f1, 2 => f2];
    trace(f1 == f2);
  }
}

Run it without the flag -D analyzer-optimize. It prints false.

Then run it with the flag enabled. It complains that You cannot directly compare enums with arguments. Use either switch, match or Type.enumEq.

Finally uncomment the variable declaration and run it with the flag enabled. It print false.

I think the compiler should always refuse the compilation because I’m trying to compare enums with arguments. Or no?

acarioni avatar Jul 18 '22 12:07 acarioni

Haxe correctly complains when the expression A("") == B(0) is found. However, it only sees such an expression if the analyser runs, because it inlines the f1 and f2 variables. If it does not run, then Haxe only sees a comparison of two variables of type Foo, which could be fine (e.g. if there were any argument-less constructors in the enum). With the m variable the analyser decides to not inline the f1, f2 variables anymore.

Not sure what to do: emitting that error for any == comparison of Foo types is a potential solution, but it might be too strict. On the other hand, such a comparison is probably not something you ever(?) want.

As a side note, it would be good if we had some system to derive structural equality of enums, so that one does not have to write a manual recursive equality check. (See #[derive(PartialEq, Eq)] in Rust.)

Aurel300 avatar Jul 18 '22 13:07 Aurel300

Thanks for the explanation, Aurel.

IMO the compiler should at least emit a warning when there is a comparison of two values of an enum type comprising constructors with arguments, even if the flag analyzer-optimize is not set. Otherwise if the compiler accepts expressions like these, the probability of a bug is high (as happened in my code for example).

acarioni avatar Jul 18 '22 13:07 acarioni

I have implemented this on the linked branch, but I'm still not sure if I actually like it. I'm seeing quite a few places where we use a == check as an optimistic heuristic, and getting warnings for all of those is quite annoying.

Simn avatar Aug 01 '22 09:08 Simn

This is #11536 with extra steps.

Simn avatar Feb 06 '24 09:02 Simn

It seems that periodically I forget how enum comparison works :) However I still like the idea of adding a compiler flag to enable some kind of warning.

acarioni avatar Feb 06 '24 10:02 acarioni