Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make type_expr private #9994

Merged
merged 24 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Working version
- #9650, #9651: keep refactoring the pattern-matching compiler
(Gabriel Scherer, review by Thomas Refis and Florian Angeletti)

- #9994: Make Types.type_expr a private type, and abstract marking mechanism
(Jacques Garrigue and Takafumi Saikawa,
review by Gabriel Scherer and Leo White)

- #10007: Driver.compile_common: when typing a .ml file, return the
compilation unit signature (inferred or from the .cmi) in addition
to the implementation and the coercion.
Expand Down
8 changes: 4 additions & 4 deletions ocamldoc/odoc_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,20 @@ let subst_type env t =
| Types.Tconstr (p, l, a) ->
let new_p =
Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in
t.Types.desc <- Types.Tconstr (new_p, l, a)
Btype.set_type_desc t (Types.Tconstr (new_p, l, a))
| Types.Tpackage (p, n, l) ->
let new_p =
Odoc_name.to_path (full_module_type_name env (Odoc_name.from_path p)) in
t.Types.desc <- Types.Tpackage (new_p, n, l)
Btype.set_type_desc t (Types.Tpackage (new_p, n, l))
| Types.Tobject (_, ({contents=Some(p,tyl)} as r)) ->
let new_p =
Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in
r := Some (new_p, tyl)
| Types.Tvariant ({Types.row_name=Some(p, tyl)} as row) ->
let new_p =
Odoc_name.to_path (full_type_name env (Odoc_name.from_path p)) in
t.Types.desc <-
Types.Tvariant {row with Types.row_name=Some(new_p, tyl)}
Btype.set_type_desc t
(Types.Tvariant {row with Types.row_name=Some(new_p, tyl)})
| _ ->
()
end
Expand Down
3 changes: 2 additions & 1 deletion ocamldoc/odoc_misc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,5 @@ let remove_option typ =
| Types.Tlink t2
| Types.Tsubst t2 -> iter t2.Types.desc
in
{ typ with Types.desc = iter typ.Types.desc }
Types.Private_type_expr.create (iter typ.Types.desc)
~level:typ.Types.level ~scope:typ.Types.scope ~id:typ.Types.id
13 changes: 8 additions & 5 deletions ocamldoc/odoc_print.ml
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,15 @@ let simpl_class_type t =
| Types.Cty_signature cs ->
(* we delete vals and methods in order to not print them when
displaying the type *)
let tnil =
{ Types.desc = Types.Tnil ; Types.level = 0
; Types.scope = Btype.lowest_level ; Types.id = 0 }
let tself =
let t = cs.Types.csig_self in
let t' = Types.Private_type_expr.create Types.Tnil
~level:0 ~scope:Btype.lowest_level ~id:0 in
let desc = Types.Tobject (t', ref None) in
Types.Private_type_expr.create desc
~level:t.Types.level ~scope:t.Types.scope ~id:t.Types.id
in
Types.Cty_signature { Types.csig_self = { cs.Types.csig_self with
Types.desc = Types.Tobject (tnil, ref None) };
Types.Cty_signature { Types.csig_self = tself;
csig_vars = Types.Vars.empty ;
csig_concr = Types.Concr.empty ;
csig_inher = []
Expand Down
88 changes: 52 additions & 36 deletions typing/btype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ let pivot_level = 2 * lowest_level - 1
let new_id = s_ref (-1)

let newty2 level desc =
incr new_id; { desc; level; scope = lowest_level; id = !new_id }
incr new_id;
Private_type_expr.create desc ~level ~scope:lowest_level ~id:!new_id
let newgenty desc = newty2 generic_level desc
let newgenvar ?name () = newgenty (Tvar name)
(*
Expand Down Expand Up @@ -77,7 +78,6 @@ type change =
| Ckind of field_kind option ref * field_kind option
| Ccommu of commutable ref * commutable
| Cuniv of type_expr option ref * type_expr option
| Ctypeset of TypeSet.t ref * TypeSet.t

type changes =
Change of change * changes ref
Expand All @@ -100,19 +100,19 @@ let rec field_kind_repr =
Fvar {contents = Some kind} -> field_kind_repr kind
| kind -> kind

let rec repr_link compress t d =
let rec repr_link compress (t : type_expr) d : type_expr -> type_expr =
function
{desc = Tlink t' as d'} ->
repr_link true t d' t'
| {desc = Tfield (_, k, _, t') as d'} when field_kind_repr k = Fabsent ->
repr_link true t d' t'
| t' ->
if compress then begin
log_change (Ccompress (t, t.desc, d)); t.desc <- d
log_change (Ccompress (t, t.desc, d)); Private_type_expr.set_desc t d
end;
t'

let repr t =
let repr (t : type_expr) =
match t.desc with
Tlink t' as d ->
repr_link false t d t'
Expand Down Expand Up @@ -256,6 +256,20 @@ let is_constr_row ~allow_ident t =
| Tconstr (Path.Pdot (_, s), _, _) -> is_row_name s
| _ -> false

(* TODO: where should this really be *)
(* Set row_name in Env, cf. GPR#1204/1329 *)
let set_row_name decl path =
match decl.type_manifest with
None -> ()
| Some ty ->
let ty = repr ty in
match ty.desc with
Tvariant row when static_row row ->
let row = {(row_repr row) with
row_name = Some (path, decl.type_params)} in
Private_type_expr.set_desc ty (Tvariant row)
| _ -> ()


(**********************************)
(* Utilities for type traversal *)
Expand Down Expand Up @@ -538,7 +552,7 @@ end = struct

(* Restore type descriptions. *)
let cleanup { saved_desc; saved_kinds; _ } =
List.iter (fun (ty, desc) -> ty.desc <- desc) saved_desc;
List.iter (fun (ty, desc) -> Private_type_expr.set_desc ty desc) saved_desc;
List.iter (fun r -> r := None) saved_kinds

let with_scope f =
Expand All @@ -549,29 +563,28 @@ end = struct
end

(* Mark a type. *)

let not_marked_node ty = ty.level >= lowest_level
(* type nodes with negative levels are "marked" *)

let flip_mark_node ty = Private_type_expr.set_level ty (pivot_level - ty.level)

let try_mark_node ty = not_marked_node ty && (flip_mark_node ty; true)

let rec mark_type ty =
let ty = repr ty in
if ty.level >= lowest_level then begin
ty.level <- pivot_level - ty.level;
if not_marked_node ty then begin
flip_mark_node ty;
iter_type_expr mark_type ty
end

let mark_type_node ty =
let ty = repr ty in
if ty.level >= lowest_level then begin
ty.level <- pivot_level - ty.level;
end

let mark_type_params ty =
iter_type_expr mark_type ty

let type_iterators =
let it_type_expr it ty =
let ty = repr ty in
if ty.level >= lowest_level then begin
mark_type_node ty;
it.it_do_type_expr it ty;
end
if try_mark_node ty then it.it_do_type_expr it ty
in
{type_iterators with it_type_expr}

Expand All @@ -580,7 +593,8 @@ let type_iterators =
let rec unmark_type ty =
let ty = repr ty in
if ty.level < lowest_level then begin
ty.level <- pivot_level - ty.level;
(* flip back the marked level *)
flip_mark_node ty;
iter_type_expr unmark_type ty
end

Expand Down Expand Up @@ -708,16 +722,15 @@ let extract_label l ls = extract_label_aux [] l ls
(**********************************)

let undo_change = function
Ctype (ty, desc) -> ty.desc <- desc
| Ccompress (ty, desc, _) -> ty.desc <- desc
| Clevel (ty, level) -> ty.level <- level
| Cscope (ty, scope) -> ty.scope <- scope
Ctype (ty, desc) -> Private_type_expr.set_desc ty desc
| Ccompress (ty, desc, _) -> Private_type_expr.set_desc ty desc
| Clevel (ty, level) -> Private_type_expr.set_level ty level
| Cscope (ty, scope) -> Private_type_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
| Cuniv (r, v) -> r := v
| Ctypeset (r, v) -> r := v

type snapshot = changes ref * int
let last_snapshot = s_ref 0
Expand All @@ -727,35 +740,40 @@ let log_type ty =
let link_type ty ty' =
log_type ty;
let desc = ty.desc in
ty.desc <- Tlink ty';
Private_type_expr.set_desc ty (Tlink ty');
(* Name is a user-supplied name for this unification variable (obtained
* through a type annotation for instance). *)
match desc, ty'.desc with
Tvar name, Tvar name' ->
begin match name, name' with
| Some _, None -> log_type ty'; ty'.desc <- Tvar name
| None, Some _ -> ()
| Some _, None -> log_type ty'; Private_type_expr.set_desc ty' (Tvar name)
| None, Some _ -> ()
| Some _, Some _ ->
if ty.level < ty'.level then (log_type ty'; ty'.desc <- Tvar name)
| None, None -> ()
if ty.level < ty'.level then
(log_type ty'; Private_type_expr.set_desc ty' (Tvar name))
| None, None -> ()
end
| _ -> ()
(* ; assert (check_memorized_abbrevs ()) *)
(* ; check_expans [] ty' *)
(* TODO: consider eliminating set_type_desc, replacing it with link types *)
let set_type_desc ty td =
if td != ty.desc then begin
log_type ty;
ty.desc <- td
Private_type_expr.set_desc ty td
end
let set_level ty level =
(* TODO: separate set_level into two specific functions: *)
(* set_lower_level and set_generic_level *)
let set_level ty level =
if level <> ty.level then begin
if ty.id <= !last_snapshot then log_change (Clevel (ty, ty.level));
ty.level <- level
Private_type_expr.set_level ty level
end
(* TODO: introduce a guard and rename it to set_higher_scope? *)
let set_scope ty scope =
if scope <> ty.scope then begin
if ty.id <= !last_snapshot then log_change (Cscope (ty, ty.scope));
ty.scope <- scope
Private_type_expr.set_scope ty scope
end
let set_univar rty ty =
log_change (Cuniv (rty, !rty)); rty := Some ty
Expand All @@ -767,8 +785,6 @@ 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 set_typeset rs s =
log_change (Ctypeset (rs, !rs)); rs := s

let snapshot () =
let old = !last_snapshot in
Expand Down Expand Up @@ -817,6 +833,6 @@ let undo_compress (changes, _old) =
List.iter
(fun r -> match !r with
Change (Ccompress (ty, desc, d), next) when ty.desc == d ->
ty.desc <- desc; r := !next
Private_type_expr.set_desc ty desc; r := !next
| _ -> ())
log
21 changes: 13 additions & 8 deletions typing/btype.mli
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ val has_constr_row: type_expr -> bool
val is_row_name: string -> bool
val is_constr_row: allow_ident:bool -> type_expr -> bool

(* Set the polymorphic variant row_name field *)
val set_row_name : type_declaration -> Path.t -> unit

(**** Utilities for type traversal ****)

val iter_type_expr: (type_expr -> unit) -> type_expr -> unit
Expand Down Expand Up @@ -130,7 +133,7 @@ type type_iterators =
it_path: Path.t -> unit; }
val type_iterators: type_iterators
(* Iteration on arbitrary type information.
[it_type_expr] calls [mark_type_node] to avoid loops. *)
[it_type_expr] calls [mark_node] to avoid loops. *)
val unmark_iterators: type_iterators
(* Unmark any structure containing types. See [unmark_type] below. *)

Expand Down Expand Up @@ -164,14 +167,17 @@ end

val lowest_level: int
(* Marked type: ty.level < lowest_level *)
val pivot_level: int
(* Type marking: ty.level <- pivot_level - ty.level *)
val not_marked_node: type_expr -> bool
(* Return true if a type node is not yet marked *)
val flip_mark_node: type_expr -> unit
(* Mark a type node. No [repr]'ing *)
val try_mark_node: type_expr -> bool
(* Mark a type node if it is not yet marked.
Return false if it was already marked *)
val mark_type: type_expr -> unit
(* Mark a type *)
val mark_type_node: type_expr -> unit
(* Mark a type node (but not its sons) *)
(* Mark a type recursively *)
val mark_type_params: type_expr -> unit
(* Mark the sons of a type node *)
(* Mark the sons of a type node recursively *)
val unmark_type: type_expr -> unit
val unmark_type_decl: type_declaration -> unit
val unmark_extension_constructor: extension_constructor -> unit
Expand Down Expand Up @@ -241,7 +247,6 @@ val set_row_field: row_field option ref -> row_field -> unit
val set_univar: type_expr option ref -> type_expr -> unit
val set_kind: field_kind option ref -> field_kind -> unit
val set_commu: commutable ref -> commutable -> unit
val set_typeset: TypeSet.t ref -> TypeSet.t -> unit
(* Set references, logging the old value *)

(**** Forward declarations ****)
Expand Down