@@ -424,7 +424,42 @@ let generalize ~lvl ty =
424
424
Caml.Format. printf " GENR lvl:%i %s@." lvl (Ty_sch. show ty_sch);
425
425
ty_sch
426
426
427
- let subsumes constraints =
427
+ let rec promote ~lvl (ty : ty ) =
428
+ match ty with
429
+ | Ty_const _ -> ty
430
+ | Ty_var v -> (
431
+ match Var. ty v with
432
+ | None -> if Var. lvl v > lvl then Ty_top else ty
433
+ | Some ty -> promote ~lvl ty)
434
+ | Ty_app (ty , args ) ->
435
+ Ty_app (promote ~lvl ty, List. map args ~f: (promote ~lvl ))
436
+ | Ty_nullable ty -> Ty_nullable (promote ~lvl ty)
437
+ | Ty_arr (args , ty ) -> Ty_arr (List. map args ~f: (demote ~lvl ), promote ~lvl ty)
438
+ | Ty_record row -> Ty_record (promote ~lvl row)
439
+ | Ty_row_empty -> ty
440
+ | Ty_row_extend ((name , ty ), row ) ->
441
+ Ty_row_extend ((name, promote ~lvl ty), promote ~lvl row)
442
+ | Ty_bot -> ty
443
+ | Ty_top -> ty
444
+
445
+ and demote ~lvl (ty : ty ) =
446
+ match ty with
447
+ | Ty_const _ -> ty
448
+ | Ty_var v -> (
449
+ match Var. ty v with
450
+ | None -> if Var. lvl v > lvl then Ty_bot else ty
451
+ | Some ty -> demote ~lvl ty)
452
+ | Ty_app (ty , args ) -> Ty_app (promote ~lvl ty, List. map args ~f: (demote ~lvl ))
453
+ | Ty_nullable ty -> Ty_nullable (demote ~lvl ty)
454
+ | Ty_arr (args , ty ) -> Ty_arr (List. map args ~f: (promote ~lvl ), demote ~lvl ty)
455
+ | Ty_record row -> Ty_record (demote ~lvl row)
456
+ | Ty_row_empty -> ty
457
+ | Ty_row_extend ((name , ty ), row ) ->
458
+ Ty_row_extend ((name, demote ~lvl ty), demote ~lvl row)
459
+ | Ty_bot -> ty
460
+ | Ty_top -> ty
461
+
462
+ let subsumes ~lvl constraints =
428
463
let exception Row_rewrite_error in
429
464
let rec aux ~super_ty ~sub_ty =
430
465
if Debug. log_solve then
@@ -466,18 +501,18 @@ let subsumes constraints =
466
501
~merge_upper: (Constraint_set. greatest_lower_bound' constraints)
467
502
sub_v super_v
468
503
| Some sub_ty , None ->
469
- Constraint_set. add constraints super_v (sub_ty, Ty_top )
504
+ Constraint_set. add constraints super_v (promote ~lvl sub_ty, Ty_top )
470
505
| None , Some super_ty ->
471
- Constraint_set. add constraints sub_v (Ty_bot , super_ty)
506
+ Constraint_set. add constraints sub_v (Ty_bot , demote ~lvl super_ty)
472
507
| Some sub_ty , Some super_ty -> aux ~sub_ty ~super_ty )
473
508
| Ty_var sub_v , super_ty -> (
474
509
match Var. ty sub_v with
475
510
| Some sub_ty -> aux ~super_ty ~sub_ty
476
- | None -> Constraint_set. add constraints sub_v (Ty_bot , super_ty))
511
+ | None -> Constraint_set. add constraints sub_v (Ty_bot , demote ~lvl super_ty))
477
512
| sub_ty , Ty_var super_v -> (
478
513
match Var. ty super_v with
479
514
| Some super_ty -> aux ~super_ty ~sub_ty
480
- | None -> Constraint_set. add constraints super_v (sub_ty, Ty_top ))
515
+ | None -> Constraint_set. add constraints super_v (promote ~lvl sub_ty, Ty_top ))
481
516
| _ , Ty_top -> ()
482
517
| Ty_bot , _ -> ()
483
518
| _ -> Type_error. raise_not_a_subtype ~sub_ty ~super_ty
@@ -673,7 +708,7 @@ and synth' ~ctx expr =
673
708
in
674
709
let ty = Ty_record row in
675
710
let ty', expr = synth ~ctx expr in
676
- subsumes constraints ~sub_ty: ty ~super_ty: ty';
711
+ subsumes ~lvl: ctx.lvl constraints ~sub_ty: ty ~super_ty: ty';
677
712
Constraint_set. solve constraints;
678
713
(ty, E_record_update (expr, List. rev fields))
679
714
| E_lit (Lit_string _ ) -> (Ty_const " string" , expr)
@@ -719,7 +754,7 @@ and check' ~ctx ~constraints expr ty =
719
754
List. fold2 args args_ty ~init: (env, [] )
720
755
~f: (fun (env , args ) (name , ty' ) ty ->
721
756
Option. iter ty' ~f: (fun ty' ->
722
- subsumes constraints ~sub_ty: ty ~super_ty: ty');
757
+ subsumes ~lvl: ctx.lvl constraints ~sub_ty: ty ~super_ty: ty');
723
758
let env = Env. add_val env name ([] , ty) in
724
759
(env, (name, Some ty) :: args))
725
760
with
@@ -742,16 +777,16 @@ and check' ~ctx ~constraints expr ty =
742
777
let () =
743
778
match
744
779
List. iter2 args_tys' args_tys ~f: (fun ty' ty ->
745
- subsumes constraints ~sub_ty: ty ~super_ty: ty')
780
+ subsumes ~lvl: ctx.lvl constraints ~sub_ty: ty ~super_ty: ty')
746
781
with
747
782
| Unequal_lengths -> Type_error. raise Error_arity_mismatch
748
783
| Ok () -> ()
749
784
in
750
- subsumes constraints ~sub_ty: ty' ~super_ty: ty;
785
+ subsumes ~lvl: ctx.lvl constraints ~sub_ty: ty' ~super_ty: ty;
751
786
E_app (f, args)
752
787
| expr ->
753
788
let ty', expr = synth ~ctx expr in
754
- subsumes constraints ~sub_ty: ty' ~super_ty: ty;
789
+ subsumes ~lvl: ctx.lvl constraints ~sub_ty: ty' ~super_ty: ty;
755
790
expr
756
791
757
792
and check ~ctx expr ty =
0 commit comments