Skip to content

Commit 924d1e7

Browse files
authored
flambda-backend: clean up mutable() logic as commented (#2467)
* clean up mutable() logic as commented * address comment
1 parent 686aa9a commit 924d1e7

File tree

2 files changed

+59
-56
lines changed

2 files changed

+59
-56
lines changed

testsuite/tests/typing-modes/mutable.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,24 @@
88
yet. *)
99

1010
(* CR zqian: add test for mutable when mutable is decoupled from modalities. *)
11+
12+
(* CR mode-crossing: Uncomment the following examples once portability is added. *)
13+
14+
(* The [m0] in mutable should cross modes upon construction. *)
15+
(*
16+
type r =
17+
{ f : string -> string;
18+
mutable a : int }
19+
let r @ portable =
20+
{ f = fun x -> x;
21+
a = 42 } *)
22+
23+
(* The [m0] in mutable corresponds to the field type wrapped in modality; as a
24+
result, it enjoys mode crossing enabled by the modality. *)
25+
(*
26+
type r =
27+
{ f : string -> string;
28+
mutable g : string -> string @@ portable }
29+
let r @ portable =
30+
{ f = fun x -> x;
31+
g = fun x -> x } *)

typing/typecore.ml

Lines changed: 38 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,11 @@ let mode_default mode =
460460

461461
let mode_legacy = mode_default Value.legacy
462462

463+
let mode_modality modality expected_mode =
464+
expected_mode.mode
465+
|> modality_box_right modality
466+
|> mode_default
467+
463468
(* used when entering a function;
464469
mode is the mode of the function region *)
465470
let mode_return mode =
@@ -861,55 +866,28 @@ let apply_mode_annots ~loc ~env (m : Alloc.Const.Option.t) mode =
861866
| Ok () -> ()
862867
| Error e -> error (Right_le_left, e))
863868

864-
(** Takes the mutability and modalities on a record field, and [m] which is a
865-
left mode on the record being accessed, returns the left mode of the
866-
projected field. *)
867-
let project_field mutability modalities (m : (allowed * _) Value.t) =
868-
ignore mutability;
869-
modality_unbox_left modalities m
870-
871-
(** Takes [m0] which is the parameter on mutable, and [m] which is a right mode
872-
on the record being constructed, returns the right mode for the mutable
873-
field used for construction. *)
874-
let construct_mutable m0 m =
875-
let m0 =
876-
Alloc.Const.merge
877-
{comonadic = m0;
878-
monadic = Alloc.Monadic.Const.min}
879-
in
880-
let m0 = Const.alloc_as_value m0 in
881-
(* We require [join m0 ret <= m], which is equivalent to [m0 <= m] and [ret <=
882-
m]. *)
883-
(match Value.submode (Value.of_const m0) m with
884-
| Ok () -> ()
885-
| Error _ -> Misc.fatal_error
886-
"mutable defaults to Comonadic.legacy, \
887-
which is min, so this call cannot fail."
888-
);
889-
m |> Value.disallow_left
890-
891-
(** Takes [m0] which is the parameter on mutable, returns the right mode for the
892-
new value of the mutable field. *)
893-
let mutate_mutable m0 =
869+
(** Given the parameter [m0] on mutable, return the mode of future writes. *)
870+
let mutable_mode m0 =
894871
let m0 =
895872
Alloc.Const.merge
896873
{comonadic = m0;
897874
monadic = Alloc.Monadic.Const.min}
898875
in
899-
let m0 = Const.alloc_as_value m0 in
900-
m0 |> Value.of_const |> Value.disallow_left
876+
m0 |> Const.alloc_as_value |> Value.of_const
901877

902-
(** Takes the mutability and modalities on the field, and expected mode of the
903-
record (adjusted for allocation), returns the expected mode for the field.
904-
*)
905-
let construct_field mutability modalities (argument_mode : expected_mode) =
906-
let mode =
907-
match mutability with
908-
| Immutable -> argument_mode.mode
909-
| Mutable m0 -> construct_mutable m0 argument_mode.mode
910-
in
911-
let mode = modality_box_right modalities mode in
912-
mode_default mode
878+
(** Takes the mutability on a field, and expected mode of the record (adjusted
879+
for allocation), check that the construction would be allowed. *)
880+
let check_construct_mutability mutability (argument_mode : expected_mode) =
881+
match mutability with
882+
| Immutable -> ()
883+
| Mutable m0 ->
884+
let m0 = mutable_mode m0 in
885+
match Value.submode m0 argument_mode.mode with
886+
| Ok () -> ()
887+
| Error _ ->
888+
Misc.fatal_error
889+
"mutable defaults to Comonadic.legacy, \
890+
which is min, so this call cannot fail."
913891

914892
(* Typing of patterns *)
915893

@@ -2414,7 +2392,7 @@ and type_pat_aux
24142392
(* CR zqian: decouple mutable and global modality *)
24152393
if Types.is_mutable mutability then Global else Unrestricted
24162394
in
2417-
let alloc_mode = project_field mutability modalities alloc_mode.mode in
2395+
let alloc_mode = modality_unbox_left modalities alloc_mode.mode in
24182396
let alloc_mode = simple_pat_mode alloc_mode in
24192397
let pl = List.map (fun p -> type_pat ~alloc_mode tps Value p ty_elt) spl in
24202398
rvp {
@@ -2657,7 +2635,7 @@ and type_pat_aux
26572635
let args =
26582636
List.map2
26592637
(fun p (ty, gf) ->
2660-
let alloc_mode = project_field Immutable gf alloc_mode.mode in
2638+
let alloc_mode = modality_unbox_left gf alloc_mode.mode in
26612639
let alloc_mode = simple_pat_mode alloc_mode in
26622640
type_pat ~alloc_mode tps Value p ty)
26632641
sargs (List.combine ty_args_ty ty_args_gf)
@@ -2700,7 +2678,7 @@ and type_pat_aux
27002678
let type_label_pat (label_lid, label, sarg) =
27012679
let ty_arg =
27022680
solve_Ppat_record_field ~refine loc env label label_lid record_ty in
2703-
let mode = project_field label.lbl_mut label.lbl_global alloc_mode.mode in
2681+
let mode = modality_unbox_left label.lbl_global alloc_mode.mode in
27042682
let alloc_mode = simple_pat_mode mode in
27052683
(label_lid, label, type_pat tps Value ~alloc_mode sarg ty_arg)
27062684
in
@@ -5594,7 +5572,8 @@ and type_expect_
55945572
None, expected_mode
55955573
in
55965574
let type_label_exp ((_, label, _) as x) =
5597-
let argument_mode = construct_field label.lbl_mut label.lbl_global argument_mode in
5575+
check_construct_mutability label.lbl_mut argument_mode;
5576+
let argument_mode = mode_modality label.lbl_global argument_mode in
55985577
type_label_exp true env argument_mode loc ty_record x
55995578
in
56005579
let lbl_exp_list = List.map type_label_exp lbl_a_list in
@@ -5655,8 +5634,11 @@ and type_expect_
56555634
unify_exp_types loc env ty_arg1 ty_arg2;
56565635
with_explanation (fun () ->
56575636
unify_exp_types loc env (instance ty_expected) ty_res2);
5658-
let mode = project_field lbl.lbl_mut lbl.lbl_global mode in
5659-
let argument_mode = construct_field lbl.lbl_mut lbl.lbl_global argument_mode in
5637+
let mode = modality_unbox_left lbl.lbl_global mode in
5638+
check_construct_mutability lbl.lbl_mut argument_mode;
5639+
let argument_mode =
5640+
mode_modality lbl.lbl_global argument_mode
5641+
in
56605642
submode ~loc ~env mode argument_mode;
56615643
Kept (ty_arg1, lbl.lbl_mut,
56625644
unique_use ~loc ~env mode argument_mode.mode)
@@ -5702,7 +5684,7 @@ and type_expect_
57025684
ty_arg
57035685
end ~post:generalize_structure
57045686
in
5705-
let mode = project_field label.lbl_mut label.lbl_global rmode in
5687+
let mode = modality_unbox_left label.lbl_global rmode in
57065688
let boxing : texp_field_boxing =
57075689
let is_float_boxing =
57085690
match label.lbl_repres with
@@ -5745,10 +5727,9 @@ and type_expect_
57455727
let (label_loc, label, newval) =
57465728
match label.lbl_mut with
57475729
| Mutable m0 ->
5748-
let mode = mutate_mutable m0 in
5749-
let mode = modality_box_right label.lbl_global mode in
5750-
type_label_exp false env (mode_default mode) loc
5751-
ty_record (lid, label, snewval)
5730+
let mode = mutable_mode m0 |> mode_default in
5731+
let mode = mode_modality label.lbl_global mode in
5732+
type_label_exp false env mode loc ty_record (lid, label, snewval)
57525733
| Immutable ->
57535734
raise(Error(loc, env, Label_not_mutable lid.txt))
57545735
in
@@ -7816,7 +7797,7 @@ and type_construct env (expected_mode : expected_mode) loc lid sarg
78167797
let args =
78177798
List.map2
78187799
(fun e ((ty, gf),t0) ->
7819-
let argument_mode = construct_field Immutable gf argument_mode in
7800+
let argument_mode = mode_modality gf argument_mode in
78207801
type_argument ~recarg env argument_mode e ty t0)
78217802
sargs (List.combine ty_args ty_args0)
78227803
in
@@ -8702,7 +8683,8 @@ and type_generic_array
87028683
else
87038684
Predef.type_iarray, Global_flag.Unrestricted
87048685
in
8705-
let argument_mode = construct_field mutability modalities argument_mode in
8686+
check_construct_mutability mutability argument_mode;
8687+
let argument_mode = mode_modality modalities argument_mode in
87068688
let jkind, elt_sort = Jkind.of_new_sort_var ~why:Array_element in
87078689
let ty = newgenvar jkind in
87088690
let to_unify = type_ ty in

0 commit comments

Comments
 (0)