Code:
@[Flags]
enum Animal
UNKNOWN = 0
DOG
CAT
LAMA
end
pp Animal::UNKNOWN.unknown? # => false
Why do you use @[Flags]?
@j8r This is just an example.
I came across it when I wanted to rename "None" to something else.
Ideally, a None member should only be created if there is no other member with a value of 0 and the member with a value of 0 should get the right question method using #== instead of #includes?.
Currently only the None member gets the right question method defined through define_enum_none_question_method.
https://github.com/crystal-lang/crystal/blob/5502b00c9482b20ed872ea0583a5fe90d91b1e84/src/compiler/crystal/semantic/top_level_visitor.cr#L698
And another effect of having None member always defined is this:
```crystal
pp Animal::UNKNOWN # => None
Fun fact, a None member is only created if there is no one.
https://github.com/crystal-lang/crystal/blob/5502b00c9482b20ed872ea0583a5fe90d91b1e84/src/compiler/crystal/semantic/top_level_visitor.cr#L585-L591
But this means if I define a None = 0 member, no functioning question method is created.
@[Flags]
enum Animal
None = 0
DOG
CAT
LAMA
end
pp Animal::None.none? # => false
I still think we should remove the autogenerated None and All enum members.
Whether we keep them or not, does not change the fact that we need to define the right question method for a member with a value of 0.
@petoem It's failing right now because there's special logic in Enum#includes? and Enum#each to deal with None and All. If we remove those generated enum members the issue will be trivially fixed.
Yeah, for example replacing this ...
https://github.com/crystal-lang/crystal/blob/fcfb8f71db6c49254f821e7346797b5499af8173/src/compiler/crystal/semantic/top_level_visitor.cr#L663
with this ...
if is_flags && counter == 0
define_enum_question_method(enum_type, member, false)
else
define_enum_question_method(enum_type, member, is_flags)
end
... should define the correct question method.