summaryrefslogtreecommitdiff
path: root/testsuite/tests/typing-modules/module_type_substitution.ml
blob: 09f16ce7be5d50de7630e087589d24c81d58a645 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
(* TEST
  * expect
*)

(** Basic *)
module type x = sig type t = int end

module type t = sig
  module type x
  module M:x
end

module type t' = t with module type x = x
[%%expect {|
module type x = sig type t = int end
module type t = sig module type x module M : x end
module type t' = sig module type x = x module M : x end
|}]

module type t'' = t with module type x := x
[%%expect {|
module type t'' = sig module M : x end
|}]

module type t3 = t with module type x = sig type t end
[%%expect {|
module type t3 = sig module type x = sig type t end module M : x end
|}]

module type t4 = t with module type x := sig type t end
[%%expect {|
module type t4 = sig module M : sig type t end end
|}]

(** nested *)

module type ENDO = sig
  module Inner:
  sig
    module type T
    module F: T -> T
  end
end
module type ENDO_2 = ENDO with module type Inner.T = ENDO
module type ENDO_2' = ENDO with module type Inner.T := ENDO
[%%expect {|
module type ENDO =
  sig module Inner : sig module type T module F : T -> T end end
module type ENDO_2 =
  sig module Inner : sig module type T = ENDO module F : T -> T end end
module type ENDO_2' = sig module Inner : sig module F : ENDO -> ENDO end end
|}]


module type S = sig
  module M: sig
    module type T
  end
  module N: M.T
end
module type R = S with module type M.T := sig end
[%%expect {|
module type S = sig module M : sig module type T end module N : M.T end
module type R = sig module M : sig end module N : sig end end
|}]


(** Adding equalities *)

module type base = sig type t = X of int | Y of float end

module type u = sig
  module type t = sig type t = X of int | Y of float end
  module M: t
end

module type s = u with module type t := base
[%%expect {|
module type base = sig type t = X of int | Y of float end
module type u =
  sig module type t = sig type t = X of int | Y of float end module M : t end
module type s = sig module M : base end
|}]


module type base = sig type t = X of int | Y of float end

module type u = sig
  type x
  type y
  module type t = sig type t = X of x | Y of y end
  module M: t
end

module type r =
  u with type x = int
     and type y = float
     and module type t = base
[%%expect {|
module type base = sig type t = X of int | Y of float end
module type u =
  sig
    type x
    type y
    module type t = sig type t = X of x | Y of y end
    module M : t
  end
module type r =
  sig type x = int type y = float module type t = base module M : t end
|}]

module type r =
  u with type x = int
     and type y = float
     and module type t := base
[%%expect {|
module type r = sig type x = int type y = float module M : base end
|}]


module type r =
  u with type x := int
     and type y := float
     and module type t := base
[%%expect {|
module type r = sig module M : base end
|}]

(** error *)

module type r =
  u with module type t := base

[%%expect {|
Line 4, characters 2-30:
4 |   u with module type t := base
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: In this `with' constraint, the new definition of t
       does not match its original definition in the constrained signature:
       At position module type t = <here>
       Module types do not match:
         sig type t = X of x | Y of y end
       is not equal to
         base
       At position module type t = <here>
       Type declarations do not match:
         type t = X of x | Y of y
       is not included in
         type t = X of int | Y of float
       1. Constructors do not match:
         X of x
       is not the same as:
         X of int
       The type x is not equal to the type int
       2. Constructors do not match:
         Y of y
       is not the same as:
         Y of float
       The type y is not equal to the type float
|}]

(** First class module types require an identity *)

module type fst = sig
  module type t
  val x: (module t)
end

module type ext
module type fst_ext = fst with module type t = ext
module type fst_ext = fst with module type t := ext
[%%expect {|
module type fst = sig module type t val x : (module t) end
module type ext
module type fst_ext = sig module type t = ext val x : (module t) end
module type fst_ext = sig val x : (module ext) end
|}]



module type fst_erased = fst with module type t := sig end
[%%expect {|
Line 1, characters 25-58:
1 | module type fst_erased = fst with module type t := sig end
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This `with' constraint t := sig end makes a packed module ill-formed.
|}]

module type fst_ok = fst with module type t = sig end
[%%expect {|
module type fst_ok = sig module type t = sig end val x : (module t) end
|}]

module type S = sig
  module M: sig
    module type T
  end
  val x: (module M.T)
end

module type R = S with module type M.T := sig end
[%%expect {|
module type S = sig module M : sig module type T end val x : (module M.T) end
Line 8, characters 16-49:
8 | module type R = S with module type M.T := sig end
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This `with' constraint M.T := sig end
       makes a packed module ill-formed.
|}]


module type S = sig
  module M: sig
    module type T
    val x: (module T)
  end
end

module type R = S with module type M.T := sig end
[%%expect {|
module type S = sig module M : sig module type T val x : (module T) end end
Line 8, characters 16-49:
8 | module type R = S with module type M.T := sig end
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This `with' constraint T := sig end makes a packed module ill-formed.
|}]


(** local module type substitutions *)

module type s = sig
  module type u := sig type a type b type c end
  module type r = sig type r include u end
  module type s = sig include u type a = A end
end
[%%expect {|
module type s =
  sig
    module type r = sig type r type a type b type c end
    module type s = sig type b type c type a = A end
  end
|}]


module type s = sig
  module type u := sig type a type b type c end
  module type wrong = sig type a include u end
end
[%%expect {|
Line 3, characters 33-42:
3 |   module type wrong = sig type a include u end
                                     ^^^^^^^^^
Error: Multiple definition of the type name a.
       Names must be unique in a given structure or signature.
|}]

module type fst = sig
  module type t := sig end
  val x: (module t)
end
[%%expect {|
Line 3, characters 2-19:
3 |   val x: (module t)
      ^^^^^^^^^^^^^^^^^
Error: The module type t is not a valid type for a packed module:
       it is defined as a local substitution for a non-path module type.
|}]


module type hidden = sig
  module type t := sig type u end
  include t
  val x: (module t)
  val x: int
end
[%%expect {|
module type hidden = sig type u val x : int end
|}]