@@ -29,6 +29,9 @@ let raw_type_expr : (Format.formatter -> type_expr -> unit) ref =
29
29
30
30
let set_raw_type_expr p = raw_type_expr := p
31
31
32
+ let constructor_unbound_type_vars_excluding_row_variables =
33
+ ref (fun _ -> assert false )
34
+
32
35
module Nonempty_list = Misc. Nonempty_list
33
36
34
37
(* A *sort* is the information the middle/back ends need to be able to
@@ -2274,7 +2277,7 @@ let for_unboxed_record lbls =
2274
2277
in
2275
2278
Builtin. product ~why: Unboxed_record tys_modalities layouts
2276
2279
2277
- let for_boxed_variant cstrs =
2280
+ let for_boxed_variant ~ decl_params ~ type_apply cstrs =
2278
2281
let open Types in
2279
2282
if List. for_all
2280
2283
(fun cstr ->
@@ -2298,16 +2301,129 @@ let for_boxed_variant cstrs =
2298
2301
~why: Boxed_variant
2299
2302
|> mark_best
2300
2303
in
2301
- let add_cstr_args cstr jkind =
2302
- match cstr.cd_args with
2303
- | Cstr_tuple args ->
2304
- List. fold_right
2305
- (fun arg ->
2306
- add_with_bounds ~modality: arg.ca_modalities ~type_expr: arg.ca_type)
2307
- args jkind
2308
- | Cstr_record lbls -> add_labels_as_with_bounds lbls jkind
2304
+ let has_gadt_constructors =
2305
+ List. exists (fun cstr -> Option. is_some cstr.cd_res) cstrs
2306
+ in
2307
+ let module Variant_parts = struct
2308
+ type t =
2309
+ { cstr_arg_tys : type_expr list ;
2310
+ cstr_arg_modalities : Mode.Modality.Value.Const .t list ;
2311
+ params : type_expr list ;
2312
+ ret_args : type_expr list ;
2313
+ seen : Btype.TypeSet .t
2314
+ }
2315
+
2316
+ let empty =
2317
+ { cstr_arg_tys = [] ;
2318
+ cstr_arg_modalities = [] ;
2319
+ params = [] ;
2320
+ ret_args = [] ;
2321
+ seen = Btype.TypeSet. empty
2322
+ }
2323
+ end in
2324
+ let { Variant_parts. cstr_arg_tys; cstr_arg_modalities; ret_args; params; _ }
2325
+ =
2326
+ List. fold_left
2327
+ (fun { Variant_parts. cstr_arg_tys;
2328
+ cstr_arg_modalities;
2329
+ ret_args;
2330
+ params;
2331
+ seen
2332
+ } cstr ->
2333
+ let cstr_arg_tys, cstr_arg_modalities =
2334
+ match cstr.cd_args with
2335
+ | Cstr_tuple args ->
2336
+ List. fold_left
2337
+ (fun (tys , ms ) arg ->
2338
+ arg.ca_type :: tys, arg.ca_modalities :: ms)
2339
+ (cstr_arg_tys, cstr_arg_modalities)
2340
+ args
2341
+ | Cstr_record lbls ->
2342
+ List. fold_left
2343
+ (fun (tys , ms ) lbl ->
2344
+ lbl.ld_type :: tys, lbl.ld_modalities :: ms)
2345
+ (cstr_arg_tys, cstr_arg_modalities)
2346
+ lbls
2347
+ in
2348
+ (* Note: we're using polymorphic variants here to fake labeled tuples; we
2349
+ can replace this with labeled tuples once we can build with a compiler
2350
+ that supports those. *)
2351
+ let `Args ret_args, `Params params, seen =
2352
+ match cstr.cd_res with
2353
+ | None when not has_gadt_constructors ->
2354
+ `Args ret_args, `Params params, seen
2355
+ | None ->
2356
+ ( `Args (decl_params @ ret_args),
2357
+ `Params (decl_params @ params),
2358
+ seen )
2359
+ | Some res -> (
2360
+ let existentials =
2361
+ ! constructor_unbound_type_vars_excluding_row_variables cstr
2362
+ |> Btype.TypeSet. to_seq
2363
+ |> Seq. map Types.Transient_expr. type_expr
2364
+ |> List. of_seq
2365
+ in
2366
+ let tof_kinds =
2367
+ List. map
2368
+ (fun ty ->
2369
+ match get_desc ty with
2370
+ | Tof_kind _ ->
2371
+ (* We shouldn't be able to hit this, but it's harmless and
2372
+ defensive to just keep these types the same. *)
2373
+ ty
2374
+ | Tvar { jkind; _ } | Tunivar { jkind; _ } ->
2375
+ Btype. newgenty (Tof_kind jkind)
2376
+ | _ ->
2377
+ Misc. fatal_error
2378
+ " constructor_unbound_type_vars must return Tvar or \
2379
+ Tunivar" )
2380
+ existentials
2381
+ in
2382
+ match Types. get_desc res with
2383
+ | Tconstr (_ , args , _ ) ->
2384
+ List. fold_left2
2385
+ (fun (`Args ret_args , `Params params , seen ) arg param ->
2386
+ if Btype.TypeSet. mem arg seen
2387
+ then `Args ret_args, `Params params, seen
2388
+ else
2389
+ match Types. get_desc arg, Types. get_desc param with
2390
+ | Tvar _ , Tvar _ ->
2391
+ ( `Args (arg :: ret_args),
2392
+ `Params (param :: params),
2393
+ Btype.TypeSet. add arg seen )
2394
+ | _ -> `Args ret_args, `Params params, seen)
2395
+ ( `Args (existentials @ ret_args),
2396
+ `Params (tof_kinds @ params),
2397
+ seen )
2398
+ args decl_params
2399
+ | _ -> Misc. fatal_error " cd_res must be Tconstr" )
2400
+ in
2401
+ { Variant_parts. cstr_arg_tys;
2402
+ cstr_arg_modalities;
2403
+ params;
2404
+ ret_args;
2405
+ seen
2406
+ })
2407
+ Variant_parts. empty cstrs
2408
+ in
2409
+ let cstr_arg_tys =
2410
+ if Misc.Stdlib.List. is_empty params
2411
+ then cstr_arg_tys
2412
+ else
2413
+ match
2414
+ type_apply ret_args
2415
+ (Btype. newgenty
2416
+ (Ttuple (List. map (fun ty -> None , ty) cstr_arg_tys)))
2417
+ params
2418
+ |> Types. get_desc
2419
+ with
2420
+ | Ttuple args -> List. map snd args
2421
+ | _ -> Misc. fatal_error " apply should have returned a tuple here"
2309
2422
in
2310
- List. fold_right add_cstr_args cstrs base
2423
+ List. fold_left2
2424
+ (fun jkind type_expr modality ->
2425
+ add_with_bounds ~modality ~type_expr jkind)
2426
+ base cstr_arg_tys cstr_arg_modalities
2311
2427
2312
2428
let for_boxed_tuple elts =
2313
2429
List. fold_right
0 commit comments