2 * Copyright (c) 2015, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
11 open Typing_defs_flags
12 include Typing_defs_core
21 ce_visibility
: ce_visibility
;
22 ce_type
: decl_ty
Lazy.t
;
23 ce_origin
: string; (** identifies the class from which this elt originates *)
24 ce_deprecated
: string option;
25 ce_pos
: Pos.t
Lazy.t
; (** pos of the type of the elt *)
31 fe_deprecated
: string option;
44 (** identifies the class from which this const originates *)
48 type record_field_req
=
53 type record_def_type
= {
55 rdt_extends
: Nast.sid
option;
56 rdt_fields
: (Nast.sid
* record_field_req
) list
;
62 (** The position is that of the hint in the `use` / `implements` AST node
63 * that causes a class to have this requirement applied to it. E.g.
69 * require extends Foo; <- position of the decl_phase ty
72 * class Baz extends Foo implements Bar { <- position of the `implements`
76 type requirement
= Pos.t
* decl_ty
80 tc_members_fully_known
: bool;
81 (** Whether the typechecker knows of all (non-interface) ancestors
82 * and thus known all accessible members of this class *)
86 tc_deferred_init_members
: SSet.t
;
87 (** When a class is abstract (or in a trait) the initialization of
88 * a protected member can be delayed *)
89 tc_kind
: Ast_defs.class_kind
;
91 tc_has_xhp_keyword
: bool;
92 tc_is_disposable
: bool;
95 tc_tparams
: decl_tparam list
;
96 tc_where_constraints
: decl_where_constraint list
;
97 tc_consts
: class_const
SMap.t
;
98 tc_typeconsts
: typeconst_type
SMap.t
;
99 tc_props
: class_elt
SMap.t
;
100 tc_sprops
: class_elt
SMap.t
;
101 tc_methods
: class_elt
SMap.t
;
102 tc_smethods
: class_elt
SMap.t
;
103 tc_construct
: class_elt
option * consistent_kind
;
104 (** the consistent_kind represents final constructor or __ConsistentConstruct *)
105 tc_ancestors
: decl_ty
SMap.t
;
106 (** This includes all the classes, interfaces and traits this class is
108 tc_implements_dynamic
: bool; (** Whether the class is coercible to dynamic *)
109 tc_req_ancestors
: requirement list
;
110 tc_req_ancestors_extends
: SSet.t
; (** the extends of req_ancestors *)
112 tc_enum_type
: enum_type
option;
113 tc_sealed_whitelist
: SSet.t
option;
114 tc_decl_errors
: Errors.t
option; [@opaque
]
117 and typeconst_abstract_kind
=
118 | TCAbstract
of decl_ty
option
119 | TCPartiallyAbstract
122 and typeconst_type
= {
123 ttc_abstract
: typeconst_abstract_kind
;
125 ttc_constraint
: decl_ty
option;
126 ttc_type
: decl_ty
option;
128 ttc_enforceable
: Pos.t
* bool;
129 ttc_reifiable
: Pos.t
option;
134 te_constraint
: decl_ty
option;
135 te_includes
: decl_ty list
;
140 type typedef_type
= {
142 td_vis
: Aast.typedef_visibility
;
143 td_tparams
: decl_tparam list
;
144 td_constraint
: decl_ty
option;
149 let is_enum_class = function
151 | Some info
-> info
.te_enum_class
157 type deserialization_error
=
158 | Wrong_phase
of string
159 (** The type was valid, but some component thereof was a decl_ty when we
160 expected a locl_phase ty, or vice versa. *)
161 | Not_supported
of string
162 (** The specific type or some component thereof is not one that we support
163 deserializing, usually because not enough information was serialized to be
164 able to deserialize it again. *)
165 | Deserialization_error
of string
166 (** The input JSON was invalid for some reason. *)
168 (** Tracks information about how a type was expanded *)
170 type_expansions
: (bool * Pos.t
* string) list
;
171 (** A list of the type defs and type access we have expanded thus far. Used
172 * to prevent entering into a cycle when expanding these types.
173 * If the boolean is set, then emit an error because we were checking the
174 * definition of a type (by type, or newtype, or a type constant)
176 substs
: locl_ty
SMap.t
;
178 (** The type that is substituted for `this` in signatures. It should be
179 * set to an expression dependent type if appropraite
182 (** If set to true, do not report errors, just return Terr or equivalent *)
183 on_error
: Errors.typing_error_callback
;
184 (** If what we are localizing or expanding comes from the decl heap for
185 example, then some errors must be silenced since they must have already been
186 raised when first typechecking whatever we have fetched from the heap.
187 Setting {!quiet} to true will silence those errors.
188 T54121530 aims at offering a better mechanism. *)
192 match get_node t
with
196 let get_class_type t
=
197 match get_node t
with
198 | Tclass
(id
, exact
, tyl
) -> Some
(id
, exact
, tyl
)
203 | LoclType t
-> get_var t
204 | ConstraintType _
-> None
206 let is_tyvar t
= Option.is_some
(get_var t
)
209 match get_node t
with
210 | Tvar v'
when Ident.equal v v'
-> true
214 match get_node t
with
219 match get_node t
with
224 match get_node t
with
229 match get_node t
with
234 match get_node t
with
238 let is_generic_equal_to n t
=
239 (* TODO(T69551141) handle type arguments *)
240 match get_node t
with
241 | Tgeneric
(n'
, _tyargs
) when String.equal n n'
-> true
245 match get_node t
with
246 | Tprim p'
when Aast.equal_tprim p p'
-> true
250 match get_node t
with
254 let is_constraint_type_union t
=
255 match deref_constraint_type t
with
256 | (_
, TCunion _
) -> true
259 let is_has_member t
=
260 match deref_constraint_type t
with
261 | (_
, Thas_member _
) -> true
264 let show_phase_ty _
= "<phase_ty>"
266 let pp_phase_ty _ _
= Printf.printf
"%s\n" "<phase_ty>"
268 let is_locl_type = function
272 let has_expanded { type_expansions
; _
} x
=
273 List.find_map type_expansions
(function
274 | (report
, _
, x'
) when String.equal x x'
-> Some report
277 let reason = function
278 | LoclType t
-> get_reason t
279 | ConstraintType t
-> fst
(deref_constraint_type t
)
281 let is_constraint_type = function
282 | ConstraintType _
-> true
283 | LoclType _
-> false
285 let is_union_or_inter_type (ty
: locl_ty
) =
286 (* do not expand type here! *)
287 match get_node ty
with
309 | Tvarray_or_darray _
313 module InternalType
= struct
316 | LoclType t
-> get_var t
317 | ConstraintType _
-> None
321 | LoclType t
-> is_var_v t v
322 | ConstraintType _
-> false
324 let is_not_var_v t ~v
= not
@@ is_var_v t ~v
327 (* The identifier for this *)
328 let this = Local_id.make_scoped
"$this"
330 (* This should be the ONLY way that Tany is constructed anywhere in the
332 let make_tany () = Tany
TanySentinel.value
334 let arity_min ft
: int =
335 List.count ~f
:(fun fp
-> not
(get_fp_has_default fp
)) ft
.ft_params
337 let get_param_mode callconv
=
339 | Some
Ast_defs.Pinout
-> FPinout
342 module DependentKind
= struct
343 let to_string = function
344 | DTthis
-> SN.Typehints.this
346 let display_id = Reason.get_expr_display_id i
in
347 "<expr#" ^ string_of_int
display_id ^
">"
349 let is_generic_dep_ty s
= String_utils.is_substring
"::" s
352 module ShapeFieldMap
= struct
353 include Nast.ShapeMap
355 let map_and_rekey shape_map key_f value_f
=
356 let f_over_shape_field_type ({ sft_ty
; _
} as shape_field_type
) =
357 { shape_field_type
with sft_ty
= value_f sft_ty
}
359 Nast.ShapeMap.map_and_rekey shape_map key_f
f_over_shape_field_type
361 let map_env f env shape_map
=
362 let f_over_shape_field_type env _key
({ sft_ty
; _
} as shape_field_type
) =
363 let (env
, sft_ty
) = f env sft_ty
in
364 (env
, { shape_field_type
with sft_ty
})
366 Nast.ShapeMap.map_env f_over_shape_field_type env shape_map
368 let map f shape_map
= map_and_rekey shape_map
(fun x
-> x
) f
370 let iter f shape_map
=
371 let f_over_shape_field_type shape_map_key
{ sft_ty
; _
} =
372 f shape_map_key sft_ty
374 Nast.ShapeMap.iter f_over_shape_field_type shape_map
376 let iter_values f
= iter (fun _
-> f
)
379 module ShapeFieldList
= struct
382 let map_env env xs ~f
=
383 let f_over_shape_field_type env
({ sft_ty
; _
} as shape_field_type
) =
384 let (env
, sft_ty
) = f env sft_ty
in
385 (env
, { shape_field_type
with sft_ty
})
387 Common.List.map_env env xs ~f
:f_over_shape_field_type
390 (*****************************************************************************)
392 (*****************************************************************************)
394 (* Set to true when we are trying to infer the missing type hints. *)
395 let is_suggest_mode = ref false
397 (* Ordinal value for type constructor, for localized types *)
398 let ty_con_ordinal ty_
=
405 match get_node t
with
420 | Tintersection _
-> 14
425 | Tvarray_or_darray _
-> 22
426 | Tunapplied_alias _
-> 23
429 (* Ordinal value for type constructor, for decl types *)
430 let decl_ty_con_ordinal ty_
=
441 | Tvarray_or_darray _
-> 8
453 | Tintersection _
-> 21
455 let reactivity_ordinal r
=
464 | MaybeReactive _
-> 7
469 (* Compare two types syntactically, ignoring reason information and other
470 * small differences that do not affect type inference behaviour. This
471 * comparison function can be used to construct tree-based sets of types,
472 * or to compare two types for "exact" equality.
473 * Note that this function does *not* expand type variables, or type
475 * But if ty_compare ty1 ty2 = 0, then the types must not be distinguishable
476 * by any typing rules.
478 let rec ty__compare ?
(normalize_lists
= false) ty_1 ty_2
=
479 let rec ty__compare ty_1 ty_2
=
480 match (ty_1
, ty_2
) with
481 | (Tprim ty1
, Tprim ty2
) -> Aast_defs.compare_tprim ty1 ty2
482 | (Toption ty
, Toption ty2
)
483 | (Tvarray ty
, Tvarray ty2
) ->
485 | (Tdarray
(tk
, tv
), Tdarray
(tk2
, tv2
))
486 | (Tvarray_or_darray
(tk
, tv
), Tvarray_or_darray
(tk2
, tv2
)) ->
488 match ty_compare tk tk2
with
489 | 0 -> ty_compare tv tv2
492 | (Tfun fty
, Tfun fty2
) -> tfun_compare fty fty2
493 | (Tunion tyl1
, Tunion tyl2
)
494 | (Tintersection tyl1
, Tintersection tyl2
)
495 | (Ttuple tyl1
, Ttuple tyl2
) ->
496 tyl_compare ~sort
:normalize_lists ~normalize_lists tyl1 tyl2
497 | (Tgeneric
(n1
, args1
), Tgeneric
(n2
, args2
)) ->
499 match String.compare n1 n2
with
500 | 0 -> tyl_compare ~sort
:false ~normalize_lists args1 args2
503 | (Tnewtype
(id
, tyl
, cstr1
), Tnewtype
(id2
, tyl2
, cstr2
)) ->
505 match String.compare id id2
with
507 (match tyl_compare ~sort
:false tyl tyl2
with
508 | 0 -> ty_compare cstr1 cstr2
512 | (Tdependent
(d1
, cstr1
), Tdependent
(d2
, cstr2
)) ->
514 match compare_dependent_type d1 d2
with
515 | 0 -> ty_compare cstr1 cstr2
518 (* An instance of a class or interface, ty list are the arguments *)
519 | (Tclass
(id
, exact
, tyl
), Tclass
(id2
, exact2
, tyl2
)) ->
521 match String.compare
(snd id
) (snd id2
) with
524 match tyl_compare ~sort
:false tyl tyl2
with
525 | 0 -> compare_exact exact exact2
530 | (Tshape
(shape_kind1
, fields1
), Tshape
(shape_kind2
, fields2
)) ->
532 match compare_shape_kind shape_kind1 shape_kind2
with
535 (fun (k1
, v1
) (k2
, v2
) ->
536 match Ast_defs.ShapeField.compare k1 k2
with
537 | 0 -> shape_field_type_compare v1 v2
539 (Nast.ShapeMap.elements fields1
)
540 (Nast.ShapeMap.elements fields2
)
543 | (Tvar v1
, Tvar v2
) -> compare v1 v2
544 | (Tunapplied_alias n1
, Tunapplied_alias n2
) -> String.compare n1 n2
545 | (Taccess
(ty1
, id1
), Taccess
(ty2
, id2
)) ->
547 match ty_compare ty1 ty2
with
548 | 0 -> String.compare
(snd id1
) (snd id2
)
551 | (Tnonnull
, Tnonnull
) -> 0
552 | (Tdynamic
, Tdynamic
) -> 0
553 | (Tobject
, Tobject
) -> 0
555 | ( ( Tprim _
| Toption _
| Tvarray _
| Tdarray _
| Tvarray_or_darray _
556 | Tfun _
| Tintersection _
| Tunion _
| Ttuple _
| Tgeneric _
557 | Tnewtype _
| Tdependent _
| Tclass _
| Tshape _
| Tvar _
558 | Tunapplied_alias _
| Tnonnull
| Tdynamic
| Terr
| Tobject
| Taccess _
562 ( Tprim _
| Toption _
| Tvarray _
| Tdarray _
| Tvarray_or_darray _
563 | Tfun _
| Tintersection _
| Tunion _
| Ttuple _
| Tgeneric _
564 | Tnewtype _
| Tdependent _
| Tclass _
| Tshape _
| Tvar _
565 | Tunapplied_alias _
| Tnonnull
| Tdynamic
| Terr
| Tobject
| Taccess _
567 ty_con_ordinal ty_1
- ty_con_ordinal ty_2
568 and shape_field_type_compare sft1 sft2
=
569 let { sft_ty
= ty1
; sft_optional
= optional1
} = sft1
in
570 let { sft_ty
= ty2
; sft_optional
= optional2
} = sft2
in
571 match ty_compare ty1 ty2
with
572 | 0 -> Bool.compare optional1 optional2
574 and user_attribute_compare ua1 ua2
=
575 let { ua_name
= name1
; ua_classname_params
= classname_params1
} = ua1
in
576 let { ua_name
= name2
; ua_classname_params
= classname_params2
} = ua2
in
577 match String.compare
(snd name1
) (snd name2
) with
578 | 0 -> List.compare
String.compare classname_params1 classname_params2
580 and user_attributes_compare ual1 ual2
=
581 List.compare user_attribute_compare ual1 ual2
582 and tparam_compare tp1 tp2
=
584 (* Type parameters on functions are always marked invariant *)
587 tp_tparams
= tparams1
;
588 tp_constraints
= constraints1
;
589 tp_reified
= reified1
;
590 tp_user_attributes
= user_attributes1
;
597 tp_tparams
= tparams2
;
598 tp_constraints
= constraints2
;
599 tp_reified
= reified2
;
600 tp_user_attributes
= user_attributes2
;
604 match String.compare
(snd name1
) (snd name2
) with
607 match tparams_compare tparams1 tparams2
with
610 match constraints_compare constraints1 constraints2
with
614 user_attributes_compare user_attributes1 user_attributes2
616 | 0 -> Aast_defs.compare_reify_kind reified1 reified2
624 and tparams_compare tpl1 tpl2
= List.compare tparam_compare tpl1 tpl2
625 and constraints_compare cl1 cl2
= List.compare constraint_compare cl1 cl2
626 and constraint_compare
(ck1
, ty1
) (ck2
, ty2
) =
627 match Ast_defs.compare_constraint_kind ck1 ck2
with
628 | 0 -> ty_compare ty1 ty2
630 and where_constraint_compare
(ty1a
, ck1
, ty1b
) (ty2a
, ck2
, ty2b
) =
631 match Ast_defs.compare_constraint_kind ck1 ck2
with
634 match ty_compare ty1a ty2a
with
635 | 0 -> ty_compare ty1b ty2b
639 and where_constraints_compare cl1 cl2
=
640 List.compare where_constraint_compare cl1 cl2
641 (* We match every field rather than using field selection syntax. This guards against future additions to function type elements *)
642 and tfun_compare fty1 fty2
=
647 ft_reactive
= reactive1
;
649 ft_implicit_params
= implicit_params1
;
650 ft_ifc_decl
= ifc_decl1
;
651 ft_tparams
= tparams1
;
652 ft_where_constraints
= where_constraints1
;
660 ft_reactive
= reactive2
;
662 ft_implicit_params
= implicit_params2
;
663 ft_ifc_decl
= ifc_decl2
;
664 ft_tparams
= tparams2
;
665 ft_where_constraints
= where_constraints2
;
669 match possibly_enforced_ty_compare ret1 ret2
with
672 match ft_params_compare params1 params2
with
674 (* Explicit polymorphic equality. Need to write equality on
675 * locl_ty by hand if we want to make a specialized one
678 match ft_arity_compare arity1 arity2
with
681 match tparams_compare tparams1 tparams2
with
685 where_constraints_compare
691 match Int.compare flags1 flags2
with
693 let { capability
= capability1
} = implicit_params1
in
694 let { capability
= capability2
} = implicit_params2
in
697 capability_compare capability1 capability2
702 compare_ifc_fun_decl ifc_decl1 ifc_decl2
704 | 0 -> reactivity_compare reactive1 reactive2
720 and ft_arity_compare a1 a2
=
722 | (Fstandard
, Fstandard
) -> 0
723 | (Fstandard
, Fvariadic _
) -> -1
724 | (Fvariadic _
, Fstandard
) -> 1
725 | (Fvariadic p1
, Fvariadic p2
) -> ft_param_compare ~normalize_lists p1 p2
726 and capability_compare cap1 cap2
=
727 match (cap1
, cap2
) with
728 | (CapDefaults _
, CapDefaults _
) -> 0
729 | (CapDefaults _
, CapTy _
) -> -1
730 | (CapTy _
, CapDefaults _
) -> 1
731 | (CapTy ty1
, CapTy ty2
) -> ty_compare ty1 ty2
732 and reactivity_compare r1 r2
=
734 | (Nonreactive
, Nonreactive
)
735 | (CippGlobal
, CippGlobal
)
736 | (CippRx
, CippRx
) ->
738 | (Local opt_ty1
, Local opt_ty2
)
739 | (Shallow opt_ty1
, Shallow opt_ty2
)
740 | (Reactive opt_ty1
, Reactive opt_ty2
)
741 | (Pure opt_ty1
, Pure opt_ty2
) ->
742 (* TODO T82455489: proper decl compare. Poly.compare will be position sensitive *)
743 Option.compare
Poly.compare opt_ty1 opt_ty2
744 | (MaybeReactive r1
, MaybeReactive r2
) -> reactivity_compare r1 r2
745 | (RxVar opt_r1
, RxVar opt_r2
) ->
746 Option.compare reactivity_compare opt_r1 opt_r2
747 | (Cipp opt_s1
, Cipp opt_s2
)
748 | (CippLocal opt_s1
, CippLocal opt_s2
) ->
749 Option.compare
String.compare opt_s1 opt_s2
750 | ( ( Nonreactive
| CippGlobal
| CippRx
| Local _
| Shallow _
| Reactive _
751 | Pure _
| MaybeReactive _
| RxVar _
| Cipp _
| CippLocal _
),
752 ( Nonreactive
| CippGlobal
| CippRx
| Local _
| Shallow _
| Reactive _
753 | Pure _
| MaybeReactive _
| RxVar _
| Cipp _
| CippLocal _
) ) ->
754 reactivity_ordinal r1
- reactivity_ordinal r2
755 and ty_compare ty1 ty2
= ty__compare (get_node ty1
) (get_node ty2
) in
756 ty__compare ty_1 ty_2
758 and ty_compare ?
(normalize_lists
= false) ty1 ty2
=
759 ty__compare ~normalize_lists
(get_node ty1
) (get_node ty2
)
761 and tyl_compare ~sort ?
(normalize_lists
= false) tyl1 tyl2
=
764 (List.sort ~compare
:ty_compare tyl1
, List.sort ~compare
:ty_compare tyl2
)
768 List.compare
(ty_compare ~normalize_lists
) tyl1 tyl2
770 and possibly_enforced_ty_compare ?
(normalize_lists
= false) ety1 ety2
=
771 match ty_compare ~normalize_lists ety1
.et_type ety2
.et_type
with
772 | 0 -> Bool.compare ety1
.et_enforced ety2
.et_enforced
775 and ft_param_compare ?
(normalize_lists
= false) param1 param2
=
777 possibly_enforced_ty_compare ~normalize_lists param1
.fp_type param2
.fp_type
779 | 0 -> Int.compare param1
.fp_flags param2
.fp_flags
782 and ft_params_compare ?
(normalize_lists
= false) params1 params2
=
783 List.compare
(ft_param_compare ~normalize_lists
) params1 params2
785 let tyl_equal tyl1 tyl2
= Int.equal
0 @@ tyl_compare ~sort
:false tyl1 tyl2
787 let class_id_con_ordinal cid
=
795 let class_id_compare cid1 cid2
=
796 match (cid1
, cid2
) with
797 | (Aast.CIexpr _e1
, Aast.CIexpr _e2
) -> 0
798 | (Aast.CI
(_
, id1
), Aast.CI
(_
, id2
)) -> String.compare id1 id2
799 | _
-> class_id_con_ordinal cid2
- class_id_con_ordinal cid1
801 let class_id_equal cid1 cid2
= Int.equal
(class_id_compare cid1 cid2
) 0
803 let has_member_compare ~normalize_lists hm1 hm2
=
804 let ty_compare = ty_compare ~normalize_lists
in
809 hm_explicit_targs
= targs1
;
817 hm_explicit_targs
= targs2
;
821 let targ_compare (_
, (_
, hint1
)) (_
, (_
, hint2
)) =
822 Aast_defs.compare_hint_ hint1 hint2
824 match String.compare m1 m2
with
826 (match ty_compare ty1 ty2
with
828 (match class_id_compare cid1 cid2
with
829 | 0 -> Option.compare
(List.compare
targ_compare) targs1 targs2
834 let destructure_compare ~normalize_lists d1 d2
=
837 d_optional
= tyl_opt1
;
838 d_variadic
= ty_opt1
;
845 d_optional
= tyl_opt2
;
846 d_variadic
= ty_opt2
;
851 match tyl_compare ~normalize_lists ~sort
:false tyl1 tyl2
with
853 (match tyl_compare ~normalize_lists ~sort
:false tyl_opt1 tyl_opt2
with
855 (match Option.compare
ty_compare ty_opt1 ty_opt2
with
856 | 0 -> compare_destructure_kind e1 e2
861 let constraint_ty_con_ordinal cty
=
864 | Tdestructure _
-> 1
866 | TCintersection _
-> 3
868 let rec constraint_ty_compare ?
(normalize_lists
= false) ty1 ty2
=
869 let (_
, ty1
) = deref_constraint_type ty1
in
870 let (_
, ty2
) = deref_constraint_type ty2
in
871 match (ty1
, ty2
) with
872 | (Thas_member hm1
, Thas_member hm2
) ->
873 has_member_compare ~normalize_lists hm1 hm2
874 | (Tdestructure d1
, Tdestructure d2
) ->
875 destructure_compare ~normalize_lists d1 d2
876 | (TCunion
(lty1
, cty1
), TCunion
(lty2
, cty2
))
877 | (TCintersection
(lty1
, cty1
), TCintersection
(lty2
, cty2
)) ->
878 let comp1 = ty_compare ~normalize_lists lty1 lty2
in
879 if not
@@ Int.equal
comp1 0 then
882 constraint_ty_compare ~normalize_lists cty1 cty2
883 | (_
, (Thas_member _
| Tdestructure _
| TCunion _
| TCintersection _
)) ->
884 constraint_ty_con_ordinal ty2
- constraint_ty_con_ordinal ty1
886 let constraint_ty_equal ?
(normalize_lists
= false) ty1 ty2
=
887 Int.equal
(constraint_ty_compare ~normalize_lists ty1 ty2
) 0
889 let ty_equal ?
(normalize_lists
= false) ty1 ty2
=
890 Int.equal
0 (ty_compare ~normalize_lists ty1 ty2
)
892 let equal_internal_type ty1 ty2
=
893 match (ty1
, ty2
) with
894 | (LoclType ty1
, LoclType ty2
) -> ty_equal ~normalize_lists
:true ty1 ty2
895 | (ConstraintType ty1
, ConstraintType ty2
) ->
896 constraint_ty_equal ~normalize_lists
:true ty1 ty2
897 | (_
, (LoclType _
| ConstraintType _
)) -> false
899 let equal_locl_ty ty1 ty2
= ty_equal ty1 ty2
901 let equal_locl_ty_ ty_1 ty_2
= Int.equal
0 (ty__compare ty_1 ty_2
)
903 let equal_locl_fun_arity ft1 ft2
=
904 match (ft1
.ft_arity
, ft2
.ft_arity
) with
905 | (Fstandard
, Fstandard
) ->
906 Int.equal
(List.length ft1
.ft_params
) (List.length ft2
.ft_params
)
907 | (Fvariadic param1
, Fvariadic param2
) ->
908 Int.equal
0 (ft_params_compare
[param1
] [param2
])
909 | (Fstandard
, Fvariadic _
)
910 | (Fvariadic _
, Fstandard
) ->
913 let is_type_no_return = equal_locl_ty_ (Tprim
Aast.Tnoreturn
)
915 let make_function_type_rxvar param_ty
=
916 match deref param_ty
with
917 | (r
, Tfun tfun
) -> mk
(r
, Tfun
{ tfun
with ft_reactive
= RxVar None
})
922 mk
(r
, Toption
(mk
(r1
, Tfun
{ tfun
with ft_reactive
= RxVar None
})))
927 let rec equal_decl_ty_ ty_1 ty_2
=
928 match (ty_1
, ty_2
) with
929 | (Tany _
, Tany _
) -> true
930 | (Terr
, Terr
) -> true
931 | (Tthis
, Tthis
) -> true
932 | (Tmixed
, Tmixed
) -> true
933 | (Tnonnull
, Tnonnull
) -> true
934 | (Tdynamic
, Tdynamic
) -> true
935 | (Tapply
((_
, s1
), tyl1
), Tapply
((_
, s2
), tyl2
)) ->
936 String.equal s1 s2
&& equal_decl_tyl tyl1 tyl2
937 | (Tgeneric
(s1
, argl1
), Tgeneric
(s2
, argl2
)) ->
938 String.equal s1 s2
&& equal_decl_tyl argl1 argl2
939 | (Taccess
(ty1
, (_
, s1
)), Taccess
(ty2
, (_
, s2
))) ->
940 equal_decl_ty ty1 ty2
&& String.equal s1 s2
941 | (Tdarray
(tk1
, tv1
), Tdarray
(tk2
, tv2
)) ->
942 equal_decl_ty tk1 tk2
&& equal_decl_ty tv1 tv2
943 | (Tvarray ty1
, Tvarray ty2
) -> equal_decl_ty ty1 ty2
944 | (Tvarray_or_darray
(tk1
, tv1
), Tvarray_or_darray
(tk2
, tv2
)) ->
945 equal_decl_ty tk1 tk2
&& equal_decl_ty tv1 tv2
946 | (Tlike ty1
, Tlike ty2
) -> equal_decl_ty ty1 ty2
947 | (Tprim ty1
, Tprim ty2
) -> Aast.equal_tprim ty1 ty2
948 | (Toption ty
, Toption ty2
) -> equal_decl_ty ty ty2
949 | (Tfun fty1
, Tfun fty2
) -> equal_decl_fun_type fty1 fty2
950 | (Tunion tyl1
, Tunion tyl2
)
951 | (Tintersection tyl1
, Tintersection tyl2
)
952 | (Ttuple tyl1
, Ttuple tyl2
) ->
953 equal_decl_tyl tyl1 tyl2
954 | (Tshape
(shape_kind1
, fields1
), Tshape
(shape_kind2
, fields2
)) ->
955 equal_shape_kind shape_kind1 shape_kind2
957 (fun (k1
, v1
) (k2
, v2
) ->
958 Ast_defs.ShapeField.equal k1 k2
&& equal_shape_field_type v1 v2
)
959 (Nast.ShapeMap.elements fields1
)
960 (Nast.ShapeMap.elements fields2
)
961 | (Tvar v1
, Tvar v2
) -> Ident.equal v1 v2
970 | (Tvarray_or_darray _
, _
)
982 | (Tintersection _
, _
) ->
985 and equal_decl_ty ty1 ty2
= equal_decl_ty_ (get_node ty1
) (get_node ty2
)
987 and equal_shape_field_type sft1 sft2
=
988 equal_decl_ty sft1
.sft_ty sft2
.sft_ty
989 && Bool.equal sft1
.sft_optional sft2
.sft_optional
991 and equal_decl_fun_arity ft1 ft2
=
992 match (ft1
.ft_arity
, ft2
.ft_arity
) with
993 | (Fstandard
, Fstandard
) ->
994 Int.equal
(List.length ft1
.ft_params
) (List.length ft2
.ft_params
)
995 | (Fvariadic param1
, Fvariadic param2
) ->
996 equal_decl_ft_params
[param1
] [param2
]
997 | (Fstandard
, Fvariadic _
)
998 | (Fvariadic _
, Fstandard
) ->
1001 and equal_decl_fun_type fty1 fty2
=
1002 equal_decl_possibly_enforced_ty fty1
.ft_ret fty2
.ft_ret
1003 && equal_decl_ft_params fty1
.ft_params fty2
.ft_params
1004 && equal_decl_ft_implicit_params
1005 fty1
.ft_implicit_params
1006 fty2
.ft_implicit_params
1007 && equal_decl_fun_arity fty1 fty2
1008 && equal_reactivity fty1
.ft_reactive fty2
.ft_reactive
1009 && Int.equal fty1
.ft_flags fty2
.ft_flags
1011 and equal_reactivity r1 r2
=
1013 | (Nonreactive
, Nonreactive
) -> true
1014 | (Local ty1
, Local ty2
)
1015 | (Shallow ty1
, Shallow ty2
)
1016 | (Reactive ty1
, Reactive ty2
)
1017 | (Pure ty1
, Pure ty2
) ->
1018 Option.equal equal_decl_ty ty1 ty2
1019 | (MaybeReactive r1
, MaybeReactive r2
) -> equal_reactivity r1 r2
1020 | (RxVar r1
, RxVar r2
) -> Option.equal equal_reactivity r1 r2
1021 | (Cipp s1
, Cipp s2
) -> Option.equal
String.equal s1 s2
1022 | (CippLocal s1
, CippLocal s2
) -> Option.equal
String.equal s1 s2
1023 | (CippGlobal
, CippGlobal
) -> true
1024 | (CippRx
, CippRx
) -> true
1027 and any_reactive r
=
1043 and non_public_ifc ifc
=
1045 | FDPolicied
(Some
"PUBLIC") -> false
1048 and equal_param_rx_annotation pa1 pa2
=
1049 match (pa1
, pa2
) with
1050 | (Param_rx_var
, Param_rx_var
) -> true
1051 | (Param_rx_if_impl ty1
, Param_rx_if_impl ty2
) -> equal_decl_ty ty1 ty2
1052 | (Param_rx_var
, Param_rx_if_impl _
)
1053 | (Param_rx_if_impl _
, Param_rx_var
) ->
1056 and equal_decl_tyl tyl1 tyl2
= List.equal equal_decl_ty tyl1 tyl2
1058 and equal_decl_possibly_enforced_ty ety1 ety2
=
1059 equal_decl_ty ety1
.et_type ety2
.et_type
1060 && Bool.equal ety1
.et_enforced ety2
.et_enforced
1062 and equal_decl_fun_param param1 param2
=
1063 equal_decl_possibly_enforced_ty param1
.fp_type param2
.fp_type
1064 && Int.equal param1
.fp_flags param2
.fp_flags
1066 and equal_decl_ft_params params1 params2
=
1067 List.equal equal_decl_fun_param params1 params2
1069 and equal_decl_ft_implicit_params
{ capability
= cap1
} { capability
= cap2
} =
1070 (* TODO(coeffects): could rework this so that implicit defaults and explicit
1071 * [defaults] are considered equal *)
1072 match (cap1
, cap2
) with
1073 | (CapDefaults p1
, CapDefaults p2
) -> Pos.equal p1 p2
1074 | (CapTy c1
, CapTy c2
) -> equal_decl_ty c1 c2
1075 | (CapDefaults _
, CapTy _
)
1076 | (CapTy _
, CapDefaults _
) ->
1079 let equal_typeconst_abstract_kind ak1 ak2
=
1080 match (ak1
, ak2
) with
1081 | (TCAbstract ty1
, TCAbstract ty2
) -> Option.equal equal_decl_ty ty1 ty2
1082 | (TCPartiallyAbstract
, TCPartiallyAbstract
) -> true
1083 | (TCConcrete
, TCConcrete
) -> true
1085 | (TCPartiallyAbstract
, _
)
1086 | (TCConcrete
, _
) ->
1089 let equal_enum_type et1 et2
=
1090 equal_decl_ty et1
.te_base et2
.te_base
1091 && Option.equal equal_decl_ty et1
.te_constraint et2
.te_constraint
1093 let equal_decl_where_constraint c1 c2
=
1094 let (tya1
, ck1
, tyb1
) = c1
in
1095 let (tya2
, ck2
, tyb2
) = c2
in
1096 equal_decl_ty tya1 tya2
1097 && Ast_defs.equal_constraint_kind ck1 ck2
1098 && equal_decl_ty tyb1 tyb2
1100 let equal_decl_tparam tp1 tp2
=
1101 Ast_defs.equal_variance tp1
.tp_variance tp2
.tp_variance
1102 && Ast_defs.equal_id tp1
.tp_name tp2
.tp_name
1104 (Tuple.T2.equal ~eq1
:Ast_defs.equal_constraint_kind ~eq2
:equal_decl_ty
)
1107 && Aast.equal_reify_kind tp1
.tp_reified tp2
.tp_reified
1109 equal_user_attribute
1110 tp1
.tp_user_attributes
1111 tp2
.tp_user_attributes
1113 let equal_typedef_type tt1 tt2
=
1114 Pos.equal tt1
.td_pos tt2
.td_pos
1115 && Aast.equal_typedef_visibility tt1
.td_vis tt2
.td_vis
1116 && List.equal
equal_decl_tparam tt1
.td_tparams tt2
.td_tparams
1117 && Option.equal equal_decl_ty tt1
.td_constraint tt2
.td_constraint
1118 && equal_decl_ty tt1
.td_type tt2
.td_type
1120 let equal_fun_elt fe1 fe2
=
1121 Option.equal
String.equal fe1
.fe_deprecated fe2
.fe_deprecated
1122 && equal_decl_ty fe1
.fe_type fe2
.fe_type
1123 && Pos.equal fe1
.fe_pos fe2
.fe_pos
1125 let equal_const_decl cd1 cd2
=
1126 Pos.equal cd1
.cd_pos cd2
.cd_pos
&& equal_decl_ty cd1
.cd_type cd2
.cd_type
1128 let get_ce_abstract ce
= is_set ce_flags_abstract ce
.ce_flags
1130 let get_ce_final ce
= is_set ce_flags_final ce
.ce_flags
1132 let get_ce_override ce
= is_set ce_flags_override ce
.ce_flags
1134 let get_ce_lsb ce
= is_set ce_flags_lsb ce
.ce_flags
1136 let get_ce_synthesized ce
= is_set ce_flags_synthesized ce
.ce_flags
1138 let get_ce_const ce
= is_set ce_flags_const ce
.ce_flags
1140 let get_ce_lateinit ce
= is_set ce_flags_lateinit ce
.ce_flags
1142 let get_ce_dynamicallycallable ce
=
1143 is_set ce_flags_dynamicallycallable ce
.ce_flags
1145 let xhp_attr_to_ce_flags xa
=
1148 | Some
{ xa_tag
; xa_has_default
} ->
1150 ( if xa_has_default
then
1151 ce_flags_xa_has_default
1156 | None
-> ce_flags_xa_tag_none
1157 | Some Required
-> ce_flags_xa_tag_required
1158 | Some Lateinit
-> ce_flags_xa_tag_lateinit
)
1160 let flags_to_xhp_attr flags
=
1161 let tag_flags = Int.bit_and ce_flags_xa_tag_mask flags
in
1162 if Int.equal
tag_flags 0 then
1167 xa_has_default
= is_set ce_flags_xa_has_default flags
;
1169 ( if Int.equal
tag_flags ce_flags_xa_tag_none
then
1171 else if Int.equal
tag_flags ce_flags_xa_tag_required
then
1177 let get_ce_xhp_attr ce
= flags_to_xhp_attr ce
.ce_flags
1188 ~dynamicallycallable
=
1190 let flags = set_bit ce_flags_abstract abstract
flags in
1191 let flags = set_bit ce_flags_final final
flags in
1192 let flags = set_bit ce_flags_override override
flags in
1193 let flags = set_bit ce_flags_lsb lsb
flags in
1194 let flags = set_bit ce_flags_synthesized synthesized
flags in
1195 let flags = set_bit ce_flags_const const
flags in
1196 let flags = set_bit ce_flags_lateinit lateinit
flags in
1197 let flags = set_bit ce_flags_dynamicallycallable dynamicallycallable
flags in
1198 let flags = Int.bit_or
flags (xhp_attr_to_ce_flags xhp_attr
) in
1201 (** Tunapplied_alias is a locl phase constructor that always stands for a higher-kinded type.
1202 We use this function in cases where Tunapplied_alias appears in a context where we expect
1203 a fully applied type, rather than a type constructor. Seeing Tunapplied_alias in such a context
1204 always indicates a kinding error, which means that during localization, we should have
1205 created Terr rather than Tunapplied_alias. Hence, this is an *internal* error, because
1206 something went wrong during localization. Kind mismatches in code are reported to users
1208 let error_Tunapplied_alias_in_illegal_context () =
1209 failwith
"Found Tunapplied_alias in a context where it must not occur"
1211 module Attributes
= struct
1213 List.exists xs
(fun { ua_name
; _
} -> String.equal x
(snd ua_name
))
1216 List.find xs
(fun { ua_name
; _
} -> String.equal x
(snd ua_name
))