@@ -1829,8 +1829,7 @@ let subst env level priv abbrev oty params args body =
1829
1829
| _ -> assert false
1830
1830
in
1831
1831
abbreviations := abbrev;
1832
- let (params', body') = instance_parameterized_type params body
1833
- in
1832
+ let (params', body') = instance_parameterized_type params body in
1834
1833
abbreviations := ref Mnil ;
1835
1834
let uenv = Expression {env; in_subst = true } in
1836
1835
try
@@ -2117,16 +2116,66 @@ let expand_head_opt env ty =
2117
2116
let is_principal ty =
2118
2117
not ! Clflags. principal || get_level ty = generic_level
2119
2118
2119
+ module Bound_vars : sig
2120
+ type t
2121
+
2122
+ val empty : t
2123
+ val of_list : type_expr list -> t
2124
+ val add : t -> type_expr list -> t
2125
+ val union : t -> t -> t
2126
+ val mem : t -> type_expr -> bool
2127
+ val is_empty : t -> bool
2128
+ end = struct
2129
+ (* It is rare to care about which variables have been bound. This
2130
+ implementation prioritizes the common case of caring only about the
2131
+ presence of variables. *)
2132
+ type t = { is_empty : bool ; var_set : TypeSet .t Lazy .t }
2133
+
2134
+ let empty = { is_empty = true ; var_set = Lazy. from_val TypeSet. empty }
2135
+
2136
+ let of_list = function
2137
+ | [] -> empty
2138
+ | new_ones ->
2139
+ let var_set =
2140
+ lazy (TypeSet. of_list (List. map Transient_expr. repr new_ones))
2141
+ in
2142
+ { is_empty = false ; var_set }
2143
+
2144
+ let add t = function
2145
+ | [] -> t
2146
+ | new_ones ->
2147
+ let var_set = lazy begin
2148
+ let new_ones_set =
2149
+ TypeSet. of_list (List. map Transient_expr. repr new_ones)
2150
+ in
2151
+ TypeSet. union new_ones_set (Lazy. force t.var_set)
2152
+ end in
2153
+ { is_empty = false ; var_set }
2154
+
2155
+ let union ({ is_empty = empty1 ; var_set = set1 } as t1 )
2156
+ ({ is_empty = empty2 ; var_set = set2 } as t2 ) =
2157
+ match empty1, empty2 with
2158
+ | true , true -> empty
2159
+ | true , false -> t2
2160
+ | false , true -> t1
2161
+ | false , false ->
2162
+ let var_set = lazy (TypeSet. union (Lazy. force set1) (Lazy. force set2)) in
2163
+ { is_empty = false ; var_set }
2164
+
2165
+ let mem { is_empty; var_set } ty =
2166
+ not is_empty &&
2167
+ TypeSet. mem ty (Lazy. force var_set)
2168
+
2169
+ let is_empty { is_empty } = is_empty
2170
+ end
2171
+
2120
2172
type unwrapped_type_expr =
2121
2173
{ ty : type_expr
2122
- ; bound_vars : TypeSet .t
2174
+ ; bound_vars : Bound_vars .t
2123
2175
; modality : Mode.Modality.Value.Const .t }
2124
2176
2125
2177
let mk_unwrapped_type_expr ty =
2126
- { ty; bound_vars = TypeSet. empty; modality = Mode.Modality.Value.Const. id }
2127
-
2128
- let mk_bound_vars vars_list =
2129
- TypeSet. of_list (List. map Transient_expr. repr vars_list)
2178
+ { ty; bound_vars = Bound_vars. empty; modality = Mode.Modality.Value.Const. id }
2130
2179
2131
2180
type unbox_result =
2132
2181
(* unboxing process made a step: either an unboxing or removal of a [Tpoly] *)
@@ -2163,7 +2212,7 @@ let unbox_once env ty =
2163
2212
| exception Not_found -> (* but we found it earlier! *) assert false
2164
2213
in
2165
2214
Stepped { ty = apply ty2 existentials;
2166
- bound_vars = mk_bound_vars existentials;
2215
+ bound_vars = Bound_vars. of_list existentials;
2167
2216
modality }
2168
2217
| None -> begin match decl.type_kind with
2169
2218
| Type_record_unboxed_product ([_ ], Record_unboxed_product, _ ) ->
@@ -2173,7 +2222,7 @@ let unbox_once env ty =
2173
2222
((_::_::_ as lbls), Record_unboxed_product , _) ->
2174
2223
Stepped_record_unboxed_product
2175
2224
(List. map (fun ld -> { ty = apply ld.ld_type [] ;
2176
- bound_vars = TypeSet . empty;
2225
+ bound_vars = Bound_vars . empty;
2177
2226
modality = ld.ld_modalities }) lbls)
2178
2227
| Type_record_unboxed_product ([] , _ , _ ) ->
2179
2228
Misc. fatal_error " Ctype.unboxed_once: fieldless record"
@@ -2184,7 +2233,7 @@ let unbox_once env ty =
2184
2233
end
2185
2234
| Tpoly (ty , bound_vars ) ->
2186
2235
Stepped { ty;
2187
- bound_vars = mk_bound_vars bound_vars;
2236
+ bound_vars = Bound_vars. of_list bound_vars;
2188
2237
modality = Mode.Modality.Value.Const. id }
2189
2238
| _ -> Final_result
2190
2239
@@ -2215,7 +2264,7 @@ let rec get_unboxed_type_representation
2215
2264
let ty = expand_head_opt env ty in
2216
2265
match unbox_once env ty with
2217
2266
| Stepped { ty = ty2 ; bound_vars = bound_vars2 ; modality = modality2 } ->
2218
- let bound_vars = TypeSet . union bound_vars bound_vars2 in
2267
+ let bound_vars = Bound_vars . union bound_vars bound_vars2 in
2219
2268
let modality =
2220
2269
Mode.Modality.Value.Const. concat modality ~then_: modality2
2221
2270
in
@@ -2228,7 +2277,7 @@ let rec get_unboxed_type_representation
2228
2277
let get_unboxed_type_representation env ty =
2229
2278
(* Do not give too much fuel: PR#7424 *)
2230
2279
get_unboxed_type_representation
2231
- ~bound_vars: TypeSet . empty
2280
+ ~bound_vars: Bound_vars . empty
2232
2281
~modality: Mode.Modality.Value.Const. id
2233
2282
env ty ty 100
2234
2283
@@ -2267,8 +2316,8 @@ let rec estimate_type_jkind ~expand_component env ty =
2267
2316
let { ty; bound_vars = bound_vars2; modality } =
2268
2317
expand_component ty
2269
2318
in
2270
- TypeSet . union bound_vars1 bound_vars2, (ty, modality))
2271
- TypeSet . empty ltys
2319
+ Bound_vars . union bound_vars1 bound_vars2, (ty, modality))
2320
+ Bound_vars . empty ltys
2272
2321
in
2273
2322
(* CR layouts v2.8: This pretty ridiculous use of [estimate_type_jkind]
2274
2323
just to throw most of it away will go away once we get [layout_of]. *)
@@ -2325,7 +2374,7 @@ let rec estimate_type_jkind ~expand_component env ty =
2325
2374
| Tpackage _ -> Jkind.Builtin. value ~why: First_class_module
2326
2375
2327
2376
and close_open_jkind ~expand_component ~bound_vars env jkind =
2328
- if not (TypeSet . is_empty bound_vars)
2377
+ if not (Bound_vars . is_empty bound_vars)
2329
2378
(* if the type has free variables, we can't let these leak into with-bounds *)
2330
2379
(* CR layouts v2.8: Do better, by rounding only the bound variables up. *)
2331
2380
then
@@ -2397,7 +2446,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2397
2446
later).
2398
2447
2399
2448
As this unboxes types, it might unbox an existential type. We thus keep
2400
- track of the variables bound as we unbox (and look through [Tpoly]s.
2449
+ track of the variables bound as we unbox (and look through [Tpoly]s) .
2401
2450
Comparing these variables in jkinds is fine, and they can't escape from
2402
2451
this function (except harmlessly in error messages). However, we must be
2403
2452
sure not to change the kinds of these bound variables; that's the only
@@ -2422,7 +2471,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2422
2471
the call to [intersection_or_error]. And even if [ty] has unbound
2423
2472
variables, [ty's_jkind] can't have any variables in it, so we're OK. *)
2424
2473
| Tvar { jkind = ty's_jkind } when not fixed &&
2425
- not (TypeSet . mem ty bound_vars) ->
2474
+ not (Bound_vars . mem bound_vars ty ) ->
2426
2475
(* Unfixed tyvars are special in at least two ways:
2427
2476
2428
2477
1) Suppose we're processing [type 'a t = 'a list]. The ['a] on the
@@ -2452,7 +2501,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2452
2501
(* Handle the [Tpoly] case out here so [Tvar]s wrapped in [Tpoly]s can get
2453
2502
the treatment above. *)
2454
2503
| Tpoly (t , bound_vars2 ) ->
2455
- let bound_vars = TypeSet. union bound_vars (mk_bound_vars bound_vars2) in
2504
+ let bound_vars = Bound_vars. add bound_vars bound_vars2 in
2456
2505
loop ~fuel ~expanded: false t ~bound_vars ty's_jkind jkind
2457
2506
2458
2507
| _ ->
@@ -2479,7 +2528,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2479
2528
let results =
2480
2529
Misc.Stdlib.List. map3
2481
2530
(fun { ty; bound_vars = bound_vars2 ; modality } ty's_jkind jkind ->
2482
- let bound_vars = TypeSet . union bound_vars bound_vars2 in
2531
+ let bound_vars = Bound_vars . union bound_vars bound_vars2 in
2483
2532
let jkind =
2484
2533
Jkind. apply_modality_r modality jkind
2485
2534
in
@@ -2529,7 +2578,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2529
2578
(Jkind.Violation. of_ ~jkind_of_type
2530
2579
(Not_a_subjkind (ty's_jkind, jkind, sub_failure_reasons)))
2531
2580
| Stepped { ty; bound_vars = bound_vars2 ; modality } ->
2532
- let bound_vars = TypeSet . union bound_vars bound_vars2 in
2581
+ let bound_vars = Bound_vars . union bound_vars bound_vars2 in
2533
2582
let jkind = Jkind. apply_modality_r modality jkind in
2534
2583
loop ~fuel: (fuel - 1 ) ~expanded: false ty ~bound_vars
2535
2584
(estimate_type_jkind env ty) jkind
@@ -2547,7 +2596,7 @@ let constrain_type_jkind ~fixed env ty jkind =
2547
2596
Error (Jkind.Violation. of_ ~jkind_of_type
2548
2597
(Not_a_subjkind (ty's_jkind, jkind, sub_failure_reasons)))
2549
2598
in
2550
- loop ~fuel: 100 ~expanded: false ty ~bound_vars: TypeSet . empty
2599
+ loop ~fuel: 100 ~expanded: false ty ~bound_vars: Bound_vars . empty
2551
2600
(estimate_type_jkind env ty) (Jkind. disallow_left jkind)
2552
2601
2553
2602
let type_sort ~why ~fixed env ty =
0 commit comments