summaryrefslogtreecommitdiff
path: root/typing/types.ml
diff options
context:
space:
mode:
authorTakafumi Saikawa <tscompor@gmail.com>2021-07-26 16:46:47 +0900
committerJacques Garrigue <garrigue@math.nagoya-u.ac.jp>2021-10-18 21:34:35 +0900
commit024007974fbf299945957a9fee2526a694ba1b2f (patch)
tree2443731281bb55829da7c0119efab18e6d77f9f2 /typing/types.ml
parenta7bf9cbaf368f178b606e7cf38ede4a22984a9da (diff)
downloadocaml-024007974fbf299945957a9fee2526a694ba1b2f.tar.gz
make field_kind and commutable abstract types
Diffstat (limited to 'typing/types.ml')
-rw-r--r--typing/types.ml101
1 files changed, 81 insertions, 20 deletions
diff --git a/typing/types.ml b/typing/types.ml
index c70691dd9d..b43e656d13 100644
--- a/typing/types.ml
+++ b/typing/types.ml
@@ -64,14 +64,15 @@ and abbrev_memo =
| Mlink of abbrev_memo ref
and field_kind =
- Fvar of field_kind option ref
- | Fpresent
- | Fabsent
+ FKvar of {mutable field_kind: field_kind}
+ | FKprivate (* was None as parameter to Fvar *)
+ | FKpublic (* was Fpresent *)
+ | FKabsent
and commutable =
Cok
| Cunknown
- | Clink of commutable ref
+ | Cvar of {mutable commu: commutable}
module TransientTypeOps = struct
type t = type_expr
@@ -487,8 +488,8 @@ type change =
| Cname of
(Path.t * type_expr list) option ref * (Path.t * type_expr list) option
| Crow of row_field option ref * row_field option
- | Ckind of field_kind option ref * field_kind option
- | Ccommu of commutable ref * commutable
+ | Ckind of field_kind
+ | Ccommu of commutable
| Cuniv of type_expr option ref * type_expr option
type changes =
@@ -503,18 +504,47 @@ let log_change ch =
!trail := Change (ch, r');
trail := r'
-(**** Representative of a type ****)
+(* constructor and accessors for [field_kind] *)
+
+type field_kind_view =
+ Fprivate
+ | Fpublic
+ | Fabsent
+
+let rec field_kind_internal_repr = function
+ | FKvar {field_kind} when field_kind <> FKprivate ->
+ field_kind_internal_repr field_kind
+ | kind -> kind
+
+let field_kind_repr fk =
+ match field_kind_internal_repr fk with
+ | FKvar _ -> Fprivate
+ | FKpublic -> Fpublic
+ | FKabsent -> Fabsent
+ | FKprivate -> Misc.fatal_error "Types.field_kind_repr"
+
+let field_public = FKpublic
+let field_absent = FKabsent
+let field_private () = FKvar {field_kind=FKprivate}
+
+(* Constructor and accessors for [commutable] *)
-let rec field_kind_repr =
- function
- Fvar {contents = Some kind} -> field_kind_repr kind
- | kind -> kind
+let rec is_commu_ok = function
+ | Cvar {commu} -> is_commu_ok commu
+ | Cunknown -> false
+ | Cok -> true
+
+let commu_ok = Cok
+let commu_var () = Cvar {commu=Cunknown}
+
+(**** Representative of a type ****)
let rec repr_link (t : type_expr) d : type_expr -> type_expr =
function
{desc = Tlink t' as d'} ->
repr_link t d' t'
- | {desc = Tfield (_, k, _, t') as d'} when field_kind_repr k = Fabsent ->
+ | {desc = Tfield (_, k, _, t') as d'}
+ when field_kind_internal_repr k = FKabsent ->
repr_link t d' t'
| t' ->
log_change (Ccompress (t, t.desc, d));
@@ -524,7 +554,8 @@ let rec repr_link (t : type_expr) d : type_expr -> type_expr =
let repr_link1 t = function
{desc = Tlink t' as d'} ->
repr_link t d' t'
- | {desc = Tfield (_, k, _, t') as d'} when field_kind_repr k = Fabsent ->
+ | {desc = Tfield (_, k, _, t') as d'}
+ when field_kind_internal_repr k = FKabsent ->
repr_link t d' t'
| t' -> t'
@@ -532,7 +563,7 @@ let repr t =
match t.desc with
Tlink t' ->
repr_link1 t t'
- | Tfield (_, k, _, t') when field_kind_repr k = Fabsent ->
+ | Tfield (_, k, _, t') when field_kind_internal_repr k = FKabsent ->
repr_link1 t t'
| _ -> t
@@ -651,8 +682,10 @@ let undo_change = function
| Cscope (ty, scope) -> Transient_expr.set_scope ty scope
| Cname (r, v) -> r := v
| Crow (r, v) -> r := v
- | Ckind (r, v) -> r := v
- | Ccommu (r, v) -> r := v
+ | Ckind (FKvar r) -> r.field_kind <- FKprivate
+ | Ckind _ -> assert false
+ | Ccommu (Cvar r) -> r.commu <- Cunknown
+ | Ccommu _ -> Misc.fatal_error "Types.undo_change"
| Cuniv (r, v) -> r := v
type snapshot = changes ref * int
@@ -709,10 +742,38 @@ let set_name nm v =
log_change (Cname (nm, !nm)); nm := v
let set_row_field e v =
log_change (Crow (e, !e)); e := Some v
-let set_kind rk k =
- log_change (Ckind (rk, !rk)); rk := Some k
-let set_commu rc c =
- log_change (Ccommu (rc, !rc)); rc := c
+
+let rec link_kind ~inside k =
+ match inside with
+ | FKvar ({field_kind = FKprivate} as rk) ->
+ (* prevent a loop by normalizing k and comparing it with inside *)
+ let k = field_kind_internal_repr k in
+ if k != inside then begin
+ log_change (Ckind inside);
+ rk.field_kind <- k
+ end
+ | FKvar {field_kind} ->
+ link_kind ~inside:field_kind k
+ | _ -> invalid_arg "Types.link_kind"
+
+let rec commu_repr = function
+ Cvar {commu} when commu != Cunknown -> commu_repr commu
+ | c -> c
+
+let rec link_commu ~inside c =
+ match inside with
+ | Cvar ({commu = Cunknown} as rc) ->
+ (* prevent a loop by normalizing c and comparing it with inside *)
+ let c = commu_repr c in
+ if c != inside then begin
+ log_change (Ccommu inside);
+ rc.commu <- c
+ end
+ | Cvar {commu} ->
+ link_commu ~inside:commu c
+ | _ -> invalid_arg "Types.link_commu"
+
+let set_commu_ok c = link_commu ~inside:c Cok
let snapshot () =
let old = !last_snapshot in