Skip to content

Commit db22c20

Browse files
author
Nathan Rebours
committed
Add support for bivariant params in module types
Signed-off-by: Nathan Rebours <nathan.rebours@ocamlpro.com>
1 parent 8375eb9 commit db22c20

File tree

5 files changed

+116
-12
lines changed

5 files changed

+116
-12
lines changed

astlib/encoding_504.ml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Ext_name = struct
77
let bivariant_param = "ppxlib.migration.bivariant_param_5_4"
88
let bivariant_pstr = "ppxlib.migration.bivariant_str_item_5_4"
99
let bivariant_psig = "ppxlib.migration.bivariant_sig_item_5_4"
10+
let bivariant_pmty_with = "ppxlib.migration.bivariant_pmty_with_5_4"
1011
end
1112

1213
let invalid_encoding ~loc name =
@@ -460,6 +461,50 @@ module To_503 = struct
460461
] ->
461462
x
462463
| _ -> invalid_encoding ~loc "bivariant signature_item"
464+
465+
let encode_bivariant_pmty_with ~loc mty constraints =
466+
let loc = { loc with Location.loc_ghost = true } in
467+
let pmd_type =
468+
{
469+
pmty_loc = loc;
470+
pmty_attributes = [];
471+
pmty_desc = Pmty_with (mty, constraints);
472+
}
473+
in
474+
let psig_desc =
475+
Psig_module
476+
{
477+
pmd_name = { txt = None; loc };
478+
pmd_type;
479+
pmd_attributes = [];
480+
pmd_loc = loc;
481+
}
482+
in
483+
let ext =
484+
( { txt = Ext_name.bivariant_pmty_with; loc },
485+
PSig [ { psig_loc = loc; psig_desc } ] )
486+
in
487+
Pmty_extension ext
488+
489+
let decode_bivariant_pmty_with ~loc payload =
490+
match payload with
491+
| PSig
492+
[
493+
{
494+
psig_desc =
495+
Psig_module
496+
{
497+
pmd_name = { txt = None; _ };
498+
pmd_attributes = [];
499+
pmd_type =
500+
{ pmty_attributes = []; pmty_desc = Pmty_with _ as x; _ };
501+
_;
502+
};
503+
_;
504+
};
505+
] ->
506+
x
507+
| _ -> invalid_encoding ~loc "bivariant pmty_with"
463508
end
464509

465510
module To_502 = struct

astlib/encoding_504.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Ext_name : sig
44
val ppat_labeled_tuple : string
55
val bivariant_pstr : string
66
val bivariant_psig : string
7+
val bivariant_pmty_with : string
78
end
89

910
module To_503 : sig
@@ -64,8 +65,12 @@ module To_503 : sig
6465
val encode_bivariant_psig_class_type :
6566
loc:Location.t -> class_type_declaration list -> signature_item_desc
6667

68+
val encode_bivariant_pmty_with :
69+
loc:Location.t -> module_type -> with_constraint list -> module_type_desc
70+
6771
val decode_bivariant_pstr : loc:Location.t -> payload -> structure_item_desc
6872
val decode_bivariant_psig : loc:Location.t -> payload -> signature_item_desc
73+
val decode_bivariant_pmty_with : loc:Location.t -> payload -> module_type_desc
6974
end
7075

7176
module To_502 : sig

astlib/migrate_503_504.ml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -775,13 +775,14 @@ and copy_module_type :
775775
Ast_503.Parsetree.pmty_loc;
776776
Ast_503.Parsetree.pmty_attributes;
777777
} ->
778+
let loc = copy_location pmty_loc in
778779
{
779-
Ast_504.Parsetree.pmty_desc = copy_module_type_desc pmty_desc;
780-
Ast_504.Parsetree.pmty_loc = copy_location pmty_loc;
780+
Ast_504.Parsetree.pmty_desc = copy_module_type_desc_with_loc ~loc pmty_desc;
781+
Ast_504.Parsetree.pmty_loc = loc;
781782
Ast_504.Parsetree.pmty_attributes = copy_attributes pmty_attributes;
782783
}
783784

784-
and copy_module_type_desc :
785+
and copy_module_type_desc_with_loc ~loc :
785786
Ast_503.Parsetree.module_type_desc -> Ast_504.Parsetree.module_type_desc =
786787
function
787788
| Ast_503.Parsetree.Pmty_ident x0 ->
@@ -796,11 +797,20 @@ and copy_module_type_desc :
796797
(copy_module_type x0, List.map copy_with_constraint x1)
797798
| Ast_503.Parsetree.Pmty_typeof x0 ->
798799
Ast_504.Parsetree.Pmty_typeof (copy_module_expr x0)
800+
| Ast_503.Parsetree.Pmty_extension ({ txt; _ }, payload)
801+
when String.equal txt Encoding_504.Ext_name.bivariant_pmty_with ->
802+
let pmty_desc =
803+
Encoding_504.To_503.decode_bivariant_pmty_with ~loc payload
804+
in
805+
copy_module_type_desc_with_loc ~loc pmty_desc
799806
| Ast_503.Parsetree.Pmty_extension x0 ->
800807
Ast_504.Parsetree.Pmty_extension (copy_extension x0)
801808
| Ast_503.Parsetree.Pmty_alias x0 ->
802809
Ast_504.Parsetree.Pmty_alias (copy_loc (copy_Longident_t ~loc:x0.loc) x0)
803810

811+
and copy_module_type_desc pmty =
812+
copy_module_type_desc_with_loc ~loc:Location.none pmty
813+
804814
and copy_with_constraint :
805815
Ast_503.Parsetree.with_constraint -> Ast_504.Parsetree.with_constraint =
806816
function

astlib/migrate_504_503.ml

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Bivariant_param = struct
1111
| Class_decl of Ast_503.Parsetree.class_declaration
1212
| Class_desc of Ast_503.Parsetree.class_description
1313
| Class_type_decl of Ast_503.Parsetree.class_type_declaration
14+
| With_constraint of Ast_503.Parsetree.with_constraint
1415

1516
(* TODO: register exception printers to display those as location errors
1617
pointing to the right AST element and displaying a clear migration error
@@ -790,13 +791,14 @@ and copy_module_type :
790791
Ast_504.Parsetree.pmty_loc;
791792
Ast_504.Parsetree.pmty_attributes;
792793
} ->
794+
let loc = copy_location pmty_loc in
793795
{
794-
Ast_503.Parsetree.pmty_desc = copy_module_type_desc pmty_desc;
795-
Ast_503.Parsetree.pmty_loc = copy_location pmty_loc;
796+
Ast_503.Parsetree.pmty_desc = copy_module_type_desc_with_loc ~loc pmty_desc;
797+
Ast_503.Parsetree.pmty_loc = loc;
796798
Ast_503.Parsetree.pmty_attributes = copy_attributes pmty_attributes;
797799
}
798800

799-
and copy_module_type_desc :
801+
and copy_module_type_desc_with_loc ~loc :
800802
Ast_504.Parsetree.module_type_desc -> Ast_503.Parsetree.module_type_desc =
801803
function
802804
| Ast_504.Parsetree.Pmty_ident x0 ->
@@ -807,21 +809,46 @@ and copy_module_type_desc :
807809
Ast_503.Parsetree.Pmty_functor
808810
(copy_functor_parameter x0, copy_module_type x1)
809811
| Ast_504.Parsetree.Pmty_with (x0, x1) ->
810-
Ast_503.Parsetree.Pmty_with
811-
(copy_module_type x0, List.map copy_with_constraint x1)
812+
let mty = copy_module_type x0 in
813+
let contains_bivariant = ref false in
814+
let constraints =
815+
List.map
816+
(fun c ->
817+
match copy_with_constraint c with
818+
| c' -> c'
819+
| exception Bivariant_param.With_constraint c' ->
820+
contains_bivariant := true;
821+
c')
822+
x1
823+
in
824+
if !contains_bivariant then
825+
Encoding_504.To_503.encode_bivariant_pmty_with ~loc mty constraints
826+
else
827+
Ast_503.Parsetree.Pmty_with
828+
(copy_module_type x0, List.map copy_with_constraint x1)
812829
| Ast_504.Parsetree.Pmty_typeof x0 ->
813830
Ast_503.Parsetree.Pmty_typeof (copy_module_expr x0)
814831
| Ast_504.Parsetree.Pmty_extension x0 ->
815832
Ast_503.Parsetree.Pmty_extension (copy_extension x0)
816833
| Ast_504.Parsetree.Pmty_alias x0 ->
817834
Ast_503.Parsetree.Pmty_alias (copy_loc copy_Longident_t x0)
818835

836+
and copy_module_type_desc pmty =
837+
copy_module_type_desc_with_loc ~loc:Location.none pmty
838+
819839
and copy_with_constraint :
820840
Ast_504.Parsetree.with_constraint -> Ast_503.Parsetree.with_constraint =
821841
function
822842
| Ast_504.Parsetree.Pwith_type (x0, x1) ->
823-
Ast_503.Parsetree.Pwith_type
824-
(copy_loc copy_Longident_t x0, copy_type_declaration x1)
843+
let lident_loc = copy_loc copy_Longident_t x0 in
844+
let td, contains_bivariant =
845+
match copy_type_declaration x1 with
846+
| td -> (td, false)
847+
| exception Bivariant_param.Type_decl td -> (td, true)
848+
in
849+
let res = Ast_503.Parsetree.Pwith_type (lident_loc, td) in
850+
if contains_bivariant then raise (Bivariant_param.With_constraint res)
851+
else res
825852
| Ast_504.Parsetree.Pwith_module (x0, x1) ->
826853
Ast_503.Parsetree.Pwith_module
827854
(copy_loc copy_Longident_t x0, copy_loc copy_Longident_t x1)
@@ -832,8 +859,15 @@ and copy_with_constraint :
832859
Ast_503.Parsetree.Pwith_modtypesubst
833860
(copy_loc copy_Longident_t x0, copy_module_type x1)
834861
| Ast_504.Parsetree.Pwith_typesubst (x0, x1) ->
835-
Ast_503.Parsetree.Pwith_typesubst
836-
(copy_loc copy_Longident_t x0, copy_type_declaration x1)
862+
let lident_loc = copy_loc copy_Longident_t x0 in
863+
let td, contains_bivariant =
864+
match copy_type_declaration x1 with
865+
| td -> (td, false)
866+
| exception Bivariant_param.Type_decl td -> (td, true)
867+
in
868+
let res = Ast_503.Parsetree.Pwith_typesubst (lident_loc, td) in
869+
if contains_bivariant then raise (Bivariant_param.With_constraint res)
870+
else res
837871
| Ast_504.Parsetree.Pwith_modsubst (x0, x1) ->
838872
Ast_503.Parsetree.Pwith_modsubst
839873
(copy_loc copy_Longident_t x0, copy_loc copy_Longident_t x1)

test/encoding/504/migrations/run.t

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ Bivariant are also correctly handled in a signature context:
7575
> type +-'a extensible += B
7676
> class [+-'a] c : object end
7777
> class type [+-'a] d = object end
78+
> module M : S with type +-'a t = 'a u
79+
> module M2 : S with type +-'a t := 'a u
7880
> EOF
7981

8082
$ ./id_driver.exe bivariant.mli
@@ -84,6 +86,12 @@ Bivariant are also correctly handled in a signature context:
8486
| B ]
8587
[%%ppxlib.migration.bivariant_sig_item_5_4 : class ['a] c : object end]
8688
[%%ppxlib.migration.bivariant_sig_item_5_4 : class type ['a] d = object end]
89+
module M :
90+
[%ppxlib.migration.bivariant_pmty_with_5_4 :
91+
module _ : S with type 'a t = 'a u]
92+
module M2 :
93+
[%ppxlib.migration.bivariant_pmty_with_5_4 :
94+
module _ : S with type 'a t := 'a u]
8795

8896
$ ./id_driver.exe bivariant.mli --use-compiler-pp
8997
type +-'a t
@@ -92,3 +100,5 @@ Bivariant are also correctly handled in a signature context:
92100
| B
93101
class [+-'a] c : object end
94102
class type [+-'a] d = object end
103+
module M : S with type +-'a t = 'a u
104+
module M2 : S with type +-'a t := 'a u

0 commit comments

Comments
 (0)