From 06a478ba2b24ed6dcf4f2eabd060192af50c43fb Mon Sep 17 00:00:00 2001 From: George Zahariev Date: Fri, 22 Mar 2024 13:22:17 -0700 Subject: [PATCH] [flow][enums] Delete REnumRepresentation reason, and add enum representation type use op frame instead Summary: This reason was not exposed much before, but will be more with abstract flow enums. After looking at errors there, instead of the custom reason it is more clear to add a use op frame when comparing representation types. Changelog: [internal] Reviewed By: panagosg7 Differential Revision: D55219132 fbshipit-source-id: f3fa451d2a89b84ad6628147b395c973b4a966b9 --- src/common/reason.ml | 4 ---- src/common/reason.mli | 1 - src/typing/errors/flow_error.ml | 4 ++++ src/typing/statement.ml | 12 ++++++------ src/typing/subtyping_kit.ml | 14 ++++++++++---- src/typing/type.ml | 5 +++++ src/typing/typeUtil.ml | 2 ++ src/typing/type_sig_merge.ml | 2 +- .../multiplatform_subtyping.exp | 4 ++-- 9 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/common/reason.ml b/src/common/reason.ml index 9a958242c98..f3e202a655a 100644 --- a/src/common/reason.ml +++ b/src/common/reason.ml @@ -111,7 +111,6 @@ type 'loc virtual_reason_desc = | RUnknownString | RUnionEnum | REnum of string (* name *) - | REnumRepresentation of 'loc virtual_reason_desc | RThis | RThisType | RImplicitInstantiation @@ -304,7 +303,6 @@ let rec map_desc_locs f = function | RIncompatibleInstantiation _ | ROpaqueType _ | RObjectMapi | RObjectKeyMirror | RObjectMapConst | RIndexedAccess _ | RConditionalType | RInferType _ ) as r -> r - | REnumRepresentation desc -> REnumRepresentation (map_desc_locs f desc) | RConstructorCall desc -> RConstructorCall (map_desc_locs f desc) | RTypeAlias (s, None, d) -> RTypeAlias (s, None, map_desc_locs f d) | RTypeAlias (s, Some b, d) -> RTypeAlias (s, Some (f b), map_desc_locs f d) @@ -618,7 +616,6 @@ let rec string_of_desc = function | RUnknownString -> "some string with unknown value" | RUnionEnum -> "literal union" | REnum name -> spf "enum `%s`" name - | REnumRepresentation representation -> spf "%s enum" (string_of_desc representation) | RThis -> "this" | RThisType -> "`this` type" | RImplicitInstantiation -> "implicit instantiation" @@ -1563,7 +1560,6 @@ let classification_of_reason r = | RPossiblyMissingPropFromObj _ | RUnionBranching _ | REnum _ - | REnumRepresentation _ | RUnannotatedNext | RTypeGuardParam _ -> `Unclassified diff --git a/src/common/reason.mli b/src/common/reason.mli index addd54f8b80..f6e2f67a7bd 100644 --- a/src/common/reason.mli +++ b/src/common/reason.mli @@ -75,7 +75,6 @@ type 'loc virtual_reason_desc = | RUnknownString | RUnionEnum | REnum of string - | REnumRepresentation of 'loc virtual_reason_desc | RThis | RThisType | RImplicitInstantiation diff --git a/src/typing/errors/flow_error.ml b/src/typing/errors/flow_error.ml index d397cc38b25..6a8f35b8f09 100644 --- a/src/typing/errors/flow_error.ml +++ b/src/typing/errors/flow_error.ml @@ -251,6 +251,8 @@ let flip_frame = function upper_optional = c.lower_optional; } | TypeArgCompatibility c -> TypeArgCompatibility { c with lower = c.upper; upper = c.lower } + | EnumRepresentationTypeCompatibility c -> + EnumRepresentationTypeCompatibility { lower = c.upper; upper = c.lower } | ( CallFunCompatibility _ | TupleMapFunCompatibility _ | TupleAssignment _ | ObjMapFunCompatibility _ | ObjMapiFunCompatibility _ | TypeParamBound _ | OpaqueTypeBound _ | FunMissingArg _ | ImplicitTypeParam | ReactGetConfig _ | UnifyFlip | ConstrainedAssignment _ @@ -794,6 +796,8 @@ let rec make_error_printable : unwrap_frame loc frames lower use_op [text "the indexer property"] | Frame (PropertyCompatibility { prop = Some (OrdinaryName "$call"); lower; _ }, use_op) -> unwrap_frame loc frames lower use_op [text "the callable signature"] + | Frame (EnumRepresentationTypeCompatibility { lower; _ }, use_op) -> + unwrap_frame loc frames lower use_op [text "the enum's representation type"] | Frame (UnifyFlip, (Frame (PropertyCompatibility _, _) as use_op)) -> let message = [ diff --git a/src/typing/statement.ml b/src/typing/statement.ml index 613908880ae..9c59746f32a 100644 --- a/src/typing/statement.ml +++ b/src/typing/statement.ml @@ -7980,7 +7980,7 @@ module Make let (representation_t, members, has_unknown_members) = match body with | (_, BooleanBody { BooleanBody.members; has_unknown_members; _ }) -> - let reason = mk_reason (REnumRepresentation RBoolean) (loc_of_reason enum_reason) in + let reason = mk_reason RBoolean (loc_of_reason enum_reason) in let (members, bool_type, _) = Base.List.fold_left ~f: @@ -8011,7 +8011,7 @@ module Make in (DefT (reason, BoolT bool_type), members, has_unknown_members) | (_, NumberBody { NumberBody.members; has_unknown_members; _ }) -> - let reason = mk_reason (REnumRepresentation RNumber) (loc_of_reason enum_reason) in + let reason = mk_reason RNumber (loc_of_reason enum_reason) in let (members, num_type, _) = Base.List.fold_left ~f: @@ -8041,7 +8041,7 @@ module Make in (DefT (reason, NumT num_type), members, has_unknown_members) | (_, BigIntBody { BigIntBody.members; has_unknown_members; _ }) -> - let reason = mk_reason (REnumRepresentation RBigInt) (loc_of_reason enum_reason) in + let reason = mk_reason RBigInt (loc_of_reason enum_reason) in let (members, num_type, _) = Base.List.fold_left ~f: @@ -8073,7 +8073,7 @@ module Make | ( _, StringBody { StringBody.members = StringBody.Initialized members; has_unknown_members; _ } ) -> - let reason = mk_reason (REnumRepresentation RString) (loc_of_reason enum_reason) in + let reason = mk_reason RString (loc_of_reason enum_reason) in let (members, str_type, _) = Base.List.fold_left ~f: @@ -8104,13 +8104,13 @@ module Make (DefT (reason, StrT str_type), members, has_unknown_members) | (_, StringBody { StringBody.members = StringBody.Defaulted members; has_unknown_members; _ }) -> - let reason = mk_reason (REnumRepresentation RString) (loc_of_reason enum_reason) in + let reason = mk_reason RString (loc_of_reason enum_reason) in ( DefT (reason, StrT Truthy (* Member names can't be the empty string *)), defaulted_members members, has_unknown_members ) | (_, SymbolBody { SymbolBody.members; has_unknown_members; comments = _ }) -> - let reason = mk_reason (REnumRepresentation RSymbol) (loc_of_reason enum_reason) in + let reason = mk_reason RSymbol (loc_of_reason enum_reason) in (DefT (reason, SymbolT), defaulted_members members, has_unknown_members) in { enum_name; enum_id; members; representation_t; has_unknown_members } diff --git a/src/typing/subtyping_kit.ml b/src/typing/subtyping_kit.ml index e9aaba254be..b8e60f6f547 100644 --- a/src/typing/subtyping_kit.ml +++ b/src/typing/subtyping_kit.ml @@ -2142,7 +2142,7 @@ module Make (Flow : INPUT) : OUTPUT = struct when ALoc.equal_id id1 id2 -> () | ( DefT - ( _, + ( enum_reason_l, EnumObjectT { enum_id = id1; @@ -2153,7 +2153,7 @@ module Make (Flow : INPUT) : OUTPUT = struct } ), DefT - ( _, + ( enum_reason_u, EnumObjectT { enum_id = id2; @@ -2165,7 +2165,7 @@ module Make (Flow : INPUT) : OUTPUT = struct ) ) | ( DefT - ( _, + ( enum_reason_l, EnumValueT { enum_id = id1; @@ -2177,7 +2177,7 @@ module Make (Flow : INPUT) : OUTPUT = struct } ), DefT - ( _, + ( enum_reason_u, EnumValueT { enum_id = id2; @@ -2194,6 +2194,12 @@ module Make (Flow : INPUT) : OUTPUT = struct (id2, Some n2) && SSet.equal (SSet.of_list @@ SMap.keys m1) (SSet.of_list @@ SMap.keys m2) && has_unknown1 = has_unknown2 -> + let use_op = + Frame + ( EnumRepresentationTypeCompatibility { lower = enum_reason_l; upper = enum_reason_u }, + use_op + ) + in rec_flow_t cx trace ~use_op (r1, r2) | (DefT (enum_reason, EnumValueT { representation_t; _ }), t) when TypeUtil.quick_subtype representation_t t -> diff --git a/src/typing/type.ml b/src/typing/type.ml index 6fb42c3a179..61024e1f08a 100644 --- a/src/typing/type.ml +++ b/src/typing/type.ml @@ -530,6 +530,10 @@ module rec TypeTerm : sig } | RendersCompatibility | UnifyFlip + | EnumRepresentationTypeCompatibility of { + lower: 'loc virtual_reason; + upper: 'loc virtual_reason; + } and 'loc virtual_use_op = | Op of 'loc virtual_root_use_op @@ -4122,6 +4126,7 @@ let string_of_frame_use_op (type a) : a virtual_frame_use_op -> string = functio | TypePredicateCompatibility -> "TypePredicateCompatibility" | RendersCompatibility -> "RendersCompatibility" | InferredTypeForTypeGuardParameter _ -> "InferredTypeForTypeGuardParameter" + | EnumRepresentationTypeCompatibility _ -> "EnumRepresentationTypeCompatibility" let string_of_use_op (type a) : a virtual_use_op -> string = function | Op root -> string_of_root_use_op root diff --git a/src/typing/typeUtil.ml b/src/typing/typeUtil.ml index e2c2c093a20..592114aa67c 100644 --- a/src/typing/typeUtil.ml +++ b/src/typing/typeUtil.ml @@ -739,6 +739,8 @@ let rec mod_loc_of_virtual_use_op f = InferredTypeForTypeGuardParameter { reason = mod_reason reason; is_return_false_statement } | RendersCompatibility -> RendersCompatibility | UnifyFlip -> UnifyFlip + | EnumRepresentationTypeCompatibility { lower; upper } -> + EnumRepresentationTypeCompatibility { lower = mod_reason lower; upper = mod_reason upper } in function | Op op -> Op (mod_loc_of_root_use_op f op) diff --git a/src/typing/type_sig_merge.ml b/src/typing/type_sig_merge.ml index ea7cc096a39..de36aa31121 100644 --- a/src/typing/type_sig_merge.ml +++ b/src/typing/type_sig_merge.ml @@ -241,7 +241,7 @@ let import_typeof_ns file reason id_loc index = ConsGen.import_typeof file.cx reason "*" ns_t let merge_enum file reason id_loc enum_name rep members has_unknown_members = - let rep_reason desc = Reason.(mk_reason (REnumRepresentation desc) id_loc) in + let rep_reason desc = Reason.(mk_reason desc id_loc) in let rep_t desc def_t = Type.DefT (rep_reason desc, def_t) in let representation_t = let open Type in diff --git a/tests/multiplatform_subtyping/multiplatform_subtyping.exp b/tests/multiplatform_subtyping/multiplatform_subtyping.exp index bf38c7ec640..667d855fafa 100644 --- a/tests/multiplatform_subtyping/multiplatform_subtyping.exp +++ b/tests/multiplatform_subtyping/multiplatform_subtyping.exp @@ -460,8 +460,8 @@ References: Error ----------------------------------------------------------------------------------------------- enums.ios.js:16:13 -Cannot conform to common interface module because number enum [1] is incompatible with string enum [2] in property -`BarBad1`. Read the docs on Flow's multi-platform support for more information: +Cannot conform to common interface module because number [1] is incompatible with string [2] in the enum's +representation type of property `BarBad1`. Read the docs on Flow's multi-platform support for more information: https://flow.org/en/docs/react/multiplatform. [incompatible-type] enums.ios.js:16:13