···10101111### Type system:
12121313+- GPR#1826: allow expanding a type to a private abbreviation instead of
1414+ abstracting when removing references to an identifier
1515+ (Thomas Refis and Leo White, review by Jacques Garrigue)
1616+1317### Standard library:
14181519- MPR#6701, GPR#1185, GPR#1803: make float_of_string and string_of_float
···11+(* TEST
22+ * expect
33+*)
44+55+module F(_ : sig end) : sig
66+ type t = private int
77+end = struct
88+ type t = int
99+end;;
1010+[%%expect{|
1111+module F : sig end -> sig type t = private int end
1212+|}]
1313+1414+module Direct = F(struct end);;
1515+[%%expect{|
1616+module Direct : sig type t = private int end
1717+|}]
1818+1919+module G(X : sig end) : sig
2020+ type t = F(X).t
2121+end = F(X);;
2222+[%%expect{|
2323+module G : functor (X : sig end) -> sig type t = F(X).t end
2424+|}]
2525+2626+module Indirect = G(struct end);;
2727+[%%expect{|
2828+module Indirect : sig type t = private int end
2929+|}]
3030+3131+(* unroll_abbrev *)
3232+3333+module Pub(_ : sig end) = struct
3434+ type t = [ `Foo of t ]
3535+end;;
3636+[%%expect{|
3737+module Pub : sig end -> sig type t = [ `Foo of t ] end
3838+|}]
3939+4040+module Priv(_ : sig end) = struct
4141+ type t = private [ `Foo of t ]
4242+end;;
4343+[%%expect{|
4444+module Priv : sig end -> sig type t = private [ `Foo of t ] end
4545+|}]
4646+4747+module DirectPub = Pub(struct end);;
4848+[%%expect{|
4949+module DirectPub : sig type t = [ `Foo of t ] end
5050+|}]
5151+5252+module DirectPriv = Priv(struct end);;
5353+[%%expect{|
5454+module DirectPriv : sig type t = private [ `Foo of t ] end
5555+|}]
5656+5757+module H(X : sig end) : sig
5858+ type t = Pub(X).t
5959+end = Pub(X);;
6060+[%%expect{|
6161+module H : functor (X : sig end) -> sig type t = Pub(X).t end
6262+|}]
6363+6464+module I(X : sig end) : sig
6565+ type t = Priv(X).t
6666+end = Priv(X);;
6767+[%%expect{|
6868+module I : functor (X : sig end) -> sig type t = Priv(X).t end
6969+|}]
7070+7171+module IndirectPub = H(struct end);;
7272+[%%expect{|
7373+module IndirectPub : sig type t = [ `Foo of t ] end
7474+|}]
7575+7676+(* The result would be
7777+ {[
7878+ type t = private [ `Foo of t ]
7979+ ]}
8080+ if we were unrolling the abbrev. *)
8181+module IndirectPriv = I(struct end);;
8282+[%%expect{|
8383+module IndirectPriv : sig type t end
8484+|}]
8585+8686+(*** Test proposed by Jacques in
8787+ https://github.com/ocaml/ocaml/pull/1826#discussion_r194290729 ***)
8888+8989+(* Baseline *)
9090+9191+type t = private [ `Bar of int | `Foo of t -> int ];;
9292+[%%expect{|
9393+type t = private [ `Bar of int | `Foo of t -> int ]
9494+|}]
9595+9696+module M : sig
9797+ type s = private [ `Bar of int | `Foo of 'a -> int ] as 'a
9898+end = struct
9999+ type s = t
100100+end;;
101101+[%%expect{|
102102+Line _, characters 6-29:
103103+ ......struct
104104+ type s = t
105105+ end..
106106+Error: Signature mismatch:
107107+ Modules do not match:
108108+ sig type s = t end
109109+ is not included in
110110+ sig type s = private [ `Bar of int | `Foo of 'a -> int ] as 'a end
111111+ Type declarations do not match:
112112+ type s = t
113113+ is not included in
114114+ type s = private [ `Bar of int | `Foo of 'a -> int ] as 'a
115115+|}]
116116+117117+(* nondep_type_decl + nondep_type_rec *)
118118+119119+module Priv(_ : sig end) = struct
120120+ type t = private [ `Foo of t -> int | `Bar of int ]
121121+end;;
122122+[%%expect{|
123123+module Priv :
124124+ sig end -> sig type t = private [ `Bar of int | `Foo of t -> int ] end
125125+|}]
126126+127127+module I(X : sig end) : sig
128128+ type t = Priv(X).t
129129+end = Priv(X);;
130130+[%%expect{|
131131+module I : functor (X : sig end) -> sig type t = Priv(X).t end
132132+|}]
133133+134134+module IndirectPriv = I(struct end);;
135135+[%%expect{|
136136+module IndirectPriv : sig type t end
137137+|}]
···43694369let clear_hash () =
43704370 TypeHash.clear nondep_hash; TypeHash.clear nondep_variants
4371437143724372-let rec nondep_type_rec env id ty =
43724372+let rec nondep_type_rec ?(expand_private=false) env id ty =
43734373+ let expand_abbrev env t =
43744374+ if expand_private then expand_abbrev_opt env t else expand_abbrev env t
43754375+ in
43734376 match ty.desc with
43744377 Tvar _ | Tunivar _ -> ty
43754378 | Tlink ty -> nondep_type_rec env id ty
···43824385 | Tconstr(p, tl, _abbrev) ->
43834386 if Path.isfree id p then
43844387 begin try
43854385- Tlink (nondep_type_rec env id
43884388+ Tlink (nondep_type_rec ~expand_private env id
43864389 (expand_abbrev env (newty2 ty.level ty.desc)))
43874390 (*
43884391 The [Tlink] is important. The expanded type may be a
···44604463 let tk =
44614464 try map_kind (nondep_type_rec env mid) decl.type_kind
44624465 with Not_found when is_covariant -> Type_abstract
44634463- and tm =
44644464- try match decl.type_manifest with
44654465- None -> None
44664466+ and tm, priv =
44674467+ match decl.type_manifest with
44684468+ | None -> None, decl.type_private
44664469 | Some ty ->
44674467- Some (unroll_abbrev id params (nondep_type_rec env mid ty))
44684468- with Not_found when is_covariant ->
44694469- None
44704470+ try Some (unroll_abbrev id params
44714471+ (nondep_type_rec env mid ty)),
44724472+ decl.type_private
44734473+ with Not_found when is_covariant ->
44744474+ clear_hash ();
44754475+ try Some (nondep_type_rec ~expand_private:true env mid ty),
44764476+ Private
44774477+ with Not_found ->
44784478+ None, decl.type_private
44704479 in
44714480 clear_hash ();
44724481 let priv =
44734482 match tm with
44744483 | Some ty when Btype.has_constr_row ty -> Private
44754475- | _ -> decl.type_private
44844484+ | _ -> priv
44764485 in
44774486 { type_params = params;
44784487 type_arity = decl.type_arity;
+20-7
typing/typemod.ml
···13841384 mty_res
13851385 | None ->
13861386 if generative then mty_res else
13871387- try
13881388- Mtype.nondep_supertype
13891389- (Env.add_module ~arg:true param arg.mod_type env)
13901390- param mty_res
13911391- with Not_found ->
13921392- raise(Error(smod.pmod_loc, env,
13931393- Cannot_eliminate_dependency mty_functor))
13871387+ let env = Env.add_module ~arg:true param arg.mod_type env in
13881388+ let nondep_mty =
13891389+ try Mtype.nondep_supertype env param mty_res
13901390+ with Not_found ->
13911391+ raise(Error(smod.pmod_loc, env,
13921392+ Cannot_eliminate_dependency mty_functor))
13931393+ in
13941394+ begin match
13951395+ Includemod.modtypes ~loc:smod.pmod_loc env mty_res nondep_mty
13961396+ with
13971397+ | Tcoerce_none -> ()
13981398+ | _ ->
13991399+ fatal_error
14001400+ "unexpected coercion from original module type to \
14011401+ nondep_supertype one"
14021402+ | exception Includemod.Error _ ->
14031403+ fatal_error
14041404+ "nondep_supertype not included in original module type"
14051405+ end;
14061406+ nondep_mty
13941407 in
13951408 rm { mod_desc = Tmod_apply(funct, arg, coercion);
13961409 mod_type = mty_appl;