Open
Description
Where is the problem?
Missing section, as
and is
refinement.
What is the problem?
Enum classes don't have assert and coerce methods. It does have nameOf and valueOf, but the purpose of those isn't made clear. Interactions with as
and is
happen at the class level, not the member level. One can not do an as
or is
check with HH\MemberOf
.
This is all probably intentionally not supported.
Please don't change anything below this point.
- Build ID: HHVM=HHVM-4.117.0:HSL=v4.108.1:2021-07-07T22:16:22+0000:1fa47f258c6b68f8ec01899aa82fd6ffa0957109
- Page requested: /hack/built-in-types/enum-class
- Page requested at: Fri, 16 Jul 2021 11:13:26 +0000
- Controller: GuidePageController
Activity
vsiles commentedon Nov 30, 2021
@lexidor
nameOf
andvalueOf
will only be usable with enum class label (soon :p), they are not useful forMemberOf
. I'm reluctant to add a coerce/assert method to enum class as it is not meant to be that way. If you get amixed
value, it is probably not from an enum class (otherwise you would have a memberof) so I don't want to coerce like enums allow (nasty design if you ask me).Feel free to explain your use case in more detail and we can have a look together
lexidor commentedon Dec 1, 2021
Plain enums can be used at API boundaries. These apis take a text request and turn this text into an untyped Hack value. You then need to assert that this value matches the expected type. There is currently no way to put enum classes at API boundaries, since you can't assert that the input matches the expected type. In fewer words, in a fully type sound world all values of type HH\MemberOf must originate from a "hard-coded" expression. This effectively means that any API that erases the type, but preserves the exact value, can not be used.
The work around would be codegenning an if else clain comparing supplied value using
===
to all members. If they compare equal, return the member. This would erase the value type to the backing type of the enum. So when passing an int to this function, your return would be a HH\MemberOf<ClassEnumBackedByMixed, mixed>. This is unsatisfactory, because the typechecker forgot that we already knew the value to be an int.The boilerplate could be eliminated with a builtin. Code within hhvm does not have to satisfy the typechecker, so an implementation like the following can only work when it is part of the runtime.
This code can't be written in userland today, because the enumerateAllMembers method does not exist and the typechecker does not understand that the identity comparison between $v and $m constrains $v to be a subtype of TBackingType.
lexidor commentedon Dec 1, 2021
I dislike coercion more than most. Having
is
andas
be unsound on plain enums is something I despise. Same goes for assert on plain enums returning ints when given an intish string and vice versa.