@@ -72,6 +72,7 @@ type ctx = {
72
72
kinds : (kind_aux * P .l ) KBindings .t ;
73
73
function_type_variables : (kind_aux * P .l ) KBindings .t Bindings .t ;
74
74
type_constructors : type_constructor Bindings .t ;
75
+ outcome_variables : kind_aux KBindings .t ;
75
76
scattereds : (P .typquant * ctx ) Bindings .t ;
76
77
fixities : (prec * int ) Bindings .t ;
77
78
internal_files : StringSet .t ;
@@ -111,6 +112,10 @@ let merge_ctx l ctx1 ctx2 =
111
112
)
112
113
)
113
114
ctx1.function_type_variables ctx2.function_type_variables;
115
+ outcome_variables =
116
+ KBindings. merge
117
+ (compatible ( = ) (fun v -> " Outcome definitions have different kinds for type variable " ^ string_of_kid v))
118
+ ctx1.outcome_variables ctx2.outcome_variables;
114
119
type_constructors =
115
120
Bindings. merge
116
121
(compatible ( = ) (fun id -> " Different definitions for type constructor " ^ string_of_id id ^ " found" ))
@@ -788,6 +793,12 @@ module KindInference = struct
788
793
in
789
794
return (typq, typ, kind)
790
795
796
+ let check_outcome ctx typq (P. ATyp_aux (_ , l ) as typ ) kopts =
797
+ let * kopts = mapM (fun kopt -> fmap List. hd (add_vars [kopt])) kopts in
798
+ let * typq = infer_typquant ctx typq in
799
+ let * typ = check ctx typ (Kind (K_type , l)) in
800
+ return (typq, typ, kopts)
801
+
791
802
let initial_env = { sets = [] ; next_unknown = 0 ; vars = [] }
792
803
end
793
804
@@ -1457,19 +1468,51 @@ let to_ast_spec ctx (P.VS_aux (P.VS_val_spec (ts, id, ext), l)) =
1457
1468
let ctx = { ctx with function_type_variables = Bindings. add id ts_ctx.kinds ctx.function_type_variables } in
1458
1469
(VS_aux (VS_val_spec (typschm, id, ext), (l, empty_uannot)), ctx)
1459
1470
1460
- let to_ast_outcome ctx (ev : P.outcome_spec ) : outcome_spec ctx_out =
1471
+ let to_ast_outcome ctx (ev : P.outcome_spec ) : outcome_spec * ctx * ctx =
1461
1472
match ev with
1462
- | P. OV_aux (P. OV_outcome (id , typschm , outcome_args ), l ) ->
1473
+ | P. OV_aux (P. OV_outcome (id , P. TypSchm_aux (P. TypSchm_ts (typq , typ ), ts_l ), outcome_args ), l ) ->
1474
+ let open KindInference in
1475
+ let (typq, typ, outcome_args), kenv = check_outcome ctx typq typ outcome_args initial_env in
1463
1476
let outcome_args, inner_ctx =
1464
1477
List. fold_left
1465
1478
(fun (args , ctx ) arg ->
1466
- let (arg, _, ctx), _ = to_ast_kopts ctx arg in
1479
+ let (arg, _, ctx), _ = ConvertType. to_ast_kopts kenv ctx arg in
1467
1480
(arg @ args, ctx)
1468
1481
)
1469
1482
([] , ctx) outcome_args
1470
1483
in
1471
- let typschm, _ = to_ast_typschm inner_ctx typschm in
1472
- (OV_aux (OV_outcome (to_ast_id ctx id, typschm, List. rev outcome_args), l), inner_ctx)
1484
+ let typq, ts_ctx = ConvertType. to_ast_typquant kenv inner_ctx typq in
1485
+ let typ = ConvertType. to_ast_typ kenv ts_ctx typ in
1486
+ let ctx =
1487
+ List. fold_left
1488
+ (fun ctx kopt ->
1489
+ let v = kopt_kid kopt in
1490
+ let k = unaux_kind (kopt_kind kopt) in
1491
+ {
1492
+ ctx with
1493
+ outcome_variables =
1494
+ KBindings. update v
1495
+ (function
1496
+ | None -> Some k
1497
+ | Some k' when k = k' -> Some k'
1498
+ | Some k' ->
1499
+ let v', _ =
1500
+ List. find (fun (v' , _ ) -> Kid. compare v v' = 0 ) (KBindings. bindings ctx.outcome_variables)
1501
+ in
1502
+ Printf. sprintf " Outcome variable %s has kind %s here, but previously used with kind %s"
1503
+ (string_of_kid v) (string_of_kind_aux k) (string_of_kind_aux k')
1504
+ |> Reporting. err_typ (Hint (" previous use here" , kid_loc v', kid_loc v))
1505
+ |> raise
1506
+ )
1507
+ ctx.outcome_variables;
1508
+ }
1509
+ )
1510
+ ctx outcome_args
1511
+ in
1512
+ ( OV_aux (OV_outcome (to_ast_id ctx id, TypSchm_aux (TypSchm_ts (typq, typ), ts_l), List. rev outcome_args), l),
1513
+ inner_ctx,
1514
+ ctx
1515
+ )
1473
1516
1474
1517
let rec to_ast_range ctx (P. BF_aux (r , l )) =
1475
1518
(* TODO add check that ranges are sensible for some definition of sensible *)
@@ -2017,7 +2060,7 @@ let rec to_ast_def doc attrs vis ctx (P.DEF_aux (def, l)) : untyped_def list ctx
2017
2060
let vs, ctx = to_ast_spec ctx val_spec in
2018
2061
([DEF_aux (DEF_val vs, annot)], ctx)
2019
2062
| P. DEF_outcome (outcome_spec , defs ) ->
2020
- let outcome_spec, inner_ctx = to_ast_outcome ctx outcome_spec in
2063
+ let outcome_spec, inner_ctx, ctx = to_ast_outcome ctx outcome_spec in
2021
2064
let defs, _ =
2022
2065
List. fold_left
2023
2066
(fun (defs , ctx ) def ->
@@ -2150,6 +2193,7 @@ let initial_ctx =
2150
2193
(" float128" , ([] , P. K_type ));
2151
2194
(" float_rounding_mode" , ([] , P. K_type ));
2152
2195
];
2196
+ outcome_variables = KBindings. empty;
2153
2197
function_type_variables = Bindings. empty;
2154
2198
kinds = KBindings. empty;
2155
2199
scattereds = Bindings. empty;
0 commit comments