@@ -25,47 +25,6 @@ let union = VarMap.union
25
25
let from_list xs = List. to_seq xs |> VarMap. of_seq
26
26
27
27
28
- (* Combines two environments. The environments should only intersect
29
- on unrestricted types. *)
30
- let combine : Interface_env.t -> t -> t -> t * Constraint_set.t =
31
- fun ienv env1 env2 ->
32
- (* Types must be *the same* and *unrestricted* *)
33
- (* Subtype in both directions *)
34
- let join_types var (ty1 : Type.t ) (ty2 : Type.t ) =
35
- (* The subtyping and constraints are enough to rule out
36
- re-use of mailboxes, but it's worth special-casing to
37
- get a better error message. *)
38
- if Type. contains_mailbox_type ty1 && Type. contains_mailbox_type ty2
39
- then
40
- Gripers. combine_mailbox_type var
41
- else
42
- Constraint_set. union_many
43
- [
44
- make_unrestricted ty1;
45
- make_unrestricted ty2;
46
- subtype ienv ty1 ty2;
47
- subtype ienv ty2 ty1
48
- ]
49
- in
50
- (* Find the overlapping keys, zip up, and join. *)
51
- (* Since the subtyping in both directions will ensure equality of types,
52
- and that the relevant constraints are generated, it is safe to just
53
- use either type in the combined environment. *)
54
- let overlap_constrs =
55
- bindings env1
56
- |> List. filter_map (fun (k , ty1 ) ->
57
- match lookup_opt k env2 with
58
- | None -> None
59
- | Some ty2 -> Some (join_types k ty1 ty2)
60
-
61
- )
62
- |> Constraint_set. union_many
63
- in
64
- let combined_env =
65
- union (fun _ ty1 _ -> Some ty1) env1 env2
66
- in
67
- (combined_env, overlap_constrs)
68
-
69
28
(* Joins two sequential or concurrent environments (i.e., where *both*
70
29
actions will happen). *)
71
30
let join : Interface_env.t -> t -> t -> t * Constraint_set.t =
@@ -155,6 +114,53 @@ let join : Interface_env.t -> t -> t -> t * Constraint_set.t =
155
114
) ([] , Constraint_set. empty) isect1 in
156
115
from_list (joined @ disjoint1 @ disjoint2), constrs
157
116
117
+ (* Combines two environments. The environments should only intersect
118
+ on unrestricted types. *)
119
+ let combine : Interface_env.t -> t -> t -> t * Constraint_set.t =
120
+ fun ienv env1 env2 ->
121
+ let combine_really ienv env1 env2 =
122
+ (* Types must be *the same* and *unrestricted* *)
123
+ (* Subtype in both directions *)
124
+ let join_types var (ty1 : Type.t ) (ty2 : Type.t ) =
125
+ (* The subtyping and constraints are enough to rule out
126
+ re-use of mailboxes, but it's worth special-casing to
127
+ get a better error message. *)
128
+ if Type. contains_mailbox_type ty1 && Type. contains_mailbox_type ty2
129
+ then
130
+ Gripers. combine_mailbox_type var
131
+ else
132
+ Constraint_set. union_many
133
+ [
134
+ make_unrestricted ty1;
135
+ make_unrestricted ty2;
136
+ subtype ienv ty1 ty2;
137
+ subtype ienv ty2 ty1
138
+ ]
139
+ in
140
+ (* Find the overlapping keys, zip up, and join. *)
141
+ (* Since the subtyping in both directions will ensure equality of types,
142
+ and that the relevant constraints are generated, it is safe to just
143
+ use either type in the combined environment. *)
144
+ let overlap_constrs =
145
+ bindings env1
146
+ |> List. filter_map (fun (k , ty1 ) ->
147
+ match lookup_opt k env2 with
148
+ | None -> None
149
+ | Some ty2 -> Some (join_types k ty1 ty2)
150
+
151
+ )
152
+ |> Constraint_set. union_many
153
+ in
154
+ let combined_env =
155
+ union (fun _ ty1 _ -> Some ty1) env1 env2
156
+ in
157
+ (combined_env, overlap_constrs)
158
+ in
159
+ let fn =
160
+ if Settings. (get join_not_combine) then join else combine_really
161
+ in
162
+ fn ienv env1 env2
163
+
158
164
(* Merges environments resulting from branching control flow. *)
159
165
(* Core idea is that linear types must be used in precisely the same way in
160
166
each branch. Unrestricted types must be used at the same type, but need
0 commit comments