@@ -247,6 +247,30 @@ module Error = struct
247
247
(Lib_name. to_string lib)
248
248
]
249
249
;;
250
+
251
+ let expected_parameter ~loc ~name =
252
+ make
253
+ ~loc
254
+ [ Pp. textf " Expected %S to be a library parameter." (Lib_name. to_string name) ]
255
+ ;;
256
+
257
+ let duplicate_parameters ~loc name name' =
258
+ make
259
+ ~loc
260
+ [ Pp. textf
261
+ " Duplicate library parameters: %S and %S."
262
+ (Lib_name. to_string name)
263
+ (Lib_name. to_string name')
264
+ ]
265
+ ;;
266
+
267
+ let missing_parameter ~loc p =
268
+ let name = Lib_name. to_string (Lib_info. name p) in
269
+ make_resolve
270
+ ~loc
271
+ [ Pp. textf " Parameter %S is missing." name ]
272
+ ~hints: [ Pp. textf " Add (parameters %s)" name ]
273
+ ;;
250
274
end
251
275
252
276
(* Types *)
@@ -337,6 +361,7 @@ module T = struct
337
361
; ppx_runtime_deps : t list Resolve .t
338
362
; pps : t list Resolve .t
339
363
; resolved_selects : Resolved_select .t list Resolve .t
364
+ ; parameters : t list Resolve .t
340
365
; implements : t Resolve .t option
341
366
; project : Dune_project .t option
342
367
; (* these fields cannot be forced until the library is instantiated *)
@@ -430,6 +455,7 @@ let name t = t.name
430
455
let info t = t.info
431
456
let project t = t.project
432
457
let implements t = Option. map ~f: Memo. return t.implements
458
+ let parameters t = Resolve.Memo. lift t.parameters
433
459
let requires t = Memo. return t.requires
434
460
let re_exports t = Memo. return t.re_exports
435
461
let ppx_runtime_deps t = Memo. return t.ppx_runtime_deps
@@ -456,6 +482,21 @@ let main_module_name t =
456
482
| From _ -> assert false )
457
483
;;
458
484
485
+ module Parameterized = struct
486
+ let check ~loc ~parameters lib =
487
+ let open Resolve.O in
488
+ let * lib = lib in
489
+ let * required_parameters = lib.parameters in
490
+ let + () =
491
+ Resolve.List. iter required_parameters ~f: (function
492
+ | param when not (List. exists parameters ~f: (equal param)) ->
493
+ Error. missing_parameter ~loc param.info
494
+ | _ -> Resolve. return () )
495
+ in
496
+ lib
497
+ ;;
498
+ end
499
+
459
500
let wrapped t =
460
501
match Lib_info. wrapped t.info with
461
502
| None -> Resolve.Memo. return None
@@ -861,6 +902,7 @@ module rec Resolve_names : sig
861
902
: db
862
903
-> Lib_dep. t list
863
904
-> private_deps:private_deps
905
+ -> parameters:t list
864
906
-> pps:(Loc. t * Lib_name. t) list
865
907
-> dune_version:Dune_lang.Syntax.Version. t option
866
908
-> Resolved. t Memo. t
@@ -898,6 +940,32 @@ end = struct
898
940
>> | Package.Name.Map. of_list_exn)
899
941
;;
900
942
943
+ let resolve_parameters db ~private_deps info =
944
+ let open Resolve.Memo.O in
945
+ let * parameters =
946
+ Resolve.Memo.List. filter_map (Lib_info. parameters info) ~f: (fun (loc , name ) ->
947
+ let * lib = Resolve.Memo. lift_memo (resolve_dep db ~private_deps (loc, name)) in
948
+ match lib with
949
+ | None -> Resolve.Memo. return None
950
+ | Some lib ->
951
+ let * lib = Resolve.Memo. lift lib in
952
+ (match Lib_info. kind lib.info with
953
+ | Parameter -> Resolve.Memo. return (Some (loc, name, lib))
954
+ | _ -> Error. expected_parameter ~loc ~name ))
955
+ in
956
+ let parameters =
957
+ List. stable_sort parameters ~compare: (fun (_ , _ , a ) (_ , _ , b ) -> compare a b)
958
+ in
959
+ let rec check_duplicates = function
960
+ | [] | [ _ ] -> Resolve.Memo. return ()
961
+ | (_ , name , p ) :: (loc , name' , p' ) :: _ when p = p' ->
962
+ Error. duplicate_parameters ~loc name name'
963
+ | _ :: ps -> check_duplicates ps
964
+ in
965
+ let + () = check_duplicates parameters in
966
+ List. map parameters ~f: (fun (_ , _ , param ) -> param)
967
+ ;;
968
+
901
969
let instantiate_impl db (name , info , hidden ) =
902
970
let db = Lazy. force db in
903
971
let open Memo.O in
@@ -925,6 +993,7 @@ end = struct
925
993
in this position."
926
994
]
927
995
in
996
+ let * parameters = resolve_parameters db ~private_deps info in
928
997
let * resolved =
929
998
let open Resolve.Memo.O in
930
999
let * pps =
@@ -935,9 +1004,10 @@ end = struct
935
1004
|> Instrumentation. with_instrumentation ~instrumentation_backend
936
1005
>> | Preprocess.Per_module. pps
937
1006
in
1007
+ let * parameters = Resolve.Memo. lift parameters in
938
1008
let dune_version = Lib_info. dune_version info in
939
1009
Lib_info. requires info
940
- |> resolve_deps_and_add_runtime_deps db ~private_deps ~dune_version ~pps
1010
+ |> resolve_deps_and_add_runtime_deps db ~private_deps ~parameters ~ dune_version ~pps
941
1011
|> Memo. map ~f: Resolve. return
942
1012
in
943
1013
let * implements =
@@ -1067,6 +1137,7 @@ end = struct
1067
1137
; resolved_selects
1068
1138
; re_exports
1069
1139
; implements
1140
+ ; parameters
1070
1141
; default_implementation
1071
1142
; project
1072
1143
; sub_systems =
@@ -1398,17 +1469,23 @@ end = struct
1398
1469
res, { Resolved_select. src_fn; dst_fn = result_fn }
1399
1470
;;
1400
1471
1401
- let resolve_complex_deps db deps ~private_deps : Resolved. deps Memo. t =
1472
+ let resolve_complex_deps db deps ~private_deps ~parameters : Resolved. deps Memo. t =
1473
+ let open Memo.O in
1474
+ let resolve_parameterized_dep (loc , lib ) =
1475
+ resolve_dep db (loc, lib) ~private_deps
1476
+ >> | function
1477
+ | None -> None
1478
+ | Some dep -> Some (Parameterized. check ~loc ~parameters dep)
1479
+ in
1402
1480
Memo.List. fold_left ~init: Resolved.Builder. empty deps ~f: (fun acc (dep : Lib_dep.t ) ->
1403
- let open Memo.O in
1404
1481
match dep with
1405
1482
| Re_export lib ->
1406
- resolve_dep db lib ~private_deps
1483
+ resolve_parameterized_dep lib
1407
1484
>> | (function
1408
1485
| None -> acc
1409
1486
| Some lib -> Resolved.Builder. add_re_exports acc lib)
1410
1487
| Direct lib ->
1411
- resolve_dep db lib ~private_deps
1488
+ resolve_parameterized_dep lib
1412
1489
>> | (function
1413
1490
| None -> acc
1414
1491
| Some lib -> Resolved.Builder. add_resolved acc lib)
@@ -1475,6 +1552,7 @@ end = struct
1475
1552
db
1476
1553
{ Resolved. resolved; selects; re_exports }
1477
1554
~private_deps
1555
+ ~parameters
1478
1556
~pps
1479
1557
~dune_version
1480
1558
: Resolved. t Memo. t
@@ -1485,15 +1563,22 @@ end = struct
1485
1563
let open Resolve.Memo.O in
1486
1564
let * resolved = Memo. return resolved in
1487
1565
let * runtime_deps = runtime_deps in
1488
- re_exports_closure (resolved @ runtime_deps)
1566
+ re_exports_closure (resolved @ runtime_deps @ parameters )
1489
1567
and + pps = pps in
1490
1568
{ Resolved. requires; pps; selects; re_exports }
1491
1569
;;
1492
1570
1493
- let resolve_deps_and_add_runtime_deps db deps ~private_deps ~pps ~dune_version =
1571
+ let resolve_deps_and_add_runtime_deps
1572
+ db
1573
+ deps
1574
+ ~private_deps
1575
+ ~parameters
1576
+ ~pps
1577
+ ~dune_version
1578
+ =
1494
1579
let open Memo.O in
1495
- resolve_complex_deps db ~private_deps deps
1496
- >> = add_pp_runtime_deps db ~private_deps ~dune_version ~pps
1580
+ resolve_complex_deps db ~private_deps ~parameters deps
1581
+ >> = add_pp_runtime_deps db ~private_deps ~parameters ~ dune_version ~pps
1497
1582
;;
1498
1583
1499
1584
(* Compute transitive closure of libraries to figure which ones will trigger
@@ -2058,6 +2143,7 @@ module DB = struct
2058
2143
t
2059
2144
deps
2060
2145
~pps
2146
+ ~parameters: []
2061
2147
~private_deps: Allow_all
2062
2148
~dune_version: (Some dune_version))
2063
2149
in
@@ -2193,6 +2279,11 @@ let to_dune_lib
2193
2279
use_public_name
2194
2280
~info_field: (Lib_info. implements info)
2195
2281
~lib_field: (Option. map ~f: Memo. return lib.implements)
2282
+ and + parameters =
2283
+ let + lib_parameters = Resolve.Memo. lift lib.parameters in
2284
+ List. map
2285
+ (List. combine (Lib_info. parameters info) lib_parameters)
2286
+ ~f: (fun ((loc , _ ), param ) -> loc, mangled_name param)
2196
2287
and + default_implementation =
2197
2288
use_public_name
2198
2289
~info_field: (Lib_info. default_implementation info)
@@ -2223,6 +2314,7 @@ let to_dune_lib
2223
2314
~foreign_objects
2224
2315
~obj_dir
2225
2316
~implements
2317
+ ~parameters
2226
2318
~default_implementation
2227
2319
~sub_systems
2228
2320
~modules
0 commit comments