Skip to content

Commit bfe1ad1

Browse files
authored
Initialize typing env with stdlib (#135)
* Initialize typing env with stdlib * Add test * Init env with stdlib in unit tests * Add change log entry * Update test description * Fix failing test for functor paramters * Format * Minor fixes
1 parent 5845a27 commit bfe1ad1

File tree

9 files changed

+75
-12
lines changed

9 files changed

+75
-12
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
changes in a line (#126,@azzsal)
2727
- Improve handling of type equalities across the reference and current
2828
versions of the interface. (#134, @azzsal)
29+
- Initialize the typing enviorment with the standard library
2930

3031
### Deprecated
3132

lib/api_watch.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ module Library = Library
55
module Normalize = Normalize
66
module Stddiff = Stddiff
77
module Ocaml_types = Ocaml_types
8+
module Typing_env = Typing_env

lib/diff.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ and module_type ~typing_env ~name ~ref_module_type ~current_module_type
531531
~reference:ref_modtype ~current:curr_modtype
532532

533533
and signatures ~reference ~current =
534+
let initialized_env = Typing_env.initialized_env () in
534535
let modified_reference, modified_current, typing_env =
535536
Typing_env.for_diff ~reference ~current
536537
in
@@ -539,10 +540,10 @@ and signatures ~reference ~current =
539540
with
540541
| [] -> (
541542
let coercion1 () =
542-
Includemod.signatures Env.empty ~mark:Mark_both reference current
543+
Includemod.signatures initialized_env ~mark:Mark_both reference current
543544
in
544545
let coercion2 () =
545-
Includemod.signatures Env.empty ~mark:Mark_both current reference
546+
Includemod.signatures initialized_env ~mark:Mark_both current reference
546547
in
547548
match (coercion1 (), coercion2 ()) with
548549
| Tcoerce_none, Tcoerce_none -> None

lib/typing_env.ml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,34 @@ let replace_matching_ids ~reference ~current =
4545
Sig_type (new_id, td, r, v) :: lst )
4646
| None -> (subst, sig_typ_decl :: lst))
4747
| Sig_module (id, mp, md, r, v) as sig_mod_decl -> (
48-
match Env.find_value_index id ref_env with
48+
match Env.find_module_index id ref_env with
4949
| Some _ ->
5050
let new_id = Ident.rename id in
5151
( Subst.add_module id (Path.Pident new_id) subst,
5252
Sig_module (new_id, mp, md, r, v) :: lst )
5353
| None -> (subst, sig_mod_decl :: lst))
54-
| Sig_modtype (id, mtd, v) as sig_modtyp_decl -> (
54+
| Sig_modtype (id, mtd, v) -> (
5555
match Env.find_modtype_index id ref_env with
5656
| Some _ ->
5757
let new_id = Ident.rename id in
5858
( Subst.add_modtype id (Mty_ident (Pident new_id)) subst,
5959
Sig_modtype (new_id, mtd, v) :: lst )
60-
| None -> (subst, sig_modtyp_decl :: lst))
60+
| None ->
61+
(* This is a special case for functor paramters.
62+
When two functors have different parameters,
63+
they might treated equally by Includemod.modtypes, thus
64+
one of parameters' id has to be rewritten. For example:
65+
module F (M : X) : A and module F (M : Y) : A
66+
X and Y could have the same stamp, thus they would be
67+
treated equally, so Y stamp has to be rewritten.
68+
Note: This should be removed once we have fine-grained
69+
diffing of functors *)
70+
let new_id = ref (Ident.rename id) in
71+
while Option.is_some (Env.find_modtype_index !new_id ref_env) do
72+
new_id := Ident.rename id
73+
done;
74+
( Subst.add_modtype id (Mty_ident (Pident !new_id)) subst,
75+
Sig_modtype (!new_id, mtd, v) :: lst ))
6176
| Sig_value (id, vd, v) as sig_val -> (
6277
match Env.find_value_index id ref_env with
6378
| Some _ ->
@@ -117,9 +132,17 @@ let pair_items ~reference ~current =
117132
| _ -> subst)
118133
Subst.identity current
119134

135+
let initialized_env =
136+
Compmisc.init_path ();
137+
let env = Compmisc.initial_env () in
138+
fun () -> env
139+
120140
let for_diff ~reference ~current =
121141
let current = replace_matching_ids ~reference ~current in
122-
let env = Env.add_signature reference (Env.in_signature true Env.empty) in
142+
let reference = replace_matching_ids ~reference:current ~current:reference in
143+
let env =
144+
Env.add_signature reference (Env.in_signature true (initialized_env ()))
145+
in
123146
let env = Env.add_signature current env in
124147
let subst = pair_items ~reference ~current in
125148
let modified_current = apply_subst subst current in
@@ -155,6 +178,10 @@ let pp fmt t =
155178
(match mp with
156179
| Mp_present -> "Mp_present"
157180
| Mp_absent -> "Mp_absent");
181+
(match md_type with
182+
| Mty_functor (Named (Some pid, _pmt), _fmt) ->
183+
Ident.print Format.std_formatter pid
184+
| _ -> ());
158185
Format.fprintf fmt "%a" Printtyp.modtype md_type)
159186
| Env_modtype (s, id, mtyp) ->
160187
pp_rec s;

lib/typing_env.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ open Types
44

55
type t = Env.t
66

7+
val initialized_env : unit -> t
8+
(** Returns a environment initialized with the standard library. *)
9+
710
val for_diff :
811
reference:signature -> current:signature -> signature * signature * t
912
(** Returns two modified signatures with unique IDs that are suitable

tests/api-diff/stdlib.t

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Here we generate a `.mli` file with a type alias referencing a standard library type
2+
3+
$ cat > ref.mli << EOF
4+
> type t = String.t
5+
> EOF
6+
7+
We generate the .cmi file
8+
9+
$ ocamlc ref.mli
10+
11+
# A type that references the same type in the standard library
12+
13+
$ cat > cur.mli << EOF
14+
> type t = string
15+
> EOF
16+
17+
We generate the .cmi file
18+
19+
$ ocamlc cur.mli
20+
21+
Run the api-watcher on the two cmi files, there should be no diff
22+
23+
$ api-diff ref.cmi cur.cmi

tests/api-watch/stdlib.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
open Api_watch
2+
open Test_helpers
3+
4+
let%expect_test "Identical types" =
5+
let reference = compile_interface {| type t = String.t |} in
6+
let current = compile_interface {| type t = string |} in
7+
let result = Diff.interface ~module_name:"Main" ~reference ~current in
8+
Format.printf "%a" pp_diff_option result;
9+
[%expect {| None |}]

tests/api-watch/test_diff_module.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ let%expect_test "Modules with multiple value and submodule changes" =
3434
compile_interface
3535
{|
3636
type ('a, 'b) result = Ok of 'a | Error of 'b
37-
val a : string -> int
37+
val a : string -> int
3838
val f : int -> string
3939
module M : sig
4040
val b : int list -> int
@@ -89,7 +89,7 @@ let%expect_test "Modules with both supported and unsupported changes" =
8989
Some (Module Main: {Modified (Supported [ Value (x, Removed);
9090
Module M: {Modified (Unsupported)}])})|}]
9191

92-
let%expect_test "Submodules with different functor types" =
92+
let%expect_test "Submodules with different functor types." =
9393
let reference =
9494
compile_interface
9595
{|

tests/test_helpers/test_helpers.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
open Api_watch.Diff
2+
open Api_watch.Typing_env
23

34
let rec pp_module_modification fmt = function
45
| Unsupported -> Format.fprintf fmt "Unsupported"
@@ -67,10 +68,7 @@ let parse_interface content =
6768
Parse.interface lexbuf
6869

6970
let generate_signature intf =
70-
let typing_env =
71-
Typemod.initial_env ~loc:Location.none ~initially_opened_module:None
72-
~open_implicit_modules:[]
73-
in
71+
let typing_env = initialized_env () in
7472
let typed_tree = Typemod.type_interface typing_env intf in
7573
typed_tree.sig_type
7674

0 commit comments

Comments
 (0)