Replace checks on enum declaration with subtype checks
commit5ef94bbc6763a3ba472655e12ee6683edaabace2
authorAndrew Kennedy <akenn@fb.com>
Wed, 31 Jul 2019 07:03:22 +0000 (31 00:03 -0700)
committerHhvm Bot <hhvm-bot@users.noreply.github.com>
Wed, 31 Jul 2019 07:07:13 +0000 (31 00:07 -0700)
treef7379caacc0407d9cd2756c6999ba9f3badfb225
parent599b6efd9a0b67d8735a1efd73102a8bf815c48c
Replace checks on enum declaration with subtype checks

Summary:
The type checking of `enum E : t` and `class E : Enum<t>` declarations is currently quite complex, needlessly so. In this diff we simply use subtyping to check the following

1. The enum constraint (after the `as`) is a subtype of `arraykey`. If no constraint is specified, it is assumed to *be* `arraykey`.
2. The underlying type (after the `:`) is a subtype of the constraint.
3. The enum values have types that are subtypes of the underlying type.

This is both more and less restrictive than the current implementation.
* It is less restrictive because the underlying type is permitted to be `arraykey`, so values can be a mixture of both ints and strings. This was already the case for the legacy form (`class E : Enum<t>`) but not for the enum declaration form.
* It is more restrictive because you can no longer break `newtype` abstraction: the underlying type or constraint on an enum cannot be an opaque `newtype`.

Reviewed By: dlreeves

Differential Revision: D16419034

fbshipit-source-id: c9a335d4d975b90362f5ec031ef2c9a2ac5d7496
26 files changed:
hphp/hack/src/errors/error_codes.ml
hphp/hack/src/errors/errors.ml
hphp/hack/src/errors/errors.mli
hphp/hack/src/typing/typing_enum.ml
hphp/hack/src/typing/typing_reason.ml
hphp/hack/test/errors/error_map.ml
hphp/hack/test/typecheck/classname/enum.php.like_types.exp
hphp/hack/test/typecheck/enum_2.php.exp
hphp/hack/test/typecheck/enum_3.php.like_types.exp
hphp/hack/test/typecheck/enum_4.php.exp
hphp/hack/test/typecheck/enum_5.php.exp
hphp/hack/test/typecheck/enum_5.php.like_types.exp
hphp/hack/test/typecheck/enum_6.php.exp
hphp/hack/test/typecheck/enum_7.php.exp
hphp/hack/test/typecheck/fc_enum_14.php.like_types.exp
hphp/hack/test/typecheck/fc_enum_15.php.exp
hphp/hack/test/typecheck/fc_enum_16.php.exp
hphp/hack/test/typecheck/fc_enum_4.php.exp
hphp/hack/test/typecheck/fc_enum_6.php.exp
hphp/hack/test/typecheck/fc_enum_8.php.like_types.exp
hphp/hack/test/typecheck/new_type_errors/4329-4330-enum_constaint_must_be_arraykey_and_compatible.php.exp
hphp/hack/test/typecheck/nonnull/enum_of_nonnull1.php.exp
hphp/hack/test/typecheck/nonnull/enum_of_nonnull2.php.exp
hphp/hack/test/typecheck/nonnull/enum_type_typedef_nonnull.php.exp
hphp/hack/test/typecheck/nonnull/enum_type_typedef_nonnull.php.like_types.exp
hphp/hack/test/typecheck/nonnull/fc_enum_of_nonnull.php.exp