Skip to content

Commit a783691

Browse files
Michael Thomasfacebook-github-bot
authored andcommitted
Support transformation on refined constant bounds
Summary: Adds another transform function to the top-down transformation of decl types. This will be used during analysis of variance for type parameters where we wish to treat type parameters occuring inside refinements as invariant Reviewed By: mheiber Differential Revision: D78659823 fbshipit-source-id: b76023e817845ff07ff6bc6c9ddd151266eda17a
1 parent 5ac39c6 commit a783691

4 files changed

Lines changed: 111 additions & 60 deletions

File tree

hphp/hack/src/typing/typing_defs_core.ml

Lines changed: 76 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,52 +2008,80 @@ end
20082008
let find_locl_ty locl_ty ~p = Find_locl.find_ty locl_ty ~p
20092009

20102010
module Transform_top_down_decl = struct
2011-
let rec transform ty ~f ~ctx =
2012-
match f ty ~ctx with
2011+
let rec transform ty ~on_ty ~on_rc_bound ~ctx =
2012+
match on_ty ty ~ctx with
20132013
| (_, `Stop ty) -> ty
2014-
| (ctx, `Continue ty) -> traverse ty ~f ~ctx
2015-
| (ctx, `Restart ty) -> transform ty ~f ~ctx
2014+
| (ctx, `Continue ty) -> traverse ty ~on_ty ~on_rc_bound ~ctx
2015+
| (ctx, `Restart ty) -> transform ty ~on_ty ~on_rc_bound ~ctx
20162016

2017-
and traverse ty ~f ~ctx =
2017+
and traverse ty ~on_ty ~on_rc_bound ~ctx =
20182018
match deref ty with
20192019
| ( _,
20202020
( Tthis | Tmixed | Twildcard | Tany _ | Tnonnull | Tdynamic | Tprim _
20212021
| Tgeneric _ ) ) ->
20222022
ty
2023-
| (r, Tlike ty) -> mk (r, Tlike (transform ty ~f ~ctx))
2024-
| (r, Toption ty) -> mk (r, Toption (transform ty ~f ~ctx))
2025-
| (r, Tclass_ptr ty) -> mk (r, Tclass_ptr (transform ty ~f ~ctx))
2026-
| (r, Taccess (ty, id)) -> mk (r, Taccess (transform ty ~f ~ctx, id))
2023+
| (r, Tlike ty) -> mk (r, Tlike (transform ty ~on_ty ~on_rc_bound ~ctx))
2024+
| (r, Toption ty) -> mk (r, Toption (transform ty ~on_ty ~on_rc_bound ~ctx))
2025+
| (r, Tclass_ptr ty) ->
2026+
mk (r, Tclass_ptr (transform ty ~on_ty ~on_rc_bound ~ctx))
2027+
| (r, Taccess (ty, id)) ->
2028+
mk (r, Taccess (transform ty ~on_ty ~on_rc_bound ~ctx, id))
20272029
| (r, Tvec_or_dict (ty_k, ty_v)) ->
2028-
mk (r, Tvec_or_dict (transform ty_k ~f ~ctx, transform ty_v ~f ~ctx))
2029-
| (r, Tunion tys) -> mk (r, Tunion (List.map tys ~f:(transform ~f ~ctx)))
2030+
mk
2031+
( r,
2032+
Tvec_or_dict
2033+
( transform ty_k ~on_ty ~on_rc_bound ~ctx,
2034+
transform ty_v ~on_ty ~on_rc_bound ~ctx ) )
2035+
| (r, Tunion tys) ->
2036+
mk (r, Tunion (List.map tys ~f:(transform ~on_ty ~on_rc_bound ~ctx)))
20302037
| (r, Tintersection tys) ->
2031-
mk (r, Tintersection (List.map tys ~f:(transform ~f ~ctx)))
2038+
mk
2039+
(r, Tintersection (List.map tys ~f:(transform ~on_ty ~on_rc_bound ~ctx)))
20322040
| (r, Tapply (id, tys)) ->
2033-
mk (r, Tapply (id, List.map tys ~f:(transform ~f ~ctx)))
2041+
mk (r, Tapply (id, List.map tys ~f:(transform ~on_ty ~on_rc_bound ~ctx)))
20342042
| (r, Trefinement (ty, class_refinement)) ->
20352043
mk
20362044
( r,
20372045
Trefinement
2038-
( transform ty ~f ~ctx,
2039-
traverse_class_refinement class_refinement ~f ~ctx ) )
2040-
| (r, Tfun fun_ty) -> mk (r, Tfun (traverse_fun_ty fun_ty ~f ~ctx))
2041-
| (r, Ttuple tuple_ty) -> mk (r, Ttuple (traverse_tuple_ty tuple_ty ~f ~ctx))
2042-
| (r, Tshape shape_ty) -> mk (r, Tshape (traverse_shape_ty shape_ty ~f ~ctx))
2046+
( transform ty ~on_ty ~on_rc_bound ~ctx,
2047+
traverse_class_refinement
2048+
class_refinement
2049+
~on_ty
2050+
~on_rc_bound
2051+
~ctx ) )
2052+
| (r, Tfun fun_ty) ->
2053+
mk (r, Tfun (traverse_fun_ty fun_ty ~on_ty ~on_rc_bound ~ctx))
2054+
| (r, Ttuple tuple_ty) ->
2055+
mk (r, Ttuple (traverse_tuple_ty tuple_ty ~on_ty ~on_rc_bound ~ctx))
2056+
| (r, Tshape shape_ty) ->
2057+
mk (r, Tshape (traverse_shape_ty shape_ty ~on_ty ~on_rc_bound ~ctx))
20432058

2044-
and traverse_class_refinement { cr_consts } ~f ~ctx =
2045-
{ cr_consts = SMap.map (traverse_refined_const ~f ~ctx) cr_consts }
2059+
and traverse_class_refinement { cr_consts } ~on_ty ~on_rc_bound ~ctx =
2060+
{
2061+
cr_consts =
2062+
SMap.map (traverse_refined_const ~on_ty ~on_rc_bound ~ctx) cr_consts;
2063+
}
20462064

2047-
and traverse_refined_const { rc_bound; rc_is_ctx } ~f ~ctx =
2048-
let rc_bound = traverse_rc_bound rc_bound ~f ~ctx in
2065+
and traverse_refined_const { rc_bound; rc_is_ctx } ~on_ty ~on_rc_bound ~ctx =
2066+
let rc_bound = transform_rc_bound rc_bound ~on_ty ~on_rc_bound ~ctx in
20492067
{ rc_bound; rc_is_ctx }
20502068

2051-
and traverse_rc_bound rc_bound ~f ~ctx =
2069+
and transform_rc_bound rc_bound ~on_ty ~on_rc_bound ~ctx =
2070+
match on_rc_bound rc_bound ~ctx with
2071+
| (_, `Stop rc_bound) -> rc_bound
2072+
| (ctx, `Continue rc_bound) ->
2073+
traverse_rc_bound rc_bound ~on_ty ~on_rc_bound ~ctx
2074+
| (ctx, `Restart rc_bound) ->
2075+
transform_rc_bound rc_bound ~on_ty ~on_rc_bound ~ctx
2076+
2077+
and traverse_rc_bound rc_bound ~on_ty ~on_rc_bound ~ctx =
20522078
match rc_bound with
2053-
| TRexact ty -> TRexact (transform ty ~f ~ctx)
2079+
| TRexact ty -> TRexact (transform ty ~on_ty ~on_rc_bound ~ctx)
20542080
| TRloose { tr_lower; tr_upper } ->
2055-
let tr_lower = List.map tr_lower ~f:(transform ~f ~ctx)
2056-
and tr_upper = List.map tr_upper ~f:(transform ~f ~ctx) in
2081+
let tr_lower = List.map tr_lower ~f:(transform ~on_ty ~on_rc_bound ~ctx)
2082+
and tr_upper =
2083+
List.map tr_upper ~f:(transform ~on_ty ~on_rc_bound ~ctx)
2084+
in
20572085
TRloose { tr_lower; tr_upper }
20582086

20592087
and traverse_fun_ty
@@ -2065,28 +2093,32 @@ module Transform_top_down_decl = struct
20652093
ft_ret;
20662094
_;
20672095
} as fun_ty)
2068-
~f
2096+
~on_ty
2097+
~on_rc_bound
20692098
~ctx =
20702099
let ft_tparams =
20712100
List.map ft_tparams ~f:(fun ({ tp_constraints; _ } as tparam) ->
20722101
let tp_constraints =
20732102
List.map tp_constraints ~f:(fun (cstr_kind, ty) ->
2074-
(cstr_kind, transform ty ~f ~ctx))
2103+
(cstr_kind, transform ty ~on_ty ~on_rc_bound ~ctx))
20752104
in
20762105
{ tparam with tp_constraints })
20772106
and ft_params =
20782107
List.map ft_params ~f:(fun ({ fp_type; _ } as fun_param) ->
2079-
let fp_type = transform fp_type ~f ~ctx in
2108+
let fp_type = transform fp_type ~on_ty ~on_rc_bound ~ctx in
20802109
{ fun_param with fp_type })
20812110
and ft_implicit_params =
20822111
let { capability } = ft_implicit_params in
20832112
match capability with
20842113
| CapDefaults _ -> ft_implicit_params
2085-
| CapTy ty -> { capability = CapTy (transform ty ~f ~ctx) }
2114+
| CapTy ty ->
2115+
{ capability = CapTy (transform ty ~on_ty ~on_rc_bound ~ctx) }
20862116
and ft_where_constraints =
20872117
List.map ft_where_constraints ~f:(fun (ty1, cstr_kind, ty2) ->
2088-
(transform ty1 ~f ~ctx, cstr_kind, transform ty2 ~f ~ctx))
2089-
and ft_ret = transform ft_ret ~f ~ctx in
2118+
( transform ty1 ~on_ty ~on_rc_bound ~ctx,
2119+
cstr_kind,
2120+
transform ty2 ~on_ty ~on_rc_bound ~ctx ))
2121+
and ft_ret = transform ft_ret ~on_ty ~on_rc_bound ~ctx in
20902122
{
20912123
fun_ty with
20922124
ft_tparams;
@@ -2096,32 +2128,34 @@ module Transform_top_down_decl = struct
20962128
ft_ret;
20972129
}
20982130

2099-
and traverse_tuple_ty { t_required; t_extra } ~f ~ctx =
2100-
let t_required = List.map t_required ~f:(transform ~f ~ctx)
2131+
and traverse_tuple_ty { t_required; t_extra } ~on_ty ~on_rc_bound ~ctx =
2132+
let t_required = List.map t_required ~f:(transform ~on_ty ~on_rc_bound ~ctx)
21012133
and t_extra =
21022134
match t_extra with
2103-
| Tsplat ty -> Tsplat (transform ty ~f ~ctx)
2135+
| Tsplat ty -> Tsplat (transform ty ~on_ty ~on_rc_bound ~ctx)
21042136
| Textra { t_optional; t_variadic } ->
2105-
let t_optional = List.map t_optional ~f:(transform ~f ~ctx)
2106-
and t_variadic = transform t_variadic ~f ~ctx in
2137+
let t_optional =
2138+
List.map t_optional ~f:(transform ~on_ty ~on_rc_bound ~ctx)
2139+
and t_variadic = transform t_variadic ~on_ty ~on_rc_bound ~ctx in
21072140
Textra { t_optional; t_variadic }
21082141
in
21092142
{ t_required; t_extra }
21102143

2111-
and traverse_shape_ty { s_origin; s_unknown_value; s_fields } ~f ~ctx =
2112-
let s_unknown_value = transform s_unknown_value ~f ~ctx
2144+
and traverse_shape_ty
2145+
{ s_origin; s_unknown_value; s_fields } ~on_ty ~on_rc_bound ~ctx =
2146+
let s_unknown_value = transform s_unknown_value ~on_ty ~on_rc_bound ~ctx
21132147
and s_fields =
21142148
TShapeMap.map
21152149
(fun { sft_optional; sft_ty } ->
2116-
let sft_ty = transform sft_ty ~f ~ctx in
2150+
let sft_ty = transform sft_ty ~on_ty ~on_rc_bound ~ctx in
21172151
{ sft_optional; sft_ty })
21182152
s_fields
21192153
in
21202154
{ s_origin; s_unknown_value; s_fields }
21212155
end
21222156

2123-
let transform_top_down_decl_ty decl_ty ~f ~ctx =
2124-
Transform_top_down_decl.transform decl_ty ~f ~ctx
2157+
let transform_top_down_decl_ty decl_ty ~on_ty ~on_rc_bound ~ctx =
2158+
Transform_top_down_decl.transform decl_ty ~on_ty ~on_rc_bound ~ctx
21252159

21262160
let is_type_tag_generic_wildcard generic =
21272161
match generic with

hphp/hack/src/typing/typing_defs_core.mli

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,18 @@ val find_locl_ty : locl_ty -> p:(locl_ty -> bool) -> locl_ty option
799799
(** Transform a decl ty top down *)
800800
val transform_top_down_decl_ty :
801801
decl_ty ->
802-
f:
802+
on_ty:
803803
(decl_ty ->
804804
ctx:'a ->
805805
'a * [< `Continue of decl_ty | `Stop of decl_ty | `Restart of decl_ty ]) ->
806+
on_rc_bound:
807+
(decl_phase refined_const_bound ->
808+
ctx:'a ->
809+
'a
810+
* [< `Continue of decl_phase refined_const_bound
811+
| `Stop of decl_phase refined_const_bound
812+
| `Restart of decl_phase refined_const_bound
813+
]) ->
806814
ctx:'a ->
807815
decl_ty
808816

hphp/hack/src/typing/typing_extract_method.ml

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -527,21 +527,21 @@ end = struct
527527
build this reason rest ~k:(fun root ->
528528
k (mk (reason, Taccess (root, next))))
529529
in
530-
let f ty ~ctx =
530+
let on_ty ty ~ctx =
531531
match deref ty with
532532
| (reason, Tthis) -> build ty reason prefix ~k:(fun ty -> (ctx, `Stop ty))
533533
| _ -> (ctx, `Continue ty)
534-
in
535-
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~f
534+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
535+
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~on_ty ~on_rc_bound
536536

537537
let replace_this_with ty ~replacement =
538538
let open Typing_defs_core in
539-
let f ty ~ctx =
539+
let on_ty ty ~ctx =
540540
match get_node ty with
541541
| Tthis -> (ctx, `Stop replacement)
542542
| _ -> (ctx, `Continue ty)
543-
in
544-
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~f
543+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
544+
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~on_ty ~on_rc_bound
545545

546546
(** Accumulate all types mentioned in the definition or bounds of a type constant *)
547547
let accumulate_tys typeconst tys =
@@ -578,8 +578,10 @@ end = struct
578578
in
579579
(ctx, `Stop decl_ty)
580580
| _ -> (ctx, `Continue decl_ty)
581+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
582+
let _ =
583+
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~on_ty ~on_rc_bound
581584
in
582-
let _ = Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~f:on_ty in
583585
!paths
584586
(* -- Core logic --------------------------------------------------------- *)
585587

@@ -855,17 +857,21 @@ end = struct
855857
(* For the analysis of this we need to subsitute occurrences of typeconst
856858
access rooted in the explicit class with [this] *)
857859
let this_trie =
858-
let f ty ~ctx =
860+
let on_ty ty ~ctx =
859861
let open Typing_defs_core in
860862
match deref ty with
861863
| (reason, Tapply ((_, class_name), _))
862864
when String.equal this_name class_name ->
863865
(ctx, `Stop (mk (reason, Tthis)))
864866
| _ -> (ctx, `Continue ty)
865-
in
867+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
866868
Trie.transform
867869
this_trie
868-
~f:(Typing_defs_core.transform_top_down_decl_ty ~ctx:() ~f)
870+
~f:
871+
(Typing_defs_core.transform_top_down_decl_ty
872+
~ctx:()
873+
~on_ty
874+
~on_rc_bound)
869875
in
870876
{ t with this_trie; tries }
871877

@@ -893,7 +899,7 @@ end = struct
893899

894900
(* -- Application ------------------------------------------------------- *)
895901
let apply { this_name; this_ty; this_subst; class_subst; _ } ty =
896-
let transform ty ~ctx =
902+
let on_ty ty ~ctx =
897903
let open Typing_defs_core in
898904
match get_node ty with
899905
| Tthis -> (ctx, `Stop this_ty)
@@ -937,10 +943,11 @@ end = struct
937943
(ctx, `Restart ty))
938944
end
939945
| _ -> (ctx, `Continue ty)
940-
in
946+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
941947
Typing_defs_core.transform_top_down_decl_ty
942948
ty
943-
~f:transform
949+
~on_ty
950+
~on_rc_bound
944951
~ctx:SSet.empty
945952

946953
let apply_fun_ty t fun_ty =
@@ -1238,8 +1245,10 @@ let ty_generics names ty =
12381245
let () = acc := SSet.add nm !acc in
12391246
(ctx, `Stop decl_ty)
12401247
| _ -> (ctx, `Continue decl_ty)
1248+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
1249+
let _ =
1250+
Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~on_ty ~on_rc_bound
12411251
in
1242-
let _ = Typing_defs_core.transform_top_down_decl_ty ty ~ctx:() ~f:on_ty in
12431252
!acc
12441253

12451254
let drop_unused_generics fun_ty ~names =

hphp/hack/src/typing/typing_taccess.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ let eliminate_recursive_access ty type_const_name this_ty =
132132
match get_node this_ty with
133133
| Tdependent (DTexpr expr_id, _) ->
134134
let this_name = Expression_id.display expr_id in
135-
let f ty ~ctx =
135+
let on_ty ty ~ctx =
136136
match deref ty with
137137
| (reason, Taccess (root_ty, (_, name)))
138138
when String.equal name type_const_name -> begin
@@ -147,8 +147,8 @@ let eliminate_recursive_access ty type_const_name this_ty =
147147
| _ -> (ctx, `Continue ty)
148148
end
149149
| _ -> (ctx, `Continue ty)
150-
in
151-
Typing_defs_core.transform_top_down_decl_ty ty ~f ~ctx:()
150+
and on_rc_bound rc_bound ~ctx = (ctx, `Continue rc_bound) in
151+
Typing_defs_core.transform_top_down_decl_ty ty ~on_ty ~on_rc_bound ~ctx:()
152152
| _ -> ty
153153

154154
(** [create_root_from_type_constant ctx env root class_name class_]

0 commit comments

Comments
 (0)