Skip to content

Commit 199263e

Browse files
committed
reorganize crossing logic
1 parent 400c3cb commit 199263e

File tree

4 files changed

+94
-89
lines changed

4 files changed

+94
-89
lines changed

typing/ctype.ml

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4977,31 +4977,38 @@ let relevant_pairs pairs v =
49774977
| Contravariant -> pairs.contravariant_pairs
49784978
| Bivariant -> pairs.bivariant_pairs
49794979

4980-
(* This is very similar to Typecore.mode_cross_left_value. Any bugs here
4981-
are likely bugs there, too. *)
4982-
let mode_cross_left_alloc env ty mode =
4983-
if not (is_principal ty) then Alloc.disallow_right mode else begin
4980+
let crossing_of_jkind env jkind =
4981+
let jkind_of_type = type_jkind_purely_if_principal env in
4982+
Jkind.get_mode_crossing ~jkind_of_type jkind
4983+
4984+
let crossing_of_ty env ?modalities ty =
4985+
if not (is_principal ty)
4986+
then Crossing.top
4987+
else
49844988
let jkind = type_jkind_purely env ty in
4985-
let jkind_of_type = type_jkind_purely_if_principal env in
4986-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
4987-
mode
4988-
|> Alloc.disallow_right
4989-
|> Crossing.apply_left_alloc crossing
4990-
end
4989+
let crossing = crossing_of_jkind env jkind in
4990+
match modalities with
4991+
| None -> crossing
4992+
| Some m -> Crossing.modality m crossing
49914993

4992-
(* This is very similar to Typecore.expect_mode_cross. Any bugs here
4993-
are likely bugs there, too. *)
4994-
let mode_cross_right env ty mode =
4995-
if not (is_principal ty) then Alloc.disallow_left mode else
4996-
let jkind = type_jkind_purely env ty in
4997-
let jkind_of_type = type_jkind_purely_if_principal env in
4998-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
4999-
mode
5000-
|> Alloc.disallow_left
5001-
|> Crossing.apply_right_alloc crossing
4994+
let cross_left env ?modalities ty mode =
4995+
let crossing = crossing_of_ty env ?modalities ty in
4996+
mode |> Value.disallow_right |> Crossing.apply_left crossing
4997+
4998+
let cross_right env ?modalities ty mode =
4999+
let crossing = crossing_of_ty env ?modalities ty in
5000+
mode |> Value.disallow_left |> Crossing.apply_right crossing
5001+
5002+
let cross_left_alloc env ?modalities ty mode =
5003+
let crossing = crossing_of_ty env ?modalities ty in
5004+
mode |> Alloc.disallow_right |> Crossing.apply_left_alloc crossing
5005+
5006+
let cross_right_alloc env ?modalities ty mode =
5007+
let crossing = crossing_of_ty env ?modalities ty in
5008+
mode |> Alloc.disallow_left |> Crossing.apply_right_alloc crossing
50025009

50035010
let submode_with_cross env ~is_ret ty l r =
5004-
let r' = mode_cross_right env ty r in
5011+
let r' = cross_right_alloc env ty r in
50055012
let r' =
50065013
if is_ret then
50075014
(* the locality axis of the return mode cannot cross modes, because a
@@ -6127,10 +6134,10 @@ let rec build_subtype env (visited : transient_expr list)
61276134
let t1 = if posi then t1 else t1' in
61286135
let posi_arg = not posi in
61296136
if posi_arg then begin
6130-
let a = mode_cross_right env t1 a in
6137+
let a = cross_right_alloc env t1 a in
61316138
build_submode_pos a
61326139
end else begin
6133-
let a = mode_cross_left_alloc env t1 a in
6140+
let a = cross_left_alloc env t1 a in
61346141
build_submode_neg a
61356142
end
61366143
end else a, Unchanged
@@ -6360,7 +6367,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
63606367
t2 t1
63616368
cstrs
63626369
in
6363-
let a2 = mode_cross_left_alloc env t2 a2 in
6370+
let a2 = cross_left_alloc env t2 a2 in
63646371
subtype_alloc_mode env trace a2 a1;
63656372
(* RHS mode of arrow types indicates allocation in the parent region
63666373
and is not subject to mode crossing *)

typing/ctype.mli

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,3 +720,45 @@ val is_principal : type_expr -> bool
720720
type global_state
721721
val global_state : global_state
722722
val print_global_state : Format.formatter -> global_state -> unit
723+
724+
(** Get the crossing of a jkind *)
725+
val crossing_of_jkind : Env.t -> 'd Types.jkind -> Mode.Crossing.t
726+
727+
(** Get the crossing of a type wrapped in modalities *)
728+
val crossing_of_ty :
729+
Env.t ->
730+
?modalities:Mode.Modality.Value.Const.t ->
731+
Types.type_expr ->
732+
Mode.Crossing.t
733+
734+
(** Cross a right mode according to a type wrapped in modalities. *)
735+
val cross_right :
736+
Env.t ->
737+
?modalities:Mode.Modality.Value.Const.t ->
738+
Types.type_expr ->
739+
Mode.Value.r ->
740+
Mode.Value.r
741+
742+
(** Cross a left mode according to a type wrapped in modalities. *)
743+
val cross_left :
744+
Env.t ->
745+
?modalities:Mode.Modality.Value.Const.t ->
746+
Types.type_expr ->
747+
Mode.Value.l ->
748+
Mode.Value.l
749+
750+
(** Similar to [cross_right] but for [Mode.Alloc] *)
751+
val cross_right_alloc :
752+
Env.t ->
753+
?modalities:Mode.Modality.Value.Const.t ->
754+
Types.type_expr ->
755+
Mode.Alloc.r ->
756+
Mode.Alloc.r
757+
758+
(** Similar to [cross_left] but for [Mode.Alloc] *)
759+
val cross_left_alloc :
760+
Env.t ->
761+
?modalities:Mode.Modality.Value.Const.t ->
762+
Types.type_expr ->
763+
Mode.Alloc.l ->
764+
Mode.Alloc.l

typing/includecore.ml

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,6 @@ type mmodes =
5151
| All
5252
| Legacy of Env.held_locks option
5353

54-
(** Mode cross a right mode *)
55-
(* This is very similar to Ctype.mode_cross_right. Any bugs here are likely bugs
56-
there, too. *)
57-
let right_mode_cross_jkind env jkind mode =
58-
let jkind_of_type = Ctype.type_jkind_purely_if_principal env in
59-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
60-
Crossing.apply_right crossing mode
61-
62-
let right_mode_cross env ty mode =
63-
if not (Ctype.is_principal ty) then mode else
64-
let jkind = Ctype.type_jkind_purely env ty in
65-
right_mode_cross_jkind env jkind mode
66-
67-
let left_mode_cross_jkind env jkind mode =
68-
let jkind_of_type = Ctype.type_jkind_purely_if_principal env in
69-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
70-
Crossing.apply_left crossing mode
71-
72-
let left_mode_cross env ty mode=
73-
if not (Ctype.is_principal ty) then mode else
74-
let jkind = Ctype.type_jkind_purely env ty in
75-
left_mode_cross_jkind env jkind mode
76-
7754
let native_repr_args nra1 nra2 =
7855
let rec loop i nra1 nra2 =
7956
match nra1, nra2 with
@@ -152,14 +129,14 @@ let value_descriptions ~loc env name
152129
match close_over_coercion with
153130
| Some held_locks ->
154131
(* Cross modes according to RHS type as it tends to be by the user. *)
155-
let mode1 = left_mode_cross env vd2.val_type mode1 in
132+
let mode1 = Ctype.cross_left env vd2.val_type mode1 in
156133
let mode1 =
157134
Env.walk_locks ~env ~item:Value mode1 (Some vd1.val_type) held_locks
158135
in
159136
mode1.mode
160137
| None -> mode1
161138
in
162-
let mode2 = right_mode_cross env vd2.val_type mode2 in
139+
let mode2 = Ctype.cross_right env vd2.val_type mode2 in
163140
begin match Mode.Value.submode mode1 mode2 with
164141
| Ok () -> ()
165142
| Error e -> raise (Dont_match (Mode e))

typing/typecore.ml

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -930,52 +930,29 @@ let has_poly_constraint spat =
930930
end
931931
| _ -> false
932932

933-
(** Cross a left mode according to a type wrapped in modalities. *)
934-
let mode_cross_left_value env ty ?modalities mode =
935-
if not (is_principal ty) then
936-
Value.disallow_right mode
937-
else begin
938-
let jkind = type_jkind_purely env ty in
939-
let jkind_of_type = type_jkind_purely_if_principal env in
940-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
941-
let crossing =
942-
match modalities with
943-
| None -> crossing
944-
| Some m -> Crossing.modality m crossing
945-
in
946-
mode
947-
|> Value.disallow_right
948-
|> Crossing.apply_left crossing
949-
end
950-
951933
let actual_mode_cross_left env ty (actual_mode : Env.actual_mode)
952934
: Env.actual_mode =
953-
let mode = mode_cross_left_value env ty actual_mode.mode in
935+
let mode = cross_left env ty actual_mode.mode in
954936
{actual_mode with mode}
955937

956938
(** Mode cross a mode whose monadic fragment is a right mode, and whose comonadic
957939
fragment is a left mode. *)
958940
let alloc_mode_cross_to_max_min env ty { monadic; comonadic } =
959941
let monadic = Alloc.Monadic.disallow_left monadic in
960942
let comonadic = Alloc.Comonadic.disallow_right comonadic in
961-
if not (is_principal ty) then { monadic; comonadic } else
962-
let jkind = type_jkind_purely env ty in
963-
let jkind_of_type = type_jkind_purely_if_principal env in
964-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
943+
let crossing = crossing_of_ty env ty in
965944
Crossing.apply_left_right_alloc crossing { monadic; comonadic }
966945

967946
(** Mode cross a right mode *)
968947
(* This is very similar to Ctype.mode_cross_right. Any bugs here are likely bugs
969948
there, too. *)
970949
let expect_mode_cross_jkind env jkind (expected_mode : expected_mode) =
971-
let jkind_of_type = type_jkind_purely_if_principal env in
972-
let crossing = Jkind.get_mode_crossing ~jkind_of_type jkind in
950+
let crossing = crossing_of_jkind env jkind in
973951
mode_morph (Crossing.apply_right crossing) expected_mode
974952

975953
let expect_mode_cross env ty (expected_mode : expected_mode) =
976-
if not (is_principal ty) then expected_mode else
977-
let jkind = type_jkind_purely env ty in
978-
expect_mode_cross_jkind env jkind expected_mode
954+
let crossing = crossing_of_ty env ty in
955+
mode_morph (Crossing.apply_right crossing) expected_mode
979956

980957
(** The expected mode for objects *)
981958
let mode_object = expect_mode_cross_jkind Env.empty Jkind.for_object mode_legacy
@@ -1018,7 +995,7 @@ let check_construct_mutability ~loc ~env mutability ty ?modalities block_mode =
1018995
| Immutable -> ()
1019996
| Mutable m0 ->
1020997
let m0 = mutable_mode m0 in
1021-
let m0 = mode_cross_left_value env ty ?modalities m0 in
998+
let m0 = cross_left env ty ?modalities m0 in
1022999
submode ~loc ~env m0 block_mode
10231000

10241001
(** The [expected_mode] of the record when projecting a mutable field. *)
@@ -2815,7 +2792,7 @@ and type_pat_aux
28152792
| Ppat_var name ->
28162793
let ty = instance expected_ty in
28172794
let alloc_mode =
2818-
mode_cross_left_value !!penv expected_ty alloc_mode.mode
2795+
cross_left !!penv expected_ty alloc_mode.mode
28192796
in
28202797
let id, uid =
28212798
enter_variable tps loc name alloc_mode ty sp.ppat_attributes
@@ -2858,7 +2835,7 @@ and type_pat_aux
28582835
| Ppat_alias(sq, name) ->
28592836
let q = type_pat tps Value sq expected_ty in
28602837
let ty_var, mode = solve_Ppat_alias ~mode:alloc_mode.mode !!penv q in
2861-
let mode = mode_cross_left_value !!penv expected_ty mode in
2838+
let mode = cross_left !!penv expected_ty mode in
28622839
let id, uid =
28632840
enter_variable ~is_as_variable:true tps name.loc name mode ty_var
28642841
sp.ppat_attributes
@@ -6052,14 +6029,14 @@ and type_expect_
60526029
match is_float_boxing with
60536030
| true ->
60546031
let alloc_mode, argument_mode = register_allocation expected_mode in
6055-
let mode = mode_cross_left_value env Predef.type_unboxed_float mode in
6032+
let mode = cross_left env Predef.type_unboxed_float mode in
60566033
submode ~loc ~env mode argument_mode;
60576034
let uu =
60586035
unique_use ~loc ~env mode (as_single_mode argument_mode)
60596036
in
60606037
Boxing (alloc_mode, uu)
60616038
| false ->
6062-
let mode = mode_cross_left_value env ty_arg mode in
6039+
let mode = cross_left env ty_arg mode in
60636040
submode ~loc ~env mode expected_mode;
60646041
let uu = unique_use ~loc ~env mode (as_single_mode expected_mode) in
60656042
Non_boxing uu
@@ -6098,7 +6075,7 @@ and type_expect_
60986075
(Error (loc, env, Record_projection_not_rep(record.exp_type, err)))
60996076
in
61006077
let mode = Modality.Value.Const.apply label.lbl_modalities rmode in
6101-
let mode = mode_cross_left_value env ty_arg mode in
6078+
let mode = cross_left env ty_arg mode in
61026079
submode ~loc ~env mode expected_mode;
61036080
let uu = unique_use ~loc ~env mode (as_single_mode expected_mode) in
61046081
rue {
@@ -7054,7 +7031,7 @@ and type_ident env ?(recarg=Rejected) lid =
70547031
70557032
Therefore, we need to cross modes upon look-up. Ideally that should be done in
70567033
[Env], but that is difficult due to cyclic dependency between jkind and env. *)
7057-
let mode = mode_cross_left_value env desc.val_type mode in
7034+
let mode = cross_left env desc.val_type mode in
70587035
(* There can be locks between the definition and a use of a value. For
70597036
example, if a function closes over a value, there will be Closure_lock between
70607037
the value's definition and the value's use in the function. Walking the locks
@@ -7525,7 +7502,7 @@ and type_label_access
75257502
let label =
75267503
wrap_disambiguate "This expression has" (mk_expected ty_exp)
75277504
(label_disambiguate record_form usage lid env expected_type) labels in
7528-
(record, mode, label, expected_type)
7505+
(record, Mode.Value.disallow_right mode, label, expected_type)
75297506

75307507
(* Typing format strings for printing or reading.
75317508
These formats are used by functions in modules Printf, Format, and Scanf.
@@ -8191,15 +8168,16 @@ and type_application env app_loc expected_mode position_and_mode
81918168
filter_arrow_mono env (instance funct.exp_type) Nolabel
81928169
) ~post:(fun {ty_ret; _} -> generalize_structure ty_ret)
81938170
in
8171+
let ret_mode = Alloc.disallow_right ret_mode in
81948172
let type_sort ~why ty =
81958173
match Ctype.type_sort ~why ~fixed:false env ty with
81968174
| Ok sort -> sort
81978175
| Error err -> raise (Error (app_loc, env, Function_type_not_rep (ty, err)))
81988176
in
81998177
let arg_sort = type_sort ~why:Function_argument ty_arg in
8200-
let ap_mode = Locality.disallow_right (Alloc.proj (Comonadic Areality) ret_mode) in
8178+
let ap_mode = Alloc.proj (Comonadic Areality) ret_mode in
82018179
let mode_res =
8202-
mode_cross_left_value env ty_ret (alloc_as_value ret_mode)
8180+
cross_left env ty_ret (alloc_as_value ret_mode)
82038181
in
82048182
submode ~loc:app_loc ~env ~reason:Other
82058183
mode_res expected_mode;
@@ -8256,9 +8234,10 @@ and type_application env app_loc expected_mode position_and_mode
82568234
ty_ret, mode_ret, args, position_and_mode
82578235
end ~post:(fun (ty_ret, _, _, _) -> generalize_structure ty_ret)
82588236
in
8259-
let ap_mode = Locality.disallow_right (Alloc.proj (Comonadic Areality) mode_ret) in
8237+
let mode_ret = Alloc.disallow_right mode_ret in
8238+
let ap_mode = Alloc.proj (Comonadic Areality) mode_ret in
82608239
let mode_ret =
8261-
mode_cross_left_value env ty_ret (alloc_as_value mode_ret)
8240+
cross_left env ty_ret (alloc_as_value mode_ret)
82628241
in
82638242
submode ~loc:app_loc ~env ~reason:(Application ty_ret)
82648243
mode_ret expected_mode;

0 commit comments

Comments
 (0)