Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question method on member with value 0 in enum with flags attribute broken #7249

Open
petoem opened this issue Jan 2, 2019 · 8 comments
Open
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib

Comments

@petoem
Copy link
Contributor

petoem commented Jan 2, 2019

Code:

@[Flags]
enum Animal
  UNKNOWN = 0
  DOG
  CAT
  LAMA
end

pp Animal::UNKNOWN.unknown? # => false

https://play.crystal-lang.org/#/r/5wi8

@j8r
Copy link
Contributor

j8r commented Jan 2, 2019

Why do you use @[Flags]?

@petoem
Copy link
Contributor Author

petoem commented Jan 2, 2019

@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.

def define_enum_none_question_method(enum_type, node)

And another effect of having None member always defined is this:

pp Animal::UNKNOWN # => None

@petoem
Copy link
Contributor Author

petoem commented Jan 2, 2019

Fun fact, a None member is only created if there is no one.

unless enum_type.types["None"]?
none = NumberLiteral.new("0", enum_base_type.kind)
none.type = enum_type
enum_type.add_constant Arg.new("None", default_value: none)
define_enum_none_question_method(enum_type, node)
end

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

https://play.crystal-lang.org/#/r/5wjq

@asterite
Copy link
Member

asterite commented Jan 2, 2019

I still think we should remove the autogenerated None and All enum members.

@petoem
Copy link
Contributor Author

petoem commented Jan 4, 2019

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.

@asterite
Copy link
Member

asterite commented Jan 4, 2019

@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.

@petoem
Copy link
Contributor Author

petoem commented Jan 4, 2019

Yeah, for example replacing this ...

define_enum_question_method(enum_type, member, is_flags)

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.

@jhass jhass added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib labels Dec 17, 2019
@straight-shoota
Copy link
Member

Related to #7285

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib
Projects
None yet
Development

No branches or pull requests

5 participants