this repo has no description
1Resolution
2==========
3
4Resolution is the process by which we take a value of type `Lang.t` and
5look up details of the internal cross references and make sure we know exactly
6which component is being referred to. Much of the work has been done by the
7compiler but we need to do a little more. For example, given
8
9```
10module M : sig
11 type t
12end
13type u = M.t
14```
15
16in the definition of `u`, the compiler tells us precisely which `M` is on the
17right hand side but doesn't say to which `t` it is referring to; the representation
18of this is simply the string "t". Resolution is the process of finding precise
19identifiers that will allow us to construct links.
20
21We'll start with a little preamble, constructing the execution environment in which we can
22run through some tests and describe the resolution process.
23
24```ocaml env=e1
25(* Prelude *)
26#require "odoc.xref_test";;
27open Odoc_xref2;;
28open Odoc_xref_test;;
29open Odoc_model.Names;;
30#install_printer Common.root_pp;;
31#install_printer Odoc_model.Names.ValueName.fmt;;
32#install_printer Odoc_model.Names.ModuleName.fmt;;
33#install_printer Odoc_model.Names.ModuleTypeName.fmt;;
34#install_printer Odoc_model.Names.TypeName.fmt;;
35#install_printer Odoc_model.Names.ExceptionName.fmt;;
36#install_printer Odoc_model.Names.FieldName.fmt;;
37#install_printer Odoc_model.Names.PageName.fmt;;
38#print_length 65536;;
39Odoc_xref2.Component.Delayed.eager := true;;
40Odoc_xref2.Tools.disable_all_caches ();;
41let id = Common.id;;
42let _ = Odoc_model.Names.set_unique_ident "XXXX";;
43```
44
45Simple resolution
46-----------------
47
48We'll start by examining the simple case - how we deal with module hierarchies,
49and build up later to the more advanced uses of the module system.
50
51### No modules at all
52
53The simplest possible resolution it simply checking that a resolved path exists.
54We'll use a helper function `Common.signature_of_mli_string` to go straight from
55a text representation of an mli file to the type we would ordinarily read from a
56compiled cmti file.
57
58```ocaml env=e1
59let test_data = {|
60 type x
61 type u = x
62|};;
63let sg = Common.signature_of_mli_string test_data;;
64```
65
66The type of `sg` is:
67
68```ocaml env=e1
69# #show_val sg;;
70val sg : Odoc_model.Lang.Signature.t
71```
72
73This `Signature.t` is a representation of the entire cmti file, and resolution
74essentially proceeds as map function over this data type: `Signature.t -> Signature.t`,
75with the end result having precise identifiers for all elements in the signature.
76
77The first thing we do is to construct an environment from the signature. The
78environment is simply a mapping from identifiers to items representing
79each element in the signature. The representations are types declared in the
80module `Component`, and follow quite closely those in module `Lang`, the main
81difference being in the types of paths. The environment constructed from the above
82signature is as follows:
83
84```ocaml env=e1
85# Env.open_signature sg Env.empty;;
86- : Env.t = <abstr>
87```
88
89here we can see there are two types in the environment and nothing else. `u` has identifier
90`` `Type (`Root (Common.root, "Root"), "u") ``, and has an internal identifier of `("u",17)`. `t` is
91abstract and therefore has
92no `manifest`, but `u` has a manifest that points to the `` `Identifier `` path that
93has already been `` `Resolved `` to `` `Identifier `` `` `Type (`Root (Common.root, "Root"), "u") ``. So there won't be much
94for us to do.
95
96The resolution process proceeds starting from the `Lang.Signature.t` going down until it finds
97values that are subtypes of `Path.t` - for example, a `Module.decl` is defined as
98
99```
100type decl =
101 | Alias of Path.Module.t
102 | ModuleType of ModuleType.expr
103```
104
105This type `Path.Module.t` is a polymorphic variant:
106
107```
108type any = [
109 | `Resolved of Resolved_path.module_
110 | `Root of string
111 | `Forward of string
112 | `Dot of module_ * string
113 | `Apply of module_ * module_
114]
115```
116
117and `Resolved_path.module_` is:
118
119```
120type module_ = [
121 | `Identifier of Identifier.path_module
122 | `Subst of module_type * module_
123 | `Alias of module_ * module_
124 | `Hidden of module_
125 | `Module of module_ * ModuleName.t
126 | `Canonical of module_ * Path.module_
127 | `Apply of module_ * Path.module_
128 | `Alias of module_ * module_
129 ]
130```
131
132Once it gets to a `Path.t` (or a `Path.Module.t`, `Path.Type.t` etc.), and looks down the path to
133find the element. The aim is to have every path start with `` `Resolved ``.
134
135In our example above, the first instance of a `Path.t` is the right hand side of the type `u`. For
136the purposes of examining that value, we can define a `Lens` that extracts just that out of the
137`Signature.t`:
138
139```ocaml env=e1
140let type_manifest name =
141 let open Common.LangUtils.Lens in
142 Signature.type_ name |-- TypeDecl.equation |-- TypeDecl.Equation.manifest
143let u_manifest = type_manifest "u"
144let t_manifest = type_manifest "t"
145let s_manifest = type_manifest "s"
146```
147
148and using this lens on our original signature we obtain:
149
150```ocaml env=e1
151# Common.LangUtils.Lens.get u_manifest sg ;;
152- : Odoc_model.Lang.TypeExpr.t option =
153Some
154 (Odoc_model.Lang.TypeExpr.Constr
155 (`Identifier
156 ({Odoc_model__Paths_types.iv =
157 `Type
158 ({Odoc_model__Paths_types.iv =
159 `Root
160 (Some
161 {Odoc_model__Paths_types.iv = `Page (None, None);
162 ihash = 236059787; ikey = "p_None"},
163 Root);
164 ihash = 818126955; ikey = "r_Root.p_None"},
165 x);
166 ihash = 622581103; ikey = "t_x.r_Root.p_None"},
167 false),
168 []))
169```
170
171This path clearly already begins with `` `Resolved ``, so we don't expect to change it,
172but we _are_ going to check it exists. We convert the path into a `Cpath.t` and call
173`Tools.resolve_type`. This function starts approximately:
174
175```
176 | `Resolved r as unresolved ->
177 of_result ~unresolved (lookup_type env r) >>=
178 fun t -> return (r, t)
179```
180
181and `lookup_type` starts:
182
183```
184
185 | `Identifier (`Type _ as i) ->
186 of_option ~error:(`Lookup_failure i) (Env.lookup_type i env)
187 >>= fun t -> Ok (Find.Found (`T t))
188```
189
190and so we simply look up the type in the environment, giving a `Component.Type.t` that represents the type.
191
192```ocaml env=e1
193# Common.compile_signature sg;;
194- : Odoc_model.Lang.Signature.t =
195{Odoc_model.Lang.Signature.items =
196 [Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
197 {Odoc_model.Lang.TypeDecl.id =
198 {Odoc_model__Paths_types.iv =
199 `Type
200 ({Odoc_model__Paths_types.iv =
201 `Root
202 (Some
203 {Odoc_model__Paths_types.iv = `Page (None, None);
204 ihash = 236059787; ikey = "p_None"},
205 Root);
206 ihash = 818126955; ikey = "r_Root.p_None"},
207 x);
208 ihash = 622581103; ikey = "t_x.r_Root.p_None"};
209 source_loc = None;
210 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
211 canonical = None;
212 equation =
213 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
214 manifest = None; constraints = []};
215 representation = None});
216 Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
217 {Odoc_model.Lang.TypeDecl.id =
218 {Odoc_model__Paths_types.iv =
219 `Type
220 ({Odoc_model__Paths_types.iv =
221 `Root
222 (Some
223 {Odoc_model__Paths_types.iv = `Page (None, None);
224 ihash = 236059787; ikey = "p_None"},
225 Root);
226 ihash = 818126955; ikey = "r_Root.p_None"},
227 u);
228 ihash = 15973539; ikey = "t_u.r_Root.p_None"};
229 source_loc = None;
230 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
231 canonical = None;
232 equation =
233 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
234 manifest =
235 Some
236 (Odoc_model.Lang.TypeExpr.Constr
237 (`Resolved
238 (`Identifier
239 {Odoc_model__Paths_types.iv =
240 `Type
241 ({Odoc_model__Paths_types.iv =
242 `Root
243 (Some
244 {Odoc_model__Paths_types.iv = `Page (None, None);
245 ihash = 236059787; ikey = "p_None"},
246 Root);
247 ihash = 818126955; ikey = "r_Root.p_None"},
248 x);
249 ihash = 622581103; ikey = "t_x.r_Root.p_None"}),
250 []));
251 constraints = []};
252 representation = None})];
253 compiled = true; removed = [];
254 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
255```
256
257### One module
258
259Now let's look at a marginally more complicated example. In this case, our type [t] is now
260inside a module:
261
262```ocaml env=e1
263let test_data = {|
264module M : sig
265 type t
266end
267type u = M.t
268|};;
269let sg = Common.signature_of_mli_string test_data;;
270let env = Env.open_signature sg Env.empty;;
271```
272
273The OCaml compiler find the module `M` exactly, but everything after that is left to us
274to identify precisely. So the manifest of `u` is now:
275
276```ocaml env=e1
277# Common.LangUtils.Lens.get u_manifest sg ;;
278- : Odoc_model.Lang.TypeExpr.t option =
279Some
280 (Odoc_model.Lang.TypeExpr.Constr
281 (`DotT
282 (`Identifier
283 ({Odoc_model__Paths_types.iv =
284 `Module
285 ({Odoc_model__Paths_types.iv =
286 `Root
287 (Some
288 {Odoc_model__Paths_types.iv = `Page (None, None);
289 ihash = 236059787; ikey = "p_None"},
290 Root);
291 ihash = 818126955; ikey = "r_Root.p_None"},
292 M);
293 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
294 false),
295 t),
296 []))
297```
298
299Here we can see that the path is not completely resolved. The `M` bit is resolved, but the `t`
300bit is not. So we have to do a bit more work when we look up the type in
301`Tools.resolve_type`.
302
303Let's look in more detail at that process. The first thing that happens is that the path is matched
304the [`Dot] is found:
305
306```
307 | `Dot (parent, id) ->
308 resolve_module env parent
309 >>= fun (p, m) ->
310```
311
312This implies that the thing before the dot is a module, so we call
313`Tools.resolve_module`. This is a resolved identifier so we can simply look this up from
314the environment. This gets us back the path and a `Component.Module.t` representing the module M,
315which are:
316
317```ocaml env=e1
318# let get_ok = function
319 | Ok x -> x
320 | Error _ -> failwith "Found error";;
321val get_ok : ('a, 'b) result -> 'a = <fun>
322# let (path, module_) = get_ok @@ Tools.resolve_module env (`Resolved (`Gpath (`Identifier (Common.root_module "M"))));;
323val path : Cpath.Resolved.module_ =
324 `Gpath
325 (`Identifier
326 {Odoc_model__Paths_types.iv =
327 `Module
328 ({Odoc_model__Paths_types.iv =
329 `Root
330 (Some
331 {Odoc_model__Paths_types.iv = `Page (None, None);
332 ihash = 236059787; ikey = "p_None"},
333 Root);
334 ihash = 818126955; ikey = "r_Root.p_None"},
335 M);
336 ihash = 716453475; ikey = "m_M.r_Root.p_None"})
337val module_ : Component.Module.t Component.Delayed.t =
338 {Odoc_xref2.Component.Delayed.v =
339 Some
340 {Odoc_xref2.Component.Module.source_loc = None;
341 doc =
342 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
343 type_ =
344 Odoc_xref2.Component.Module.ModuleType
345 (Odoc_xref2.Component.ModuleType.Signature
346 {Odoc_xref2.Component.Signature.items =
347 [Odoc_xref2.Component.Signature.Type (`LType (t, 0),
348 Odoc_model.Lang.Signature.Ordinary,
349 {Odoc_xref2.Component.Delayed.v =
350 Some
351 {Odoc_xref2.Component.TypeDecl.source_loc = None;
352 doc =
353 {Odoc_xref2.Component.CComment.elements = [];
354 warnings_tag = None};
355 canonical = None;
356 equation =
357 {Odoc_xref2.Component.TypeDecl.Equation.params = [];
358 private_ = false; manifest = None; constraints = []};
359 representation = None};
360 get = None})];
361 compiled = false; removed = [];
362 doc =
363 {Odoc_xref2.Component.CComment.elements = [];
364 warnings_tag = None}});
365 canonical = None; hidden = false};
366 get = None}
367```
368
369The values returned are the resolved path to the module, and a representation of the module itself. We then turn the module into a signature via `expansion_of_module`, which in this case is quite simple since the module contains an explicit signature:
370
371```ocaml env=e1
372# get_ok @@ Tools.expansion_of_module env (Component.Delayed.get module_);;
373- : Tools.expansion =
374Odoc_xref2.Tools.Signature
375 {Odoc_xref2.Component.Signature.items =
376 [Odoc_xref2.Component.Signature.Type (`LType (t, 0),
377 Odoc_model.Lang.Signature.Ordinary,
378 {Odoc_xref2.Component.Delayed.v =
379 Some
380 {Odoc_xref2.Component.TypeDecl.source_loc = None;
381 doc =
382 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
383 canonical = None;
384 equation =
385 {Odoc_xref2.Component.TypeDecl.Equation.params = [];
386 private_ = false; manifest = None; constraints = []};
387 representation = None};
388 get = None})];
389 compiled = false; removed = [];
390 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
391```
392
393We're now in a position to verify the existence of the type `t` we're
394looking up - and indeed it is there. We therefore construct the
395new resolved path to this type : `` `Type (path, "t") ``, and return
396this and the definition of the type, which in this case is
397uninteresting.
398
399### Indirection
400
401Let's now examine the case when a module's signature has to be found
402from the environment.
403
404```ocaml env=e1
405let test_data = {|
406module type M = sig
407 type t
408end
409module N : M
410type u = N.t
411|};;
412let sg = Common.signature_of_mli_string test_data;;
413let env = Env.open_signature sg Env.empty;;
414```
415
416It proceeds much as the previous example until we get the result
417of looking up the module `N`:
418
419```ocaml env=e1
420# let (path, module_) = get_ok @@ Tools.resolve_module env (`Resolved (`Gpath (`Identifier (Common.root_module "N"))));;
421val path : Cpath.Resolved.module_ =
422 `Gpath
423 (`Identifier
424 {Odoc_model__Paths_types.iv =
425 `Module
426 ({Odoc_model__Paths_types.iv =
427 `Root
428 (Some
429 {Odoc_model__Paths_types.iv = `Page (None, None);
430 ihash = 236059787; ikey = "p_None"},
431 Root);
432 ihash = 818126955; ikey = "r_Root.p_None"},
433 N);
434 ihash = 502470005; ikey = "m_N.r_Root.p_None"})
435val module_ : Component.Module.t Component.Delayed.t =
436 {Odoc_xref2.Component.Delayed.v =
437 Some
438 {Odoc_xref2.Component.Module.source_loc = None;
439 doc =
440 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
441 type_ =
442 Odoc_xref2.Component.Module.ModuleType
443 (Odoc_xref2.Component.ModuleType.Path
444 {Odoc_xref2.Component.ModuleType.p_expansion = None;
445 p_path =
446 `Identifier
447 ({Odoc_model__Paths_types.iv =
448 `ModuleType
449 ({Odoc_model__Paths_types.iv =
450 `Root
451 (Some
452 {Odoc_model__Paths_types.iv = `Page (None, None);
453 ihash = 236059787; ikey = "p_None"},
454 Root);
455 ihash = 818126955; ikey = "r_Root.p_None"},
456 M);
457 ihash = 459143770; ikey = "mt_M.r_Root.p_None"},
458 false)});
459 canonical = None; hidden = false};
460 get = None}
461```
462
463This time turning the module into a signature demonstrates why the function `expansion_of_module` requires the environment. We need to lookup the module type `M` from the environment to determine the
464signature of the module. After this though the resolution is as before.
465
466### Local paths
467
468We now look at an example involving local paths. These paths happen
469when a path refers to something that isn't in the toplevel environment. We'll use the following example to explain the idea:
470
471```ocaml env=e1
472let test_data = {|
473module type M = sig
474 module type N = sig
475 type t
476 end
477 module B : N
478end
479module A : M
480type u = A.B.t
481|};;
482let sg = Common.signature_of_mli_string test_data;;
483let env = Env.open_signature sg Env.empty;;
484```
485
486The definition of module `B` constrains it to have a signature given
487by the module type `N`. However, `N` is not defined at the top level
488here, so it has a local identifier. We can see this by looking up module `M` from the environment:
489
490```ocaml env=e1
491# let m = Env.(lookup_by_id s_module_type) (Odoc_model.Paths.Identifier.Mk.module_type (Common.id, Odoc_model.Names.ModuleTypeName.make_std "M")) env;;
492val m : Component.Element.module_type option =
493 Some
494 (`ModuleType
495 ({Odoc_model__Paths_types.iv =
496 `ModuleType
497 ({Odoc_model__Paths_types.iv =
498 `Root
499 (Some
500 {Odoc_model__Paths_types.iv = `Page (None, None);
501 ihash = 236059787; ikey = "p_None"},
502 Root);
503 ihash = 818126955; ikey = "r_Root.p_None"},
504 M);
505 ihash = 459143770; ikey = "mt_M.r_Root.p_None"},
506 {Odoc_xref2.Component.ModuleType.source_loc = None;
507 doc =
508 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
509 canonical = None;
510 expr =
511 Some
512 (Odoc_xref2.Component.ModuleType.Signature
513 {Odoc_xref2.Component.Signature.items =
514 [Odoc_xref2.Component.Signature.ModuleType
515 (`LModuleType (N, 1),
516 {Odoc_xref2.Component.Delayed.v =
517 Some
518 {Odoc_xref2.Component.ModuleType.source_loc = None;
519 doc =
520 {Odoc_xref2.Component.CComment.elements = [];
521 warnings_tag = None};
522 canonical = None;
523 expr =
524 Some
525 (Odoc_xref2.Component.ModuleType.Signature
526 {Odoc_xref2.Component.Signature.items =
527 [Odoc_xref2.Component.Signature.Type
528 (`LType (t, 2),
529 Odoc_model.Lang.Signature.Ordinary,
530 {Odoc_xref2.Component.Delayed.v =
531 Some
532 {Odoc_xref2.Component.TypeDecl.source_loc =
533 None;
534 doc =
535 {Odoc_xref2.Component.CComment.elements = [];
536 warnings_tag = None};
537 canonical = None;
538 equation =
539 {Odoc_xref2.Component.TypeDecl.Equation.params
540 = [];
541 private_ = false; manifest = None;
542 constraints = []};
543 representation = None};
544 get = None})];
545 compiled = false; removed = [];
546 doc =
547 {Odoc_xref2.Component.CComment.elements = [];
548 warnings_tag = None}})};
549 get = None});
550 Odoc_xref2.Component.Signature.Module (`LModule (B, 0),
551 Odoc_model.Lang.Signature.Ordinary,
552 {Odoc_xref2.Component.Delayed.v =
553 Some
554 {Odoc_xref2.Component.Module.source_loc = None;
555 doc =
556 {Odoc_xref2.Component.CComment.elements = [];
557 warnings_tag = None};
558 type_ =
559 Odoc_xref2.Component.Module.ModuleType
560 (Odoc_xref2.Component.ModuleType.Path
561 {Odoc_xref2.Component.ModuleType.p_expansion = None;
562 p_path = `Local (`LModuleType (N, 1), false)});
563 canonical = None; hidden = false};
564 get = None})];
565 compiled = false; removed = [];
566 doc =
567 {Odoc_xref2.Component.CComment.elements = [];
568 warnings_tag = None}})}))
569```
570
571We can see here that module `B` has type `` Path (`Resolved (`Local (`LModuleType (N, 1)))) `` which refers to the module type defined just above it.
572
573To look up we need to have fully qualified paths for all items so this needs some work.
574The way this is handled is that when we want to look up an element within a module,
575we don't just convert it blindly to a signature. Since we have the fully qualified
576path to the module, we prefix all the identifiers bound in that signature
577with that path to turn them into global identifiers.
578
579Concretely, we start here wanting to resolve the path for type `u`,
580which is `A.B.t`. The compiler has started us off by resolving the
581`A`:
582
583```ocaml env=e1
584# Common.LangUtils.Lens.get u_manifest sg ;;
585- : Odoc_model.Lang.TypeExpr.t option =
586Some
587 (Odoc_model.Lang.TypeExpr.Constr
588 (`DotT
589 (`Dot
590 (`Identifier
591 ({Odoc_model__Paths_types.iv =
592 `Module
593 ({Odoc_model__Paths_types.iv =
594 `Root
595 (Some
596 {Odoc_model__Paths_types.iv = `Page (None, None);
597 ihash = 236059787; ikey = "p_None"},
598 Root);
599 ihash = 818126955; ikey = "r_Root.p_None"},
600 A);
601 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
602 false),
603 B),
604 t),
605 []))
606```
607
608we look up `A` from the environment:
609
610```ocaml env=e1
611# let p = `Gpath (`Identifier (Common.root_module "A")) in
612 let m = get_ok @@ Tools.lookup_module env p in
613 let sg = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m) in
614 Tools.prefix_signature (`Module p, sg);;
615Line 4, characters 38-40:
616Error: The value sg has type Tools.expansion
617 but an expression was expected of type Component.Signature.t
618```
619
620So before the prefixing operation we had that the type of the module was
621
622```ocaml skip
623 type_ =
624 Odoc_xref2.Component.Module.ModuleType
625 (Odoc_xref2.Component.ModuleType.Path
626 (`Resolved (`Local (`LModuleType (N, 1)))));
627```
628
629and afterwards it is
630
631```ocaml skip
632 type_ =
633 Odoc_xref2.Component.Module.ModuleType
634 (Odoc_xref2.Component.ModuleType.Path
635 (`Resolved
636 (`ModuleType
637 (`Module
638 (`Identifier (`Module (`Root (Common.root, Root), A))),
639 N))));
640```
641
642We now look up module `B` from this signature, which once again
643we need to convert to a signature to find `t`. We find the type above,
644which we can then convert in turn into a signature. Once again,
645we go down the path until we find the identifier (`A` in this case), look that up from the environment, then look up the module type `N`.
646We can then turn this into the signature for `B`, prefixing local
647paths with the resolved path `A.B` (though in this case there are
648now no local identifiers.) Finally we can now look up `t`, which
649we then return along with the fully resolved identifier.
650
651```ocaml env=e1
652# fst @@ get_ok @@ Tools.resolve_type env
653 (`DotT
654 (`Dot
655 (`Resolved
656 (`Gpath (`Identifier (Common.root_module "A"))),
657 ModuleName.make_std "B"),
658 TypeName.make_std "t"));;
659- : Cpath.Resolved.type_ =
660`Type
661 (`Module
662 (`Module
663 (`Module
664 (`Gpath
665 (`Identifier
666 {Odoc_model__Paths_types.iv =
667 `Module
668 ({Odoc_model__Paths_types.iv =
669 `Root
670 (Some
671 {Odoc_model__Paths_types.iv = `Page (None, None);
672 ihash = 236059787; ikey = "p_None"},
673 Root);
674 ihash = 818126955; ikey = "r_Root.p_None"},
675 A);
676 ihash = 353272258; ikey = "m_A.r_Root.p_None"})),
677 B)),
678 t)
679```
680
681### Module aliases
682
683```ocaml env=e1
684let test_data = {|
685module A : sig
686 module M : sig type t end
687 module N = M
688end
689
690type t = A.N.t
691|}
692let sg = Common.signature_of_mli_string test_data;;
693let resolved = Common.compile_signature sg;;
694```
695
696Let's look at `t`'s manifest:
697
698```ocaml env=e1
699# Common.LangUtils.Lens.get t_manifest resolved ;;
700- : Odoc_model.Lang.TypeExpr.t option =
701Some
702 (Odoc_model.Lang.TypeExpr.Constr
703 (`Resolved
704 (`Type
705 (`Alias
706 (`Module
707 (`Identifier
708 {Odoc_model__Paths_types.iv =
709 `Module
710 ({Odoc_model__Paths_types.iv =
711 `Root
712 (Some
713 {Odoc_model__Paths_types.iv = `Page (None, None);
714 ihash = 236059787; ikey = "p_None"},
715 Root);
716 ihash = 818126955; ikey = "r_Root.p_None"},
717 A);
718 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
719 M),
720 `Dot
721 (`Identifier
722 ({Odoc_model__Paths_types.iv =
723 `Module
724 ({Odoc_model__Paths_types.iv =
725 `Root
726 (Some
727 {Odoc_model__Paths_types.iv =
728 `Page (None, None);
729 ihash = 236059787; ikey = "p_None"},
730 Root);
731 ihash = 818126955; ikey = "r_Root.p_None"},
732 A);
733 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
734 false),
735 N)),
736 t)),
737 []))
738```
739
740When we turn `A.N.t` into a link, we need to render `A.N.t` as the link text
741(going down the right-hand side of the `Alias` constructor), but link to
742`A.M.t` since `A.N` will not have an expansion.
743
744```ocaml env=e1
745let test_data = {|
746module A : sig
747 module M : sig type t end
748 module N = M
749 module O = N
750end
751
752type t = A.O.t
753|}
754let sg = Common.signature_of_mli_string test_data;;
755let resolved = Common.compile_signature sg;;
756```
757
758```ocaml env=e1
759# Common.LangUtils.Lens.get t_manifest resolved ;;
760- : Odoc_model.Lang.TypeExpr.t option =
761Some
762 (Odoc_model.Lang.TypeExpr.Constr
763 (`Resolved
764 (`Type
765 (`Alias
766 (`Alias
767 (`Module
768 (`Identifier
769 {Odoc_model__Paths_types.iv =
770 `Module
771 ({Odoc_model__Paths_types.iv =
772 `Root
773 (Some
774 {Odoc_model__Paths_types.iv =
775 `Page (None, None);
776 ihash = 236059787; ikey = "p_None"},
777 Root);
778 ihash = 818126955; ikey = "r_Root.p_None"},
779 A);
780 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
781 M),
782 `Dot
783 (`Identifier
784 ({Odoc_model__Paths_types.iv =
785 `Module
786 ({Odoc_model__Paths_types.iv =
787 `Root
788 (Some
789 {Odoc_model__Paths_types.iv =
790 `Page (None, None);
791 ihash = 236059787; ikey = "p_None"},
792 Root);
793 ihash = 818126955; ikey = "r_Root.p_None"},
794 A);
795 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
796 false),
797 N)),
798 `Dot
799 (`Identifier
800 ({Odoc_model__Paths_types.iv =
801 `Module
802 ({Odoc_model__Paths_types.iv =
803 `Root
804 (Some
805 {Odoc_model__Paths_types.iv =
806 `Page (None, None);
807 ihash = 236059787; ikey = "p_None"},
808 Root);
809 ihash = 818126955; ikey = "r_Root.p_None"},
810 A);
811 ihash = 353272258; ikey = "m_A.r_Root.p_None"},
812 false),
813 O)),
814 t)),
815 []))
816```
817
818
819### Module substitution
820
821We'll now look at a case where we perform a module substitution
822on a signature.
823
824In the following example we have an interesting case where we
825have a module with a module type in it, and we make a substitution
826of this module.
827
828```ocaml env=e1
829let test_data = {|
830module type A = sig
831module M : sig module type S end
832module N : M.S
833end
834
835module B : sig module type S = sig type t end end
836
837module C : A with module M = B
838
839type t = C.N.t
840|};;
841let sg = Common.signature_of_mli_string test_data;;
842let resolved = Common.compile_signature sg;;
843let env = Env.open_signature sg Env.empty;;
844```
845
846So in module type `A`, module `N` has type `M.S`, which
847does not contain a declaration for type `t`.
848When we make the substitution, although we're substituting `M`,
849because the signature of `N` is `M.S`, we _also_ change `N`. So
850in module `C`, `N` should now contain a type `t`.
851
852Once again, we look at the resolution of `type t = C.N.t`. When
853we look up the module C we find that the `type_` field look as
854follows:
855
856```ocaml env=e1
857# let module_C_lens =
858 let open Common.LangUtils.Lens in
859 Signature.module_ "C";;
860val module_C_lens :
861 (Odoc_model.Lang.Signature.t, Odoc_model.Lang.Module.t)
862 Common.LangUtils.Lens.lens =
863 {Odoc_xref_test.Common.LangUtils.Lens.get = <fun>; set = <fun>}
864# Common.LangUtils.Lens.get module_C_lens sg;;
865- : Odoc_model.Lang.Module.t =
866{Odoc_model.Lang.Module.id =
867 {Odoc_model__Paths_types.iv =
868 `Module
869 ({Odoc_model__Paths_types.iv =
870 `Root
871 (Some
872 {Odoc_model__Paths_types.iv = `Page (None, None);
873 ihash = 236059787; ikey = "p_None"},
874 Root);
875 ihash = 818126955; ikey = "r_Root.p_None"},
876 C);
877 ihash = 43786577; ikey = "m_C.r_Root.p_None"};
878 source_loc = None;
879 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
880 type_ =
881 Odoc_model.Lang.Module.ModuleType
882 (Odoc_model.Lang.ModuleType.With
883 {Odoc_model.Lang.ModuleType.w_substitutions =
884 [Odoc_model.Lang.ModuleType.ModuleEq (`Dot (`Root, "M"),
885 Odoc_model.Lang.Module.Alias
886 (`Identifier
887 ({Odoc_model__Paths_types.iv =
888 `Module
889 ({Odoc_model__Paths_types.iv =
890 `Root
891 (Some
892 {Odoc_model__Paths_types.iv = `Page (None, None);
893 ihash = 236059787; ikey = "p_None"},
894 Root);
895 ihash = 818126955; ikey = "r_Root.p_None"},
896 B);
897 ihash = 814134997; ikey = "m_B.r_Root.p_None"},
898 false),
899 None))];
900 w_expansion = None;
901 w_expr =
902 Odoc_model.Lang.ModuleType.U.Path
903 (`Identifier
904 ({Odoc_model__Paths_types.iv =
905 `ModuleType
906 ({Odoc_model__Paths_types.iv =
907 `Root
908 (Some
909 {Odoc_model__Paths_types.iv = `Page (None, None);
910 ihash = 236059787; ikey = "p_None"},
911 Root);
912 ihash = 818126955; ikey = "r_Root.p_None"},
913 A);
914 ihash = 231492881; ikey = "mt_A.r_Root.p_None"},
915 false))});
916 canonical = None; hidden = false}
917```
918
919Clearly there is no `type t` declared in here. Let's get the representation
920of module `C` we see the following:
921
922```ocaml env=e1
923# let m = get_ok @@ Tools.lookup_module env (`Gpath (`Identifier (Common.root_module "C")));;
924val m : Component.Module.t Component.Delayed.t =
925 {Odoc_xref2.Component.Delayed.v =
926 Some
927 {Odoc_xref2.Component.Module.source_loc = None;
928 doc =
929 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
930 type_ =
931 Odoc_xref2.Component.Module.ModuleType
932 (Odoc_xref2.Component.ModuleType.With
933 {Odoc_xref2.Component.ModuleType.w_substitutions =
934 [Odoc_xref2.Component.ModuleType.ModuleEq (`Dot (`Root, "M"),
935 Odoc_xref2.Component.Module.Alias
936 (`Identifier
937 ({Odoc_model__Paths_types.iv =
938 `Module
939 ({Odoc_model__Paths_types.iv =
940 `Root
941 (Some
942 {Odoc_model__Paths_types.iv =
943 `Page (None, None);
944 ihash = 236059787; ikey = "p_None"},
945 Root);
946 ihash = 818126955; ikey = "r_Root.p_None"},
947 B);
948 ihash = 814134997; ikey = "m_B.r_Root.p_None"},
949 false),
950 None))];
951 w_expansion = None;
952 w_expr =
953 Odoc_xref2.Component.ModuleType.U.Path
954 (`Identifier
955 ({Odoc_model__Paths_types.iv =
956 `ModuleType
957 ({Odoc_model__Paths_types.iv =
958 `Root
959 (Some
960 {Odoc_model__Paths_types.iv = `Page (None, None);
961 ihash = 236059787; ikey = "p_None"},
962 Root);
963 ihash = 818126955; ikey = "r_Root.p_None"},
964 A);
965 ihash = 231492881; ikey = "mt_A.r_Root.p_None"},
966 false))});
967 canonical = None; hidden = false};
968 get = None}
969```
970
971now we can ask for the signature of this module:
972
973```ocaml env=e1
974# let sg = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
975val sg : Tools.expansion =
976 Odoc_xref2.Tools.Signature
977 {Odoc_xref2.Component.Signature.items =
978 [Odoc_xref2.Component.Signature.Module (`LModule (M, 31),
979 Odoc_model.Lang.Signature.Ordinary,
980 {Odoc_xref2.Component.Delayed.v =
981 Some
982 {Odoc_xref2.Component.Module.source_loc = None;
983 doc =
984 {Odoc_xref2.Component.CComment.elements = [];
985 warnings_tag = None};
986 type_ =
987 Odoc_xref2.Component.Module.Alias
988 (`Identifier
989 ({Odoc_model__Paths_types.iv =
990 `Module
991 ({Odoc_model__Paths_types.iv =
992 `Root
993 (Some
994 {Odoc_model__Paths_types.iv = `Page (None, None);
995 ihash = 236059787; ikey = "p_None"},
996 Root);
997 ihash = 818126955; ikey = "r_Root.p_None"},
998 B);
999 ihash = 814134997; ikey = "m_B.r_Root.p_None"},
1000 false),
1001 None);
1002 canonical = None; hidden = false};
1003 get = None});
1004 Odoc_xref2.Component.Signature.Module (`LModule (N, 32),
1005 Odoc_model.Lang.Signature.Ordinary,
1006 {Odoc_xref2.Component.Delayed.v =
1007 Some
1008 {Odoc_xref2.Component.Module.source_loc = None;
1009 doc =
1010 {Odoc_xref2.Component.CComment.elements = [];
1011 warnings_tag = None};
1012 type_ =
1013 Odoc_xref2.Component.Module.ModuleType
1014 (Odoc_xref2.Component.ModuleType.Path
1015 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1016 p_path =
1017 `DotMT (`Substituted (`Local (`LModule (M, 31), false)), S)});
1018 canonical = None; hidden = false};
1019 get = None})];
1020 compiled = false; removed = [];
1021 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1022```
1023
1024and we can see the module `M` is now an alias of the root module `B`. We can now
1025look up module `N` from within this and find its signature:
1026
1027```ocaml env=e1
1028# let m = get_ok @@ Tools.lookup_module env
1029 (`Module (`Module (`Gpath (`Identifier (Common.root_module "C"))), ModuleName.make_std "N"));;
1030val m : Component.Module.t Component.Delayed.t =
1031 {Odoc_xref2.Component.Delayed.v =
1032 Some
1033 {Odoc_xref2.Component.Module.source_loc = None;
1034 doc =
1035 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
1036 type_ =
1037 Odoc_xref2.Component.Module.ModuleType
1038 (Odoc_xref2.Component.ModuleType.Path
1039 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1040 p_path =
1041 `DotMT
1042 (`Substituted
1043 (`Module
1044 (`Module
1045 (`Gpath
1046 (`Identifier
1047 {Odoc_model__Paths_types.iv =
1048 `Module
1049 ({Odoc_model__Paths_types.iv =
1050 `Root
1051 (Some
1052 {Odoc_model__Paths_types.iv =
1053 `Page (None, None);
1054 ihash = 236059787; ikey = "p_None"},
1055 Root);
1056 ihash = 818126955; ikey = "r_Root.p_None"},
1057 C);
1058 ihash = 43786577; ikey = "m_C.r_Root.p_None"})),
1059 M)),
1060 S)});
1061 canonical = None; hidden = false};
1062 get = None}
1063# get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
1064- : Tools.expansion =
1065Odoc_xref2.Tools.Signature
1066 {Odoc_xref2.Component.Signature.items =
1067 [Odoc_xref2.Component.Signature.Type (`LType (t, 41),
1068 Odoc_model.Lang.Signature.Ordinary,
1069 {Odoc_xref2.Component.Delayed.v =
1070 Some
1071 {Odoc_xref2.Component.TypeDecl.source_loc = None;
1072 doc =
1073 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
1074 canonical = None;
1075 equation =
1076 {Odoc_xref2.Component.TypeDecl.Equation.params = [];
1077 private_ = false; manifest = None; constraints = []};
1078 representation = None};
1079 get = None})];
1080 compiled = false; removed = [];
1081 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1082```
1083
1084where we've correctly identified that a type `t` exists in the signature. The path in
1085type t is resolved as:
1086
1087```ocaml env=e1
1088# Common.LangUtils.Lens.get t_manifest resolved;;
1089- : Odoc_model.Lang.TypeExpr.t option =
1090Some
1091 (Odoc_model.Lang.TypeExpr.Constr
1092 (`Resolved
1093 (`Type
1094 (`Module
1095 (`Identifier
1096 {Odoc_model__Paths_types.iv =
1097 `Module
1098 ({Odoc_model__Paths_types.iv =
1099 `Root
1100 (Some
1101 {Odoc_model__Paths_types.iv = `Page (None, None);
1102 ihash = 236059787; ikey = "p_None"},
1103 Root);
1104 ihash = 818126955; ikey = "r_Root.p_None"},
1105 C);
1106 ihash = 43786577; ikey = "m_C.r_Root.p_None"},
1107 N),
1108 t)),
1109 []))
1110```
1111
1112### Interesting functor
1113
1114```ocaml env=e1
1115let test_data = {|
1116module M : sig
1117 module F(X : sig module type S end) : sig
1118 module type S = X.S
1119 module N : X.S
1120 end
1121 module T : sig
1122 module type S = sig type t end
1123 end
1124 module O : F(T).S
1125end
1126type t = M.O.t
1127type s = M.F(M.T).N.t
1128|};;
1129let sg = Common.signature_of_mli_string test_data;;
1130let t_manifest = type_manifest "t";;
1131let s_manifest = type_manifest "s";;
1132let resolved = Common.compile_signature sg;;
1133```
1134
1135The interesting thing here is the difference between `type t` and `type s`. The module `M.O` has
1136a concrete representation in the file and the expansion of this will contain a declaration of type
1137`t` - hence the path representing `M.O.t` does not need a `Subst` constructor in it. However, the
1138path to `M.F(M.T).N.t` can't point directly at a type within a module as there isn't one - in
1139some sense `F(M.T)` is making a brand new module on the fly without binding it anywhere, and the
1140type within this is not within the body of the functor itself.
1141
1142```ocaml env=e1
1143# Common.LangUtils.Lens.get (type_manifest "t") resolved;;
1144- : Odoc_model.Lang.TypeExpr.t option =
1145Some
1146 (Odoc_model.Lang.TypeExpr.Constr
1147 (`Resolved
1148 (`Type
1149 (`Subst
1150 (`AliasModuleType
1151 (`ModuleType
1152 (`Substituted
1153 (`Module
1154 (`Identifier
1155 {Odoc_model__Paths_types.iv =
1156 `Module
1157 ({Odoc_model__Paths_types.iv =
1158 `Root
1159 (Some
1160 {Odoc_model__Paths_types.iv =
1161 `Page (None, None);
1162 ihash = 236059787; ikey = "p_None"},
1163 Root);
1164 ihash = 818126955; ikey = "r_Root.p_None"},
1165 M);
1166 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1167 T)),
1168 S),
1169 `SubstT
1170 (`ModuleType
1171 (`Substituted
1172 (`Module
1173 (`Identifier
1174 {Odoc_model__Paths_types.iv =
1175 `Module
1176 ({Odoc_model__Paths_types.iv =
1177 `Root
1178 (Some
1179 {Odoc_model__Paths_types.iv =
1180 `Page (None, None);
1181 ihash = 236059787; ikey = "p_None"},
1182 Root);
1183 ihash = 818126955;
1184 ikey = "r_Root.p_None"},
1185 M);
1186 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1187 T)),
1188 S),
1189 `ModuleType
1190 (`Apply
1191 (`Module
1192 (`Identifier
1193 {Odoc_model__Paths_types.iv =
1194 `Module
1195 ({Odoc_model__Paths_types.iv =
1196 `Root
1197 (Some
1198 {Odoc_model__Paths_types.iv =
1199 `Page (None, None);
1200 ihash = 236059787; ikey = "p_None"},
1201 Root);
1202 ihash = 818126955;
1203 ikey = "r_Root.p_None"},
1204 M);
1205 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1206 F),
1207 `Module
1208 (`Identifier
1209 {Odoc_model__Paths_types.iv =
1210 `Module
1211 ({Odoc_model__Paths_types.iv =
1212 `Root
1213 (Some
1214 {Odoc_model__Paths_types.iv =
1215 `Page (None, None);
1216 ihash = 236059787; ikey = "p_None"},
1217 Root);
1218 ihash = 818126955;
1219 ikey = "r_Root.p_None"},
1220 M);
1221 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1222 T)),
1223 S))),
1224 `Module
1225 (`Identifier
1226 {Odoc_model__Paths_types.iv =
1227 `Module
1228 ({Odoc_model__Paths_types.iv =
1229 `Root
1230 (Some
1231 {Odoc_model__Paths_types.iv = `Page (None, None);
1232 ihash = 236059787; ikey = "p_None"},
1233 Root);
1234 ihash = 818126955; ikey = "r_Root.p_None"},
1235 M);
1236 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1237 O)),
1238 t)),
1239 []))
1240# Common.LangUtils.Lens.get (type_manifest "s") resolved;;
1241- : Odoc_model.Lang.TypeExpr.t option =
1242Some
1243 (Odoc_model.Lang.TypeExpr.Constr
1244 (`Resolved
1245 (`Type
1246 (`Subst
1247 (`ModuleType
1248 (`Substituted
1249 (`Module
1250 (`Identifier
1251 {Odoc_model__Paths_types.iv =
1252 `Module
1253 ({Odoc_model__Paths_types.iv =
1254 `Root
1255 (Some
1256 {Odoc_model__Paths_types.iv =
1257 `Page (None, None);
1258 ihash = 236059787; ikey = "p_None"},
1259 Root);
1260 ihash = 818126955; ikey = "r_Root.p_None"},
1261 M);
1262 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1263 T)),
1264 S),
1265 `Module
1266 (`Apply
1267 (`Module
1268 (`Identifier
1269 {Odoc_model__Paths_types.iv =
1270 `Module
1271 ({Odoc_model__Paths_types.iv =
1272 `Root
1273 (Some
1274 {Odoc_model__Paths_types.iv =
1275 `Page (None, None);
1276 ihash = 236059787; ikey = "p_None"},
1277 Root);
1278 ihash = 818126955; ikey = "r_Root.p_None"},
1279 M);
1280 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1281 F),
1282 `Module
1283 (`Identifier
1284 {Odoc_model__Paths_types.iv =
1285 `Module
1286 ({Odoc_model__Paths_types.iv =
1287 `Root
1288 (Some
1289 {Odoc_model__Paths_types.iv =
1290 `Page (None, None);
1291 ihash = 236059787; ikey = "p_None"},
1292 Root);
1293 ihash = 818126955; ikey = "r_Root.p_None"},
1294 M);
1295 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1296 T)),
1297 N)),
1298 t)),
1299 []))
1300```
1301
1302In the following example, `type t` does not require a `Subst` constructor since although the
1303pattern is the same as above -- that a new type `t` appears in module `O` despite not being
1304present in the definition of the functor -- because the module `O` is bound it will be expanded
1305in the expansion phase of odoc's work, and hence we can simply point right inside the module.
1306
1307We distinguish between the two cases via the `is_resolve` parameter, which is `true` when we
1308are directly resolving a path, but `false` when we simply wish to look up the signature of
1309a module.
1310
1311```ocaml env=e1
1312let test_data = {|
1313module M : sig
1314 module F(X : sig module type S end) : sig
1315 module type S = sig
1316 module N : X.S
1317 end
1318 end
1319 module T : sig
1320 module type S = sig type t end
1321 end
1322 module O : F(T).S
1323end
1324type t = M.O.N.t
1325|}
1326let sg = Common.signature_of_mli_string test_data;;
1327let env = Env.open_signature sg Env.empty;;
1328let resolved = Common.compile_signature sg;;
1329```
1330
1331```ocaml env=e1
1332# Common.LangUtils.Lens.get t_manifest resolved;;
1333- : Odoc_model.Lang.TypeExpr.t option =
1334Some
1335 (Odoc_model.Lang.TypeExpr.Constr
1336 (`Resolved
1337 (`Type
1338 (`Subst
1339 (`ModuleType
1340 (`Substituted
1341 (`Module
1342 (`Identifier
1343 {Odoc_model__Paths_types.iv =
1344 `Module
1345 ({Odoc_model__Paths_types.iv =
1346 `Root
1347 (Some
1348 {Odoc_model__Paths_types.iv =
1349 `Page (None, None);
1350 ihash = 236059787; ikey = "p_None"},
1351 Root);
1352 ihash = 818126955; ikey = "r_Root.p_None"},
1353 M);
1354 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1355 T)),
1356 S),
1357 `Module
1358 (`Module
1359 (`Identifier
1360 {Odoc_model__Paths_types.iv =
1361 `Module
1362 ({Odoc_model__Paths_types.iv =
1363 `Root
1364 (Some
1365 {Odoc_model__Paths_types.iv =
1366 `Page (None, None);
1367 ihash = 236059787; ikey = "p_None"},
1368 Root);
1369 ihash = 818126955; ikey = "r_Root.p_None"},
1370 M);
1371 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1372 O),
1373 N)),
1374 t)),
1375 []))
1376```
1377
1378This following example also shouldn't have a `Subst`, since although as before we're effectively
1379constructing a new module `M.O(M)` on the fly here, the subsequent path `.N.t` is actually
1380present in the body of the functor and is independent of the argument (in fact, the argument
1381in this case is totally ignored). Consequently the resolution proceeds without encountering
1382a `Substituted` node and we therefore don't end up putting a `Subst` node in the returned
1383path.
1384
1385```ocaml env=e1
1386let test_data = {|
1387module M : sig
1388 module F(X : sig module type S end) : sig
1389 module type S = sig
1390 module N : X.S
1391 end
1392 end
1393 module T : sig
1394 module type S = sig type t end
1395 end
1396 module O : functor (X : sig end) -> F(T).S
1397end
1398type t = M.O(M.T).N.t
1399|}
1400let sg = Common.signature_of_mli_string test_data;;
1401let env = Env.open_signature sg Env.empty;;
1402let resolved = Common.compile_signature sg;;
1403```
1404
1405```ocaml env=e1
1406# Common.LangUtils.Lens.get t_manifest resolved;;
1407- : Odoc_model.Lang.TypeExpr.t option =
1408Some
1409 (Odoc_model.Lang.TypeExpr.Constr
1410 (`Resolved
1411 (`Type
1412 (`Subst
1413 (`ModuleType
1414 (`Substituted
1415 (`Module
1416 (`Identifier
1417 {Odoc_model__Paths_types.iv =
1418 `Module
1419 ({Odoc_model__Paths_types.iv =
1420 `Root
1421 (Some
1422 {Odoc_model__Paths_types.iv =
1423 `Page (None, None);
1424 ihash = 236059787; ikey = "p_None"},
1425 Root);
1426 ihash = 818126955; ikey = "r_Root.p_None"},
1427 M);
1428 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1429 T)),
1430 S),
1431 `Module
1432 (`Apply
1433 (`Module
1434 (`Identifier
1435 {Odoc_model__Paths_types.iv =
1436 `Module
1437 ({Odoc_model__Paths_types.iv =
1438 `Root
1439 (Some
1440 {Odoc_model__Paths_types.iv =
1441 `Page (None, None);
1442 ihash = 236059787; ikey = "p_None"},
1443 Root);
1444 ihash = 818126955; ikey = "r_Root.p_None"},
1445 M);
1446 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1447 O),
1448 `Module
1449 (`Identifier
1450 {Odoc_model__Paths_types.iv =
1451 `Module
1452 ({Odoc_model__Paths_types.iv =
1453 `Root
1454 (Some
1455 {Odoc_model__Paths_types.iv =
1456 `Page (None, None);
1457 ihash = 236059787; ikey = "p_None"},
1458 Root);
1459 ihash = 818126955; ikey = "r_Root.p_None"},
1460 M);
1461 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1462 T)),
1463 N)),
1464 t)),
1465 []))
1466```
1467
1468# Higher order functors
1469
1470Functors may take other functors as arguments. In the following example we have
1471a complex functor where type of the 3rd argument is dependent on the first two:
1472
1473```ocaml env=e1
1474let test_data = {|
1475module type Type = sig module type T end
1476module App : functor (T : Type) (F : Type -> Type) (M : F(T).T) -> F(T).T
1477module Bar : sig module type T = sig type bar end end
1478module Foo :
1479 functor (T : Type) -> sig module type T = sig module Foo : T.T end end
1480module FooBarInt : sig module Foo : sig type bar = int end end
1481type t = App(Bar)(Foo)(FooBarInt).Foo.bar
1482|}
1483let sg = Common.signature_of_mli_string test_data;;
1484let env = Env.open_signature sg Env.empty;;
1485```
1486
1487The type path we're trying to look up is:
1488
1489```ocaml env=e1
1490# Common.LangUtils.Lens.get (type_manifest "t") sg;;
1491- : Odoc_model.Lang.TypeExpr.t option =
1492Some
1493 (Odoc_model.Lang.TypeExpr.Constr
1494 (`DotT
1495 (`Dot
1496 (`Apply
1497 (`Apply
1498 (`Apply
1499 (`Identifier
1500 ({Odoc_model__Paths_types.iv =
1501 `Module
1502 ({Odoc_model__Paths_types.iv =
1503 `Root
1504 (Some
1505 {Odoc_model__Paths_types.iv =
1506 `Page (None, None);
1507 ihash = 236059787; ikey = "p_None"},
1508 Root);
1509 ihash = 818126955; ikey = "r_Root.p_None"},
1510 App);
1511 ihash = 855073208; ikey = "m_App.r_Root.p_None"},
1512 false),
1513 `Identifier
1514 ({Odoc_model__Paths_types.iv =
1515 `Module
1516 ({Odoc_model__Paths_types.iv =
1517 `Root
1518 (Some
1519 {Odoc_model__Paths_types.iv =
1520 `Page (None, None);
1521 ihash = 236059787; ikey = "p_None"},
1522 Root);
1523 ihash = 818126955; ikey = "r_Root.p_None"},
1524 Bar);
1525 ihash = 608577; ikey = "m_Bar.r_Root.p_None"},
1526 false)),
1527 `Identifier
1528 ({Odoc_model__Paths_types.iv =
1529 `Module
1530 ({Odoc_model__Paths_types.iv =
1531 `Root
1532 (Some
1533 {Odoc_model__Paths_types.iv =
1534 `Page (None, None);
1535 ihash = 236059787; ikey = "p_None"},
1536 Root);
1537 ihash = 818126955; ikey = "r_Root.p_None"},
1538 Foo);
1539 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
1540 false)),
1541 `Identifier
1542 ({Odoc_model__Paths_types.iv =
1543 `Module
1544 ({Odoc_model__Paths_types.iv =
1545 `Root
1546 (Some
1547 {Odoc_model__Paths_types.iv = `Page (None, None);
1548 ihash = 236059787; ikey = "p_None"},
1549 Root);
1550 ihash = 818126955; ikey = "r_Root.p_None"},
1551 FooBarInt);
1552 ihash = 706684202; ikey = "m_FooBarInt.r_Root.p_None"},
1553 false)),
1554 Foo),
1555 bar),
1556 []))
1557```
1558
1559Extract the path to the Apply (so `App(Bar)(Foo)(FooBarInt)`)
1560```ocaml env=e1
1561let test_path =
1562 `Apply
1563 (`Apply
1564 (`Apply
1565 (`Resolved
1566 (`Identifier
1567 (Common.root_module "App")),
1568 `Resolved
1569 (`Identifier
1570 (Common.root_module "Bar"))),
1571 `Resolved
1572 (`Identifier (Common.root_module "Foo"))),
1573 `Resolved
1574 (`Identifier
1575 (Common.root_module "FooBarInt")));;
1576let cp = Component.Of_Lang.(module_path (empty ()) test_path);;
1577```
1578
1579Now let's lookup that module:
1580
1581```ocaml env=e1
1582# let (p,m) = get_ok @@ Tools.resolve_module env cp;;
1583val p : Cpath.Resolved.module_ =
1584 `Apply
1585 (`Apply
1586 (`Apply
1587 (`Gpath
1588 (`Identifier
1589 {Odoc_model__Paths_types.iv =
1590 `Module
1591 ({Odoc_model__Paths_types.iv =
1592 `Root
1593 (Some
1594 {Odoc_model__Paths_types.iv = `Page (None, None);
1595 ihash = 236059787; ikey = "p_None"},
1596 Root);
1597 ihash = 818126955; ikey = "r_Root.p_None"},
1598 App);
1599 ihash = 855073208; ikey = "m_App.r_Root.p_None"}),
1600 `Gpath
1601 (`Identifier
1602 {Odoc_model__Paths_types.iv =
1603 `Module
1604 ({Odoc_model__Paths_types.iv =
1605 `Root
1606 (Some
1607 {Odoc_model__Paths_types.iv = `Page (None, None);
1608 ihash = 236059787; ikey = "p_None"},
1609 Root);
1610 ihash = 818126955; ikey = "r_Root.p_None"},
1611 Bar);
1612 ihash = 608577; ikey = "m_Bar.r_Root.p_None"})),
1613 `Gpath
1614 (`Identifier
1615 {Odoc_model__Paths_types.iv =
1616 `Module
1617 ({Odoc_model__Paths_types.iv =
1618 `Root
1619 (Some
1620 {Odoc_model__Paths_types.iv = `Page (None, None);
1621 ihash = 236059787; ikey = "p_None"},
1622 Root);
1623 ihash = 818126955; ikey = "r_Root.p_None"},
1624 Foo);
1625 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"})),
1626 `Gpath
1627 (`Identifier
1628 {Odoc_model__Paths_types.iv =
1629 `Module
1630 ({Odoc_model__Paths_types.iv =
1631 `Root
1632 (Some
1633 {Odoc_model__Paths_types.iv = `Page (None, None);
1634 ihash = 236059787; ikey = "p_None"},
1635 Root);
1636 ihash = 818126955; ikey = "r_Root.p_None"},
1637 FooBarInt);
1638 ihash = 706684202; ikey = "m_FooBarInt.r_Root.p_None"}))
1639val m : Component.Module.t Component.Delayed.t =
1640 {Odoc_xref2.Component.Delayed.v =
1641 Some
1642 {Odoc_xref2.Component.Module.source_loc = None;
1643 doc =
1644 {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None};
1645 type_ =
1646 Odoc_xref2.Component.Module.ModuleType
1647 (Odoc_xref2.Component.ModuleType.Path
1648 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1649 p_path =
1650 `DotMT
1651 (`Apply
1652 (`Resolved
1653 (`Substituted
1654 (`Gpath
1655 (`Identifier
1656 {Odoc_model__Paths_types.iv =
1657 `Module
1658 ({Odoc_model__Paths_types.iv =
1659 `Root
1660 (Some
1661 {Odoc_model__Paths_types.iv =
1662 `Page (None, None);
1663 ihash = 236059787; ikey = "p_None"},
1664 Root);
1665 ihash = 818126955; ikey = "r_Root.p_None"},
1666 Foo);
1667 ihash = 249248993;
1668 ikey = "m_Foo.r_Root.p_None"}))),
1669 `Resolved
1670 (`Substituted
1671 (`Gpath
1672 (`Identifier
1673 {Odoc_model__Paths_types.iv =
1674 `Module
1675 ({Odoc_model__Paths_types.iv =
1676 `Root
1677 (Some
1678 {Odoc_model__Paths_types.iv =
1679 `Page (None, None);
1680 ihash = 236059787; ikey = "p_None"},
1681 Root);
1682 ihash = 818126955; ikey = "r_Root.p_None"},
1683 Bar);
1684 ihash = 608577; ikey = "m_Bar.r_Root.p_None"})))),
1685 T)});
1686 canonical = None; hidden = false};
1687 get = None}
1688# let sg' = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
1689val sg' : Tools.expansion =
1690 Odoc_xref2.Tools.Signature
1691 {Odoc_xref2.Component.Signature.items =
1692 [Odoc_xref2.Component.Signature.Module (`LModule (Foo, 16),
1693 Odoc_model.Lang.Signature.Ordinary,
1694 {Odoc_xref2.Component.Delayed.v =
1695 Some
1696 {Odoc_xref2.Component.Module.source_loc = None;
1697 doc =
1698 {Odoc_xref2.Component.CComment.elements = [];
1699 warnings_tag = None};
1700 type_ =
1701 Odoc_xref2.Component.Module.ModuleType
1702 (Odoc_xref2.Component.ModuleType.Path
1703 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1704 p_path =
1705 `DotMT
1706 (`Resolved
1707 (`Substituted
1708 (`Substituted
1709 (`Gpath
1710 (`Identifier
1711 {Odoc_model__Paths_types.iv =
1712 `Module
1713 ({Odoc_model__Paths_types.iv =
1714 `Root
1715 (Some
1716 {Odoc_model__Paths_types.iv =
1717 `Page (None, None);
1718 ihash = 236059787;
1719 ikey = "p_None"},
1720 Root);
1721 ihash = 818126955;
1722 ikey = "r_Root.p_None"},
1723 Bar);
1724 ihash = 608577;
1725 ikey = "m_Bar.r_Root.p_None"})))),
1726 T)});
1727 canonical = None; hidden = false};
1728 get = None})];
1729 compiled = false; removed = [];
1730 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1731# let sg' = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
1732val sg' : Tools.expansion =
1733 Odoc_xref2.Tools.Signature
1734 {Odoc_xref2.Component.Signature.items =
1735 [Odoc_xref2.Component.Signature.Module (`LModule (Foo, 21),
1736 Odoc_model.Lang.Signature.Ordinary,
1737 {Odoc_xref2.Component.Delayed.v =
1738 Some
1739 {Odoc_xref2.Component.Module.source_loc = None;
1740 doc =
1741 {Odoc_xref2.Component.CComment.elements = [];
1742 warnings_tag = None};
1743 type_ =
1744 Odoc_xref2.Component.Module.ModuleType
1745 (Odoc_xref2.Component.ModuleType.Path
1746 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1747 p_path =
1748 `DotMT
1749 (`Resolved
1750 (`Substituted
1751 (`Substituted
1752 (`Gpath
1753 (`Identifier
1754 {Odoc_model__Paths_types.iv =
1755 `Module
1756 ({Odoc_model__Paths_types.iv =
1757 `Root
1758 (Some
1759 {Odoc_model__Paths_types.iv =
1760 `Page (None, None);
1761 ihash = 236059787;
1762 ikey = "p_None"},
1763 Root);
1764 ihash = 818126955;
1765 ikey = "r_Root.p_None"},
1766 Bar);
1767 ihash = 608577;
1768 ikey = "m_Bar.r_Root.p_None"})))),
1769 T)});
1770 canonical = None; hidden = false};
1771 get = None})];
1772 compiled = false; removed = [];
1773 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1774# let sg' = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
1775val sg' : Tools.expansion =
1776 Odoc_xref2.Tools.Signature
1777 {Odoc_xref2.Component.Signature.items =
1778 [Odoc_xref2.Component.Signature.Module (`LModule (Foo, 26),
1779 Odoc_model.Lang.Signature.Ordinary,
1780 {Odoc_xref2.Component.Delayed.v =
1781 Some
1782 {Odoc_xref2.Component.Module.source_loc = None;
1783 doc =
1784 {Odoc_xref2.Component.CComment.elements = [];
1785 warnings_tag = None};
1786 type_ =
1787 Odoc_xref2.Component.Module.ModuleType
1788 (Odoc_xref2.Component.ModuleType.Path
1789 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1790 p_path =
1791 `DotMT
1792 (`Resolved
1793 (`Substituted
1794 (`Substituted
1795 (`Gpath
1796 (`Identifier
1797 {Odoc_model__Paths_types.iv =
1798 `Module
1799 ({Odoc_model__Paths_types.iv =
1800 `Root
1801 (Some
1802 {Odoc_model__Paths_types.iv =
1803 `Page (None, None);
1804 ihash = 236059787;
1805 ikey = "p_None"},
1806 Root);
1807 ihash = 818126955;
1808 ikey = "r_Root.p_None"},
1809 Bar);
1810 ihash = 608577;
1811 ikey = "m_Bar.r_Root.p_None"})))),
1812 T)});
1813 canonical = None; hidden = false};
1814 get = None})];
1815 compiled = false; removed = [];
1816 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1817# let sg' = get_ok @@ Tools.expansion_of_module env (Component.Delayed.get m);;
1818val sg' : Tools.expansion =
1819 Odoc_xref2.Tools.Signature
1820 {Odoc_xref2.Component.Signature.items =
1821 [Odoc_xref2.Component.Signature.Module (`LModule (Foo, 31),
1822 Odoc_model.Lang.Signature.Ordinary,
1823 {Odoc_xref2.Component.Delayed.v =
1824 Some
1825 {Odoc_xref2.Component.Module.source_loc = None;
1826 doc =
1827 {Odoc_xref2.Component.CComment.elements = [];
1828 warnings_tag = None};
1829 type_ =
1830 Odoc_xref2.Component.Module.ModuleType
1831 (Odoc_xref2.Component.ModuleType.Path
1832 {Odoc_xref2.Component.ModuleType.p_expansion = None;
1833 p_path =
1834 `DotMT
1835 (`Resolved
1836 (`Substituted
1837 (`Substituted
1838 (`Gpath
1839 (`Identifier
1840 {Odoc_model__Paths_types.iv =
1841 `Module
1842 ({Odoc_model__Paths_types.iv =
1843 `Root
1844 (Some
1845 {Odoc_model__Paths_types.iv =
1846 `Page (None, None);
1847 ihash = 236059787;
1848 ikey = "p_None"},
1849 Root);
1850 ihash = 818126955;
1851 ikey = "r_Root.p_None"},
1852 Bar);
1853 ihash = 608577;
1854 ikey = "m_Bar.r_Root.p_None"})))),
1855 T)});
1856 canonical = None; hidden = false};
1857 get = None})];
1858 compiled = false; removed = [];
1859 doc = {Odoc_xref2.Component.CComment.elements = []; warnings_tag = None}}
1860```
1861
1862```ocaml env=e1
1863let resolved = Common.compile_signature sg;;
1864```
1865
1866The resolved path of t is:
1867
1868```ocaml env=e1
1869# Common.LangUtils.Lens.get t_manifest resolved;;
1870- : Odoc_model.Lang.TypeExpr.t option =
1871Some
1872 (Odoc_model.Lang.TypeExpr.Constr
1873 (`Resolved
1874 (`Type
1875 (`Subst
1876 (`ModuleType
1877 (`Substituted
1878 (`Substituted
1879 (`Identifier
1880 {Odoc_model__Paths_types.iv =
1881 `Module
1882 ({Odoc_model__Paths_types.iv =
1883 `Root
1884 (Some
1885 {Odoc_model__Paths_types.iv =
1886 `Page (None, None);
1887 ihash = 236059787; ikey = "p_None"},
1888 Root);
1889 ihash = 818126955; ikey = "r_Root.p_None"},
1890 Bar);
1891 ihash = 608577; ikey = "m_Bar.r_Root.p_None"})),
1892 T),
1893 `Module
1894 (`Apply
1895 (`Apply
1896 (`Apply
1897 (`Identifier
1898 {Odoc_model__Paths_types.iv =
1899 `Module
1900 ({Odoc_model__Paths_types.iv =
1901 `Root
1902 (Some
1903 {Odoc_model__Paths_types.iv =
1904 `Page (None, None);
1905 ihash = 236059787; ikey = "p_None"},
1906 Root);
1907 ihash = 818126955; ikey = "r_Root.p_None"},
1908 App);
1909 ihash = 855073208; ikey = "m_App.r_Root.p_None"},
1910 `Identifier
1911 {Odoc_model__Paths_types.iv =
1912 `Module
1913 ({Odoc_model__Paths_types.iv =
1914 `Root
1915 (Some
1916 {Odoc_model__Paths_types.iv =
1917 `Page (None, None);
1918 ihash = 236059787; ikey = "p_None"},
1919 Root);
1920 ihash = 818126955; ikey = "r_Root.p_None"},
1921 Bar);
1922 ihash = 608577; ikey = "m_Bar.r_Root.p_None"}),
1923 `Identifier
1924 {Odoc_model__Paths_types.iv =
1925 `Module
1926 ({Odoc_model__Paths_types.iv =
1927 `Root
1928 (Some
1929 {Odoc_model__Paths_types.iv =
1930 `Page (None, None);
1931 ihash = 236059787; ikey = "p_None"},
1932 Root);
1933 ihash = 818126955; ikey = "r_Root.p_None"},
1934 Foo);
1935 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"}),
1936 `Identifier
1937 {Odoc_model__Paths_types.iv =
1938 `Module
1939 ({Odoc_model__Paths_types.iv =
1940 `Root
1941 (Some
1942 {Odoc_model__Paths_types.iv =
1943 `Page (None, None);
1944 ihash = 236059787; ikey = "p_None"},
1945 Root);
1946 ihash = 818126955; ikey = "r_Root.p_None"},
1947 FooBarInt);
1948 ihash = 706684202; ikey = "m_FooBarInt.r_Root.p_None"}),
1949 Foo)),
1950 bar)),
1951 []))
1952```
1953
1954### Yet another nasty one
1955
1956```ocaml env=e1
1957let test_data = {|
1958module M : sig
1959 module F(X : sig module type S end) : sig
1960 module type S = sig
1961 module N : X.S
1962 end
1963 end
1964 module T : sig
1965 module type S = sig type t end
1966 end
1967 module O : functor (X : sig end) -> F(T).S
1968end
1969type t = M.O(M).N.t
1970|}
1971let sg = Common.signature_of_mli_string test_data;;
1972let resolved = Common.compile_signature sg;;
1973```
1974
1975```ocaml env=e1
1976# Common.LangUtils.Lens.get t_manifest resolved;;
1977- : Odoc_model.Lang.TypeExpr.t option =
1978Some
1979 (Odoc_model.Lang.TypeExpr.Constr
1980 (`Resolved
1981 (`Type
1982 (`Subst
1983 (`ModuleType
1984 (`Substituted
1985 (`Module
1986 (`Identifier
1987 {Odoc_model__Paths_types.iv =
1988 `Module
1989 ({Odoc_model__Paths_types.iv =
1990 `Root
1991 (Some
1992 {Odoc_model__Paths_types.iv =
1993 `Page (None, None);
1994 ihash = 236059787; ikey = "p_None"},
1995 Root);
1996 ihash = 818126955; ikey = "r_Root.p_None"},
1997 M);
1998 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
1999 T)),
2000 S),
2001 `Module
2002 (`Apply
2003 (`Module
2004 (`Identifier
2005 {Odoc_model__Paths_types.iv =
2006 `Module
2007 ({Odoc_model__Paths_types.iv =
2008 `Root
2009 (Some
2010 {Odoc_model__Paths_types.iv =
2011 `Page (None, None);
2012 ihash = 236059787; ikey = "p_None"},
2013 Root);
2014 ihash = 818126955; ikey = "r_Root.p_None"},
2015 M);
2016 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
2017 O),
2018 `Identifier
2019 {Odoc_model__Paths_types.iv =
2020 `Module
2021 ({Odoc_model__Paths_types.iv =
2022 `Root
2023 (Some
2024 {Odoc_model__Paths_types.iv =
2025 `Page (None, None);
2026 ihash = 236059787; ikey = "p_None"},
2027 Root);
2028 ihash = 818126955; ikey = "r_Root.p_None"},
2029 M);
2030 ihash = 716453475; ikey = "m_M.r_Root.p_None"}),
2031 N)),
2032 t)),
2033 []))
2034```
2035
2036
2037# More dependently typed modules
2038
2039```ocaml env=e1
2040let test_data = {|
2041module Dep1 : sig
2042 module type S = sig
2043 type c = int
2044 end
2045 module X : sig
2046 module Y : S
2047 end
2048end
2049module Dep2 :
2050 functor (Arg : sig module type S module X : sig module Y : S end end) ->
2051 sig
2052 module A : sig
2053 module Y : Arg.S
2054 end
2055 module B = A.Y
2056 end
2057type dep1 = Dep2(Dep1).B.c
2058|};;
2059
2060let sg = Common.signature_of_mli_string test_data;;
2061let resolved = Common.compile_signature sg;;
2062```
2063
2064```ocaml env=e1
2065# Common.LangUtils.Lens.get (type_manifest "dep1") resolved;;
2066- : Odoc_model.Lang.TypeExpr.t option =
2067Some
2068 (Odoc_model.Lang.TypeExpr.Constr
2069 (`Resolved
2070 (`Type
2071 (`Alias
2072 (`Subst
2073 (`ModuleType
2074 (`Substituted
2075 (`Identifier
2076 {Odoc_model__Paths_types.iv =
2077 `Module
2078 ({Odoc_model__Paths_types.iv =
2079 `Root
2080 (Some
2081 {Odoc_model__Paths_types.iv =
2082 `Page (None, None);
2083 ihash = 236059787; ikey = "p_None"},
2084 Root);
2085 ihash = 818126955; ikey = "r_Root.p_None"},
2086 Dep1);
2087 ihash = 393430064; ikey = "m_Dep1.r_Root.p_None"}),
2088 S),
2089 `Module
2090 (`Module
2091 (`Apply
2092 (`Identifier
2093 {Odoc_model__Paths_types.iv =
2094 `Module
2095 ({Odoc_model__Paths_types.iv =
2096 `Root
2097 (Some
2098 {Odoc_model__Paths_types.iv =
2099 `Page (None, None);
2100 ihash = 236059787; ikey = "p_None"},
2101 Root);
2102 ihash = 818126955; ikey = "r_Root.p_None"},
2103 Dep2);
2104 ihash = 739333691; ikey = "m_Dep2.r_Root.p_None"},
2105 `Identifier
2106 {Odoc_model__Paths_types.iv =
2107 `Module
2108 ({Odoc_model__Paths_types.iv =
2109 `Root
2110 (Some
2111 {Odoc_model__Paths_types.iv =
2112 `Page (None, None);
2113 ihash = 236059787; ikey = "p_None"},
2114 Root);
2115 ihash = 818126955; ikey = "r_Root.p_None"},
2116 Dep1);
2117 ihash = 393430064; ikey = "m_Dep1.r_Root.p_None"}),
2118 A),
2119 Y)),
2120 `Dot
2121 (`Apply
2122 (`Identifier
2123 ({Odoc_model__Paths_types.iv =
2124 `Module
2125 ({Odoc_model__Paths_types.iv =
2126 `Root
2127 (Some
2128 {Odoc_model__Paths_types.iv =
2129 `Page (None, None);
2130 ihash = 236059787; ikey = "p_None"},
2131 Root);
2132 ihash = 818126955; ikey = "r_Root.p_None"},
2133 Dep2);
2134 ihash = 739333691; ikey = "m_Dep2.r_Root.p_None"},
2135 false),
2136 `Identifier
2137 ({Odoc_model__Paths_types.iv =
2138 `Module
2139 ({Odoc_model__Paths_types.iv =
2140 `Root
2141 (Some
2142 {Odoc_model__Paths_types.iv =
2143 `Page (None, None);
2144 ihash = 236059787; ikey = "p_None"},
2145 Root);
2146 ihash = 818126955; ikey = "r_Root.p_None"},
2147 Dep1);
2148 ihash = 393430064; ikey = "m_Dep1.r_Root.p_None"},
2149 false)),
2150 B)),
2151 c)),
2152 []))
2153```
2154
2155```ocaml env=e1
2156let test_data = {|
2157module Dep3 : sig type a end
2158module Dep4 : sig
2159 module type T = sig type b end
2160 module type S = sig
2161 module X : T
2162 module Y : sig end
2163 end
2164 module X : T
2165end
2166module Dep5 :
2167 functor (Arg : sig
2168 module type T
2169 module type S = sig
2170 module X : T
2171 module Y : sig end
2172 end
2173 module X : T
2174 end) ->
2175 sig
2176 module Z : Arg.S with module Y = Dep3
2177 end
2178type dep2 = Dep5(Dep4).Z.X.b
2179type dep3 = Dep5(Dep4).Z.Y.a
2180|};;
2181let sg = Common.signature_of_mli_string test_data;;
2182let resolved = Common.compile_signature sg;;
2183```
2184
2185```ocaml env=e1
2186# Common.LangUtils.Lens.get (type_manifest "dep2") resolved;;
2187- : Odoc_model.Lang.TypeExpr.t option =
2188Some
2189 (Odoc_model.Lang.TypeExpr.Constr
2190 (`Resolved
2191 (`Type
2192 (`Subst
2193 (`ModuleType
2194 (`Substituted
2195 (`Identifier
2196 {Odoc_model__Paths_types.iv =
2197 `Module
2198 ({Odoc_model__Paths_types.iv =
2199 `Root
2200 (Some
2201 {Odoc_model__Paths_types.iv =
2202 `Page (None, None);
2203 ihash = 236059787; ikey = "p_None"},
2204 Root);
2205 ihash = 818126955; ikey = "r_Root.p_None"},
2206 Dep4);
2207 ihash = 1019199703; ikey = "m_Dep4.r_Root.p_None"}),
2208 T),
2209 `Module
2210 (`Module
2211 (`Apply
2212 (`Identifier
2213 {Odoc_model__Paths_types.iv =
2214 `Module
2215 ({Odoc_model__Paths_types.iv =
2216 `Root
2217 (Some
2218 {Odoc_model__Paths_types.iv =
2219 `Page (None, None);
2220 ihash = 236059787; ikey = "p_None"},
2221 Root);
2222 ihash = 818126955; ikey = "r_Root.p_None"},
2223 Dep5);
2224 ihash = 592809356; ikey = "m_Dep5.r_Root.p_None"},
2225 `Identifier
2226 {Odoc_model__Paths_types.iv =
2227 `Module
2228 ({Odoc_model__Paths_types.iv =
2229 `Root
2230 (Some
2231 {Odoc_model__Paths_types.iv =
2232 `Page (None, None);
2233 ihash = 236059787; ikey = "p_None"},
2234 Root);
2235 ihash = 818126955; ikey = "r_Root.p_None"},
2236 Dep4);
2237 ihash = 1019199703; ikey = "m_Dep4.r_Root.p_None"}),
2238 Z),
2239 X)),
2240 b)),
2241 []))
2242# Common.LangUtils.Lens.get (type_manifest "dep3") resolved;;
2243- : Odoc_model.Lang.TypeExpr.t option =
2244Some
2245 (Odoc_model.Lang.TypeExpr.Constr
2246 (`Resolved
2247 (`Type
2248 (`Alias
2249 (`Identifier
2250 {Odoc_model__Paths_types.iv =
2251 `Module
2252 ({Odoc_model__Paths_types.iv =
2253 `Root
2254 (Some
2255 {Odoc_model__Paths_types.iv = `Page (None, None);
2256 ihash = 236059787; ikey = "p_None"},
2257 Root);
2258 ihash = 818126955; ikey = "r_Root.p_None"},
2259 Dep3);
2260 ihash = 403763666; ikey = "m_Dep3.r_Root.p_None"},
2261 `Dot
2262 (`Dot
2263 (`Apply
2264 (`Identifier
2265 ({Odoc_model__Paths_types.iv =
2266 `Module
2267 ({Odoc_model__Paths_types.iv =
2268 `Root
2269 (Some
2270 {Odoc_model__Paths_types.iv =
2271 `Page (None, None);
2272 ihash = 236059787; ikey = "p_None"},
2273 Root);
2274 ihash = 818126955; ikey = "r_Root.p_None"},
2275 Dep5);
2276 ihash = 592809356; ikey = "m_Dep5.r_Root.p_None"},
2277 false),
2278 `Identifier
2279 ({Odoc_model__Paths_types.iv =
2280 `Module
2281 ({Odoc_model__Paths_types.iv =
2282 `Root
2283 (Some
2284 {Odoc_model__Paths_types.iv =
2285 `Page (None, None);
2286 ihash = 236059787; ikey = "p_None"},
2287 Root);
2288 ihash = 818126955; ikey = "r_Root.p_None"},
2289 Dep4);
2290 ihash = 1019199703; ikey = "m_Dep4.r_Root.p_None"},
2291 false)),
2292 Z),
2293 Y)),
2294 a)),
2295 []))
2296```
2297
2298```ocaml env=e1
2299let test_data = {|
2300module Dep6 : sig
2301 module type S = sig type d end
2302 module type T = sig
2303 module type R = S
2304 module Y : R
2305 end
2306 module X : T
2307end
2308
2309module Dep7 :
2310 functor (Arg : sig
2311 module type S
2312 module type T = sig
2313 module type R = S
2314 module Y : R
2315 end
2316 module X : T
2317 end) -> sig
2318 module M : Arg.T
2319 end
2320
2321type dep4 = Dep7(Dep6).M.Y.d
2322|};;
2323let sg = Common.signature_of_mli_string test_data;;
2324let resolved = Common.compile_signature sg;;
2325```
2326
2327```ocaml env=e1
2328# Common.LangUtils.Lens.get (type_manifest "dep4") resolved;;
2329- : Odoc_model.Lang.TypeExpr.t option =
2330Some
2331 (Odoc_model.Lang.TypeExpr.Constr
2332 (`Resolved
2333 (`Type
2334 (`Module
2335 (`Subst
2336 (`ModuleType
2337 (`Substituted
2338 (`Identifier
2339 {Odoc_model__Paths_types.iv =
2340 `Module
2341 ({Odoc_model__Paths_types.iv =
2342 `Root
2343 (Some
2344 {Odoc_model__Paths_types.iv =
2345 `Page (None, None);
2346 ihash = 236059787; ikey = "p_None"},
2347 Root);
2348 ihash = 818126955; ikey = "r_Root.p_None"},
2349 Dep6);
2350 ihash = 489035468; ikey = "m_Dep6.r_Root.p_None"}),
2351 T),
2352 `Module
2353 (`Apply
2354 (`Identifier
2355 {Odoc_model__Paths_types.iv =
2356 `Module
2357 ({Odoc_model__Paths_types.iv =
2358 `Root
2359 (Some
2360 {Odoc_model__Paths_types.iv =
2361 `Page (None, None);
2362 ihash = 236059787; ikey = "p_None"},
2363 Root);
2364 ihash = 818126955; ikey = "r_Root.p_None"},
2365 Dep7);
2366 ihash = 108620130; ikey = "m_Dep7.r_Root.p_None"},
2367 `Identifier
2368 {Odoc_model__Paths_types.iv =
2369 `Module
2370 ({Odoc_model__Paths_types.iv =
2371 `Root
2372 (Some
2373 {Odoc_model__Paths_types.iv =
2374 `Page (None, None);
2375 ihash = 236059787; ikey = "p_None"},
2376 Root);
2377 ihash = 818126955; ikey = "r_Root.p_None"},
2378 Dep6);
2379 ihash = 489035468; ikey = "m_Dep6.r_Root.p_None"}),
2380 M)),
2381 Y),
2382 d)),
2383 []))
2384```
2385
2386```ocaml env=e1
2387let test_data = {|
2388module Dep8 : sig module type T = sig type t end end
2389
2390module Dep9 : functor (X : sig module type T end) -> sig module type T = X.T end
2391
2392module type Dep10 = Dep9(Dep8).T with type t = int
2393
2394module Dep11 : sig
2395 module type S = sig
2396 type c
2397 end
2398end
2399
2400module Dep12 :
2401 functor (Arg : sig module type S end) -> sig
2402 module type T = Arg.S
2403end
2404
2405module Dep13 : Dep12(Dep11).T
2406
2407type dep5 = Dep13.c
2408|};;
2409let sg = Common.signature_of_mli_string test_data;;
2410let resolved = Common.compile_signature sg;;
2411```
2412
2413```ocaml env=e1
2414# Common.LangUtils.Lens.get (type_manifest "dep5") resolved;;
2415- : Odoc_model.Lang.TypeExpr.t option =
2416Some
2417 (Odoc_model.Lang.TypeExpr.Constr
2418 (`Resolved
2419 (`Type
2420 (`Subst
2421 (`AliasModuleType
2422 (`ModuleType
2423 (`Substituted
2424 (`Identifier
2425 {Odoc_model__Paths_types.iv =
2426 `Module
2427 ({Odoc_model__Paths_types.iv =
2428 `Root
2429 (Some
2430 {Odoc_model__Paths_types.iv =
2431 `Page (None, None);
2432 ihash = 236059787; ikey = "p_None"},
2433 Root);
2434 ihash = 818126955; ikey = "r_Root.p_None"},
2435 Dep11);
2436 ihash = 873108764; ikey = "m_Dep11.r_Root.p_None"}),
2437 S),
2438 `SubstT
2439 (`ModuleType
2440 (`Substituted
2441 (`Identifier
2442 {Odoc_model__Paths_types.iv =
2443 `Module
2444 ({Odoc_model__Paths_types.iv =
2445 `Root
2446 (Some
2447 {Odoc_model__Paths_types.iv =
2448 `Page (None, None);
2449 ihash = 236059787; ikey = "p_None"},
2450 Root);
2451 ihash = 818126955; ikey = "r_Root.p_None"},
2452 Dep11);
2453 ihash = 873108764;
2454 ikey = "m_Dep11.r_Root.p_None"}),
2455 S),
2456 `ModuleType
2457 (`Apply
2458 (`Identifier
2459 {Odoc_model__Paths_types.iv =
2460 `Module
2461 ({Odoc_model__Paths_types.iv =
2462 `Root
2463 (Some
2464 {Odoc_model__Paths_types.iv =
2465 `Page (None, None);
2466 ihash = 236059787; ikey = "p_None"},
2467 Root);
2468 ihash = 818126955; ikey = "r_Root.p_None"},
2469 Dep12);
2470 ihash = 755368715;
2471 ikey = "m_Dep12.r_Root.p_None"},
2472 `Identifier
2473 {Odoc_model__Paths_types.iv =
2474 `Module
2475 ({Odoc_model__Paths_types.iv =
2476 `Root
2477 (Some
2478 {Odoc_model__Paths_types.iv =
2479 `Page (None, None);
2480 ihash = 236059787; ikey = "p_None"},
2481 Root);
2482 ihash = 818126955; ikey = "r_Root.p_None"},
2483 Dep11);
2484 ihash = 873108764;
2485 ikey = "m_Dep11.r_Root.p_None"}),
2486 T))),
2487 `Identifier
2488 {Odoc_model__Paths_types.iv =
2489 `Module
2490 ({Odoc_model__Paths_types.iv =
2491 `Root
2492 (Some
2493 {Odoc_model__Paths_types.iv = `Page (None, None);
2494 ihash = 236059787; ikey = "p_None"},
2495 Root);
2496 ihash = 818126955; ikey = "r_Root.p_None"},
2497 Dep13);
2498 ihash = 726816582; ikey = "m_Dep13.r_Root.p_None"}),
2499 c)),
2500 []))
2501```
2502
2503```ocaml env=e1
2504let test_data = {|
2505module With7 : functor
2506 (X : sig
2507 module type T
2508 end)
2509 -> sig
2510 module type T = X.T
2511end
2512
2513module With9 : sig
2514 module type S = sig
2515 type t
2516 end
2517end
2518
2519module With10 : sig
2520 (** {!With10.T} is a submodule type. *)
2521 module type T = sig
2522 module M : sig
2523 module type S
2524 end
2525
2526 module N : M.S
2527 end
2528end
2529
2530module type With11 = With7(With10).T with module M = With9 and type N.t = int
2531|};;
2532let sg = Common.signature_of_mli_string test_data;;
2533let resolved = Common.compile_signature sg;;
2534let with11 = Common.LangUtils.Lens.Signature.module_type "With11"
2535
2536```
2537
2538
2539Let's take a look now at hidden modules
2540
2541```ocaml env=e1
2542let test_data = {|
2543module Hidden__ : sig
2544 type t
2545end
2546
2547module H=Hidden__
2548
2549type t = Hidden__.t
2550|};;
2551let sg = Common.signature_of_mli_string test_data;;
2552let resolved = Common.compile_signature sg;;
2553```
2554
2555```ocaml env=e1
2556# Common.LangUtils.Lens.get (type_manifest "t") resolved;;
2557- : Odoc_model.Lang.TypeExpr.t option =
2558Some
2559 (Odoc_model.Lang.TypeExpr.Constr
2560 (`Resolved
2561 (`Type
2562 (`Hidden
2563 (`Identifier
2564 {Odoc_model__Paths_types.iv =
2565 `Module
2566 ({Odoc_model__Paths_types.iv =
2567 `Root
2568 (Some
2569 {Odoc_model__Paths_types.iv = `Page (None, None);
2570 ihash = 236059787; ikey = "p_None"},
2571 Root);
2572 ihash = 818126955; ikey = "r_Root.p_None"},
2573 Hidden__);
2574 ihash = 762365111; ikey = "m_Hidden__.r_Root.p_None"}),
2575 t)),
2576 []))
2577```
2578
2579
2580How about references now
2581
2582```ocaml env=e1
2583let test_data = {|
2584type t
2585(** [t] {!t} *)
2586|};;
2587let sg = Common.signature_of_mli_string test_data;;
2588let resolved = Common.compile_signature sg;;
2589```
2590
2591```ocaml env=e1
2592# Common.LangUtils.Lens.get (Common.LangUtils.Lens.Signature.type_ "t") resolved;;
2593- : Odoc_model.Lang.TypeDecl.t =
2594{Odoc_model.Lang.TypeDecl.id =
2595 {Odoc_model__Paths_types.iv =
2596 `Type
2597 ({Odoc_model__Paths_types.iv =
2598 `Root
2599 (Some
2600 {Odoc_model__Paths_types.iv = `Page (None, None);
2601 ihash = 236059787; ikey = "p_None"},
2602 Root);
2603 ihash = 818126955; ikey = "r_Root.p_None"},
2604 t);
2605 ihash = 1016576344; ikey = "t_t.r_Root.p_None"};
2606 source_loc = None;
2607 doc =
2608 {Odoc_model__.Comment.elements =
2609 [{Odoc_model__.Location_.location =
2610 {Odoc_model__.Location_.file = "";
2611 start = {Odoc_model__.Location_.line = 3; column = 6};
2612 end_ = {Odoc_model__.Location_.line = 3; column = 14}};
2613 value =
2614 `Paragraph
2615 [{Odoc_model__.Location_.location =
2616 {Odoc_model__.Location_.file = "";
2617 start = {Odoc_model__.Location_.line = 3; column = 6};
2618 end_ = {Odoc_model__.Location_.line = 3; column = 9}};
2619 value = `Code_span "t"};
2620 {Odoc_model__.Location_.location =
2621 {Odoc_model__.Location_.file = "";
2622 start = {Odoc_model__.Location_.line = 3; column = 9};
2623 end_ = {Odoc_model__.Location_.line = 3; column = 10}};
2624 value = `Space};
2625 {Odoc_model__.Location_.location =
2626 {Odoc_model__.Location_.file = "";
2627 start = {Odoc_model__.Location_.line = 3; column = 10};
2628 end_ = {Odoc_model__.Location_.line = 3; column = 14}};
2629 value = `Reference (`Root ("t", `TUnknown), [])}]}];
2630 warnings_tag = None};
2631 canonical = None;
2632 equation =
2633 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
2634 manifest = None; constraints = []};
2635 representation = None}
2636```
2637
2638
2639Expansion test
2640==============
2641
2642```ocaml env=e1
2643let test_data = {|
2644module type M = sig
2645 type t
2646end
2647
2648type u
2649
2650module type M1 = M with type t = u
2651|};;
2652let sg = Common.signature_of_mli_string test_data;;
2653```
2654
2655```ocaml env=e1
2656# Link.signature Env.empty id sg ;;
2657- : Odoc_model.Lang.Signature.t =
2658{Odoc_model.Lang.Signature.items =
2659 [Odoc_model.Lang.Signature.ModuleType
2660 {Odoc_model.Lang.ModuleType.id =
2661 {Odoc_model__Paths_types.iv =
2662 `ModuleType
2663 ({Odoc_model__Paths_types.iv =
2664 `Root
2665 (Some
2666 {Odoc_model__Paths_types.iv = `Page (None, None);
2667 ihash = 236059787; ikey = "p_None"},
2668 Root);
2669 ihash = 818126955; ikey = "r_Root.p_None"},
2670 M);
2671 ihash = 459143770; ikey = "mt_M.r_Root.p_None"};
2672 source_loc = None;
2673 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2674 canonical = None;
2675 expr =
2676 Some
2677 (Odoc_model.Lang.ModuleType.Signature
2678 {Odoc_model.Lang.Signature.items =
2679 [Odoc_model.Lang.Signature.Type
2680 (Odoc_model.Lang.Signature.Ordinary,
2681 {Odoc_model.Lang.TypeDecl.id =
2682 {Odoc_model__Paths_types.iv =
2683 `Type
2684 ({Odoc_model__Paths_types.iv =
2685 `ModuleType
2686 ({Odoc_model__Paths_types.iv =
2687 `Root
2688 (Some
2689 {Odoc_model__Paths_types.iv =
2690 `Page (None, None);
2691 ihash = 236059787; ikey = "p_None"},
2692 Root);
2693 ihash = 818126955; ikey = "r_Root.p_None"},
2694 M);
2695 ihash = 459143770; ikey = "mt_M.r_Root.p_None"},
2696 t);
2697 ihash = 825731485; ikey = "t_t.mt_M.r_Root.p_None"};
2698 source_loc = None;
2699 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2700 canonical = None;
2701 equation =
2702 {Odoc_model.Lang.TypeDecl.Equation.params = [];
2703 private_ = false; manifest = None; constraints = []};
2704 representation = None})];
2705 compiled = false; removed = [];
2706 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})};
2707 Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
2708 {Odoc_model.Lang.TypeDecl.id =
2709 {Odoc_model__Paths_types.iv =
2710 `Type
2711 ({Odoc_model__Paths_types.iv =
2712 `Root
2713 (Some
2714 {Odoc_model__Paths_types.iv = `Page (None, None);
2715 ihash = 236059787; ikey = "p_None"},
2716 Root);
2717 ihash = 818126955; ikey = "r_Root.p_None"},
2718 u);
2719 ihash = 15973539; ikey = "t_u.r_Root.p_None"};
2720 source_loc = None;
2721 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2722 canonical = None;
2723 equation =
2724 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
2725 manifest = None; constraints = []};
2726 representation = None});
2727 Odoc_model.Lang.Signature.ModuleType
2728 {Odoc_model.Lang.ModuleType.id =
2729 {Odoc_model__Paths_types.iv =
2730 `ModuleType
2731 ({Odoc_model__Paths_types.iv =
2732 `Root
2733 (Some
2734 {Odoc_model__Paths_types.iv = `Page (None, None);
2735 ihash = 236059787; ikey = "p_None"},
2736 Root);
2737 ihash = 818126955; ikey = "r_Root.p_None"},
2738 M1);
2739 ihash = 756272831; ikey = "mt_M1.r_Root.p_None"};
2740 source_loc = None;
2741 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2742 canonical = None;
2743 expr =
2744 Some
2745 (Odoc_model.Lang.ModuleType.With
2746 {Odoc_model.Lang.ModuleType.w_substitutions =
2747 [Odoc_model.Lang.ModuleType.TypeEq (`Dot (`Root, "t"),
2748 {Odoc_model.Lang.TypeDecl.Equation.params = [];
2749 private_ = false;
2750 manifest =
2751 Some
2752 (Odoc_model.Lang.TypeExpr.Constr
2753 (`Resolved
2754 (`Identifier
2755 {Odoc_model__Paths_types.iv =
2756 `Type
2757 ({Odoc_model__Paths_types.iv =
2758 `Root
2759 (Some
2760 {Odoc_model__Paths_types.iv =
2761 `Page (None, None);
2762 ihash = 236059787; ikey = "p_None"},
2763 Root);
2764 ihash = 818126955; ikey = "r_Root.p_None"},
2765 u);
2766 ihash = 15973539; ikey = "t_u.r_Root.p_None"}),
2767 []));
2768 constraints = []})];
2769 w_expansion = None;
2770 w_expr =
2771 Odoc_model.Lang.ModuleType.U.Path
2772 (`Resolved
2773 (`Identifier
2774 {Odoc_model__Paths_types.iv =
2775 `ModuleType
2776 ({Odoc_model__Paths_types.iv =
2777 `Root
2778 (Some
2779 {Odoc_model__Paths_types.iv = `Page (None, None);
2780 ihash = 236059787; ikey = "p_None"},
2781 Root);
2782 ihash = 818126955; ikey = "r_Root.p_None"},
2783 M);
2784 ihash = 459143770; ikey = "mt_M.r_Root.p_None"}))})}];
2785 compiled = false; removed = [];
2786 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
2787```
2788
2789# Expansion continued
2790
2791```ocaml env=e1
2792let test_data = {|
2793module Foo (X : sig end) : sig
2794 type t
2795 module type S = sig type s = C of t end
2796end
2797module Bar : sig end
2798module M : Foo(Bar).S
2799|};;
2800let sg = Common.signature_of_mli_string test_data;;
2801let resolved = Common.compile_signature sg;;
2802let expanded = Link.signature Env.empty id resolved;;
2803let module_M_expansion =
2804 let open Common.LangUtils.Lens in
2805 Signature.module_ "M" |-- Module.type_ |-~ Module.decl_moduletype
2806```
2807
2808```ocaml env=e1
2809# Common.LangUtils.Lens.get module_M_expansion expanded ;;
2810- : Odoc_model.Lang.ModuleType.expr =
2811Odoc_model.Lang.ModuleType.Path
2812 {Odoc_model.Lang.ModuleType.p_expansion =
2813 Some
2814 (Odoc_model.Lang.ModuleType.Signature
2815 {Odoc_model.Lang.Signature.items =
2816 [Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
2817 {Odoc_model.Lang.TypeDecl.id =
2818 {Odoc_model__Paths_types.iv =
2819 `Type
2820 ({Odoc_model__Paths_types.iv =
2821 `Module
2822 ({Odoc_model__Paths_types.iv =
2823 `Root
2824 (Some
2825 {Odoc_model__Paths_types.iv = `Page (None, None);
2826 ihash = 236059787; ikey = "p_None"},
2827 Root);
2828 ihash = 818126955; ikey = "r_Root.p_None"},
2829 M);
2830 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
2831 s);
2832 ihash = 395135148; ikey = "t_s.m_M.r_Root.p_None"};
2833 source_loc = None;
2834 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2835 canonical = None;
2836 equation =
2837 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
2838 manifest = None; constraints = []};
2839 representation =
2840 Some
2841 (Odoc_model.Lang.TypeDecl.Representation.Variant
2842 [{Odoc_model.Lang.TypeDecl.Constructor.id =
2843 {Odoc_model__Paths_types.iv =
2844 `Constructor
2845 ({Odoc_model__Paths_types.iv =
2846 `Type
2847 ({Odoc_model__Paths_types.iv =
2848 `Module
2849 ({Odoc_model__Paths_types.iv =
2850 `Root
2851 (Some
2852 {Odoc_model__Paths_types.iv =
2853 `Page (None, None);
2854 ihash = 236059787; ikey = "p_None"},
2855 Root);
2856 ihash = 818126955; ikey = "r_Root.p_None"},
2857 M);
2858 ihash = 716453475; ikey = "m_M.r_Root.p_None"},
2859 s);
2860 ihash = 395135148; ikey = "t_s.m_M.r_Root.p_None"},
2861 <abstr>);
2862 ihash = 2570800; ikey = "ctor_C.t_s.m_M.r_Root.p_None"};
2863 doc =
2864 {Odoc_model__.Comment.elements = []; warnings_tag = None};
2865 args =
2866 Odoc_model.Lang.TypeDecl.Constructor.Tuple
2867 [Odoc_model.Lang.TypeExpr.Constr
2868 (`Resolved
2869 (`Type
2870 (`Apply
2871 (`Identifier
2872 {Odoc_model__Paths_types.iv =
2873 `Module
2874 ({Odoc_model__Paths_types.iv =
2875 `Root
2876 (Some
2877 {Odoc_model__Paths_types.iv =
2878 `Page (None, None);
2879 ihash = 236059787;
2880 ikey = "p_None"},
2881 Root);
2882 ihash = 818126955;
2883 ikey = "r_Root.p_None"},
2884 Foo);
2885 ihash = 249248993;
2886 ikey = "m_Foo.r_Root.p_None"},
2887 `Identifier
2888 {Odoc_model__Paths_types.iv =
2889 `Module
2890 ({Odoc_model__Paths_types.iv =
2891 `Root
2892 (Some
2893 {Odoc_model__Paths_types.iv =
2894 `Page (None, None);
2895 ihash = 236059787;
2896 ikey = "p_None"},
2897 Root);
2898 ihash = 818126955;
2899 ikey = "r_Root.p_None"},
2900 Bar);
2901 ihash = 608577;
2902 ikey = "m_Bar.r_Root.p_None"}),
2903 t)),
2904 [])];
2905 res = None}])})];
2906 compiled = true; removed = [];
2907 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}});
2908 p_path =
2909 `Resolved
2910 (`ModuleType
2911 (`Apply
2912 (`Identifier
2913 {Odoc_model__Paths_types.iv =
2914 `Module
2915 ({Odoc_model__Paths_types.iv =
2916 `Root
2917 (Some
2918 {Odoc_model__Paths_types.iv = `Page (None, None);
2919 ihash = 236059787; ikey = "p_None"},
2920 Root);
2921 ihash = 818126955; ikey = "r_Root.p_None"},
2922 Foo);
2923 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
2924 `Identifier
2925 {Odoc_model__Paths_types.iv =
2926 `Module
2927 ({Odoc_model__Paths_types.iv =
2928 `Root
2929 (Some
2930 {Odoc_model__Paths_types.iv = `Page (None, None);
2931 ihash = 236059787; ikey = "p_None"},
2932 Root);
2933 ihash = 818126955; ikey = "r_Root.p_None"},
2934 Bar);
2935 ihash = 608577; ikey = "m_Bar.r_Root.p_None"}),
2936 S))}
2937```
2938
2939# Shadowing
2940
2941Let's see what happens when we have nested shadowing:
2942
2943<!-- $MDX version>=4.08,env=e1 -->
2944```ocaml
2945let test_data = {|
2946module Foo : sig
2947 type t
2948 val id : t
2949end
2950
2951module Foo2 : sig
2952 include module type of struct include Foo end
2953 type t
2954 val id2 : t
2955end
2956
2957module Foo3 : sig
2958 include module type of struct include Foo2 end
2959 type t
2960 val id3 : t
2961end
2962|};;
2963let sg = Common.signature_of_mli_string test_data;;
2964let module_expansion_include_sig name n =
2965 let open Common.LangUtils.Lens in
2966 Signature.module_ name |-- Module.type_ |-~ Module.decl_moduletype |-~ ModuleType.expr_signature |-- Signature.includes |-~ nth n |-- Include.expansion_sig
2967let m_e_i_s_value mod_name n val_name =
2968 let open Common.LangUtils.Lens in
2969 module_expansion_include_sig mod_name n |-- Signature.value val_name
2970```
2971
2972<!-- $MDX version>=4.08,env=e1 -->
2973```ocaml
2974# Common.LangUtils.Lens.get (m_e_i_s_value "Foo3" 0 "id") sg;;
2975- : Odoc_model.Lang.Value.t =
2976{Odoc_model.Lang.Value.id =
2977 {Odoc_model__Paths_types.iv =
2978 `Value
2979 ({Odoc_model__Paths_types.iv =
2980 `Module
2981 ({Odoc_model__Paths_types.iv =
2982 `Root
2983 (Some
2984 {Odoc_model__Paths_types.iv = `Page (None, None);
2985 ihash = 236059787; ikey = "p_None"},
2986 Root);
2987 ihash = 818126955; ikey = "r_Root.p_None"},
2988 Foo3);
2989 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
2990 id);
2991 ihash = 424389437; ikey = "v_id.m_Foo3.r_Root.p_None"};
2992 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
2993 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
2994 type_ =
2995 Odoc_model.Lang.TypeExpr.Constr
2996 (`DotT
2997 (`Identifier
2998 ({Odoc_model__Paths_types.iv =
2999 `Module
3000 ({Odoc_model__Paths_types.iv =
3001 `Root
3002 (Some
3003 {Odoc_model__Paths_types.iv = `Page (None, None);
3004 ihash = 236059787; ikey = "p_None"},
3005 Root);
3006 ihash = 818126955; ikey = "r_Root.p_None"},
3007 Foo);
3008 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
3009 false),
3010 t),
3011 [])}
3012# Common.LangUtils.Lens.get (m_e_i_s_value "Foo3" 0 "id2") sg;;
3013- : Odoc_model.Lang.Value.t =
3014{Odoc_model.Lang.Value.id =
3015 {Odoc_model__Paths_types.iv =
3016 `Value
3017 ({Odoc_model__Paths_types.iv =
3018 `Module
3019 ({Odoc_model__Paths_types.iv =
3020 `Root
3021 (Some
3022 {Odoc_model__Paths_types.iv = `Page (None, None);
3023 ihash = 236059787; ikey = "p_None"},
3024 Root);
3025 ihash = 818126955; ikey = "r_Root.p_None"},
3026 Foo3);
3027 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3028 id2);
3029 ihash = 412619918; ikey = "v_id2.m_Foo3.r_Root.p_None"};
3030 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3031 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3032 type_ =
3033 Odoc_model.Lang.TypeExpr.Constr
3034 (`Identifier
3035 ({Odoc_model__Paths_types.iv =
3036 `Type
3037 ({Odoc_model__Paths_types.iv =
3038 `Module
3039 ({Odoc_model__Paths_types.iv =
3040 `Root
3041 (Some
3042 {Odoc_model__Paths_types.iv = `Page (None, None);
3043 ihash = 236059787; ikey = "p_None"},
3044 Root);
3045 ihash = 818126955; ikey = "r_Root.p_None"},
3046 Foo3);
3047 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3048 {t}2/shadowed/(XXXX));
3049 ihash = 975388256;
3050 ikey = "t_{t}2/shadowed/(XXXX).m_Foo3.r_Root.p_None"},
3051 false),
3052 [])}
3053```
3054
3055
3056And what happens when we include multiple things defining a `t`?
3057
3058<!-- $MDX version>=4.08,env=e1 -->
3059```ocaml
3060let test_data = {|
3061module Foo : sig
3062 type t
3063 val id : t
3064end
3065
3066module Foo2 : sig
3067 type t
3068 val id2 : t
3069end
3070
3071module Foo3 : sig
3072 include module type of struct include Foo end
3073 include module type of struct include Foo2 end
3074 type t
3075 val id3 : t
3076end
3077|};;
3078let sg = Common.signature_of_mli_string test_data;;
3079```
3080
3081<!-- $MDX version>=4.08,env=e1 -->
3082```ocaml
3083# Common.LangUtils.Lens.get (module_expansion_include_sig "Foo3" 0) sg;;
3084- : Odoc_model.Lang.Signature.t =
3085{Odoc_model.Lang.Signature.items =
3086 [Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
3087 {Odoc_model.Lang.TypeDecl.id =
3088 {Odoc_model__Paths_types.iv =
3089 `Type
3090 ({Odoc_model__Paths_types.iv =
3091 `Module
3092 ({Odoc_model__Paths_types.iv =
3093 `Root
3094 (Some
3095 {Odoc_model__Paths_types.iv = `Page (None, None);
3096 ihash = 236059787; ikey = "p_None"},
3097 Root);
3098 ihash = 818126955; ikey = "r_Root.p_None"},
3099 Foo3);
3100 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3101 {t}3/shadowed/(XXXX));
3102 ihash = 584226322;
3103 ikey = "t_{t}3/shadowed/(XXXX).m_Foo3.r_Root.p_None"};
3104 source_loc = None;
3105 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3106 canonical = None;
3107 equation =
3108 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
3109 manifest =
3110 Some
3111 (Odoc_model.Lang.TypeExpr.Constr
3112 (`DotT
3113 (`Identifier
3114 ({Odoc_model__Paths_types.iv =
3115 `Module
3116 ({Odoc_model__Paths_types.iv =
3117 `Root
3118 (Some
3119 {Odoc_model__Paths_types.iv = `Page (None, None);
3120 ihash = 236059787; ikey = "p_None"},
3121 Root);
3122 ihash = 818126955; ikey = "r_Root.p_None"},
3123 Foo);
3124 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
3125 false),
3126 t),
3127 []));
3128 constraints = []};
3129 representation = None});
3130 Odoc_model.Lang.Signature.Value
3131 {Odoc_model.Lang.Value.id =
3132 {Odoc_model__Paths_types.iv =
3133 `Value
3134 ({Odoc_model__Paths_types.iv =
3135 `Module
3136 ({Odoc_model__Paths_types.iv =
3137 `Root
3138 (Some
3139 {Odoc_model__Paths_types.iv = `Page (None, None);
3140 ihash = 236059787; ikey = "p_None"},
3141 Root);
3142 ihash = 818126955; ikey = "r_Root.p_None"},
3143 Foo3);
3144 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3145 id);
3146 ihash = 424389437; ikey = "v_id.m_Foo3.r_Root.p_None"};
3147 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3148 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3149 type_ =
3150 Odoc_model.Lang.TypeExpr.Constr
3151 (`Identifier
3152 ({Odoc_model__Paths_types.iv =
3153 `Type
3154 ({Odoc_model__Paths_types.iv =
3155 `Module
3156 ({Odoc_model__Paths_types.iv =
3157 `Root
3158 (Some
3159 {Odoc_model__Paths_types.iv = `Page (None, None);
3160 ihash = 236059787; ikey = "p_None"},
3161 Root);
3162 ihash = 818126955; ikey = "r_Root.p_None"},
3163 Foo3);
3164 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3165 {t}3/shadowed/(XXXX));
3166 ihash = 584226322;
3167 ikey = "t_{t}3/shadowed/(XXXX).m_Foo3.r_Root.p_None"},
3168 false),
3169 [])}];
3170 compiled = false; removed = [];
3171 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
3172# Common.LangUtils.Lens.get (module_expansion_include_sig "Foo3" 1) sg;;
3173- : Odoc_model.Lang.Signature.t =
3174{Odoc_model.Lang.Signature.items =
3175 [Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
3176 {Odoc_model.Lang.TypeDecl.id =
3177 {Odoc_model__Paths_types.iv =
3178 `Type
3179 ({Odoc_model__Paths_types.iv =
3180 `Module
3181 ({Odoc_model__Paths_types.iv =
3182 `Root
3183 (Some
3184 {Odoc_model__Paths_types.iv = `Page (None, None);
3185 ihash = 236059787; ikey = "p_None"},
3186 Root);
3187 ihash = 818126955; ikey = "r_Root.p_None"},
3188 Foo3);
3189 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3190 {t}4/shadowed/(XXXX));
3191 ihash = 466750041;
3192 ikey = "t_{t}4/shadowed/(XXXX).m_Foo3.r_Root.p_None"};
3193 source_loc = None;
3194 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3195 canonical = None;
3196 equation =
3197 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
3198 manifest =
3199 Some
3200 (Odoc_model.Lang.TypeExpr.Constr
3201 (`DotT
3202 (`Identifier
3203 ({Odoc_model__Paths_types.iv =
3204 `Module
3205 ({Odoc_model__Paths_types.iv =
3206 `Root
3207 (Some
3208 {Odoc_model__Paths_types.iv = `Page (None, None);
3209 ihash = 236059787; ikey = "p_None"},
3210 Root);
3211 ihash = 818126955; ikey = "r_Root.p_None"},
3212 Foo2);
3213 ihash = 926621908; ikey = "m_Foo2.r_Root.p_None"},
3214 false),
3215 t),
3216 []));
3217 constraints = []};
3218 representation = None});
3219 Odoc_model.Lang.Signature.Value
3220 {Odoc_model.Lang.Value.id =
3221 {Odoc_model__Paths_types.iv =
3222 `Value
3223 ({Odoc_model__Paths_types.iv =
3224 `Module
3225 ({Odoc_model__Paths_types.iv =
3226 `Root
3227 (Some
3228 {Odoc_model__Paths_types.iv = `Page (None, None);
3229 ihash = 236059787; ikey = "p_None"},
3230 Root);
3231 ihash = 818126955; ikey = "r_Root.p_None"},
3232 Foo3);
3233 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3234 id2);
3235 ihash = 412619918; ikey = "v_id2.m_Foo3.r_Root.p_None"};
3236 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3237 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3238 type_ =
3239 Odoc_model.Lang.TypeExpr.Constr
3240 (`Identifier
3241 ({Odoc_model__Paths_types.iv =
3242 `Type
3243 ({Odoc_model__Paths_types.iv =
3244 `Module
3245 ({Odoc_model__Paths_types.iv =
3246 `Root
3247 (Some
3248 {Odoc_model__Paths_types.iv = `Page (None, None);
3249 ihash = 236059787; ikey = "p_None"},
3250 Root);
3251 ihash = 818126955; ikey = "r_Root.p_None"},
3252 Foo3);
3253 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3254 {t}4/shadowed/(XXXX));
3255 ihash = 466750041;
3256 ikey = "t_{t}4/shadowed/(XXXX).m_Foo3.r_Root.p_None"},
3257 false),
3258 [])}];
3259 compiled = false; removed = [];
3260 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
3261```
3262
3263
3264And what happens when we override values?
3265
3266<!-- $MDX version>=4.08,env=e1 -->
3267```ocaml
3268let test_data = {|
3269module Foo : sig
3270 type t
3271 val x : int
3272 val id : t
3273end
3274
3275module Foo2 : sig
3276 type t
3277 val id2 : t
3278end
3279
3280module Foo3 : sig
3281 include module type of struct include Foo end
3282 include module type of struct include Foo2 end
3283 type t
3284 val x : float
3285 val id3 : t
3286end
3287|};;
3288let sg = Common.signature_of_mli_string test_data;;
3289```
3290
3291<!-- $MDX version>=4.08,env=e1 -->
3292```ocaml
3293# Common.LangUtils.Lens.get (module_expansion_include_sig "Foo3" 0) sg;;
3294- : Odoc_model.Lang.Signature.t =
3295{Odoc_model.Lang.Signature.items =
3296 [Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary,
3297 {Odoc_model.Lang.TypeDecl.id =
3298 {Odoc_model__Paths_types.iv =
3299 `Type
3300 ({Odoc_model__Paths_types.iv =
3301 `Module
3302 ({Odoc_model__Paths_types.iv =
3303 `Root
3304 (Some
3305 {Odoc_model__Paths_types.iv = `Page (None, None);
3306 ihash = 236059787; ikey = "p_None"},
3307 Root);
3308 ihash = 818126955; ikey = "r_Root.p_None"},
3309 Foo3);
3310 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3311 {t}5/shadowed/(XXXX));
3312 ihash = 995358055;
3313 ikey = "t_{t}5/shadowed/(XXXX).m_Foo3.r_Root.p_None"};
3314 source_loc = None;
3315 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3316 canonical = None;
3317 equation =
3318 {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false;
3319 manifest =
3320 Some
3321 (Odoc_model.Lang.TypeExpr.Constr
3322 (`DotT
3323 (`Identifier
3324 ({Odoc_model__Paths_types.iv =
3325 `Module
3326 ({Odoc_model__Paths_types.iv =
3327 `Root
3328 (Some
3329 {Odoc_model__Paths_types.iv = `Page (None, None);
3330 ihash = 236059787; ikey = "p_None"},
3331 Root);
3332 ihash = 818126955; ikey = "r_Root.p_None"},
3333 Foo);
3334 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
3335 false),
3336 t),
3337 []));
3338 constraints = []};
3339 representation = None});
3340 Odoc_model.Lang.Signature.Value
3341 {Odoc_model.Lang.Value.id =
3342 {Odoc_model__Paths_types.iv =
3343 `Value
3344 ({Odoc_model__Paths_types.iv =
3345 `Module
3346 ({Odoc_model__Paths_types.iv =
3347 `Root
3348 (Some
3349 {Odoc_model__Paths_types.iv = `Page (None, None);
3350 ihash = 236059787; ikey = "p_None"},
3351 Root);
3352 ihash = 818126955; ikey = "r_Root.p_None"},
3353 Foo3);
3354 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3355 {x}6/shadowed/(XXXX));
3356 ihash = 1011043008;
3357 ikey = "v_{x}6/shadowed/(XXXX).m_Foo3.r_Root.p_None"};
3358 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3359 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3360 type_ = Odoc_model.Lang.TypeExpr.Constr (`Resolved (`CoreType int), [])};
3361 Odoc_model.Lang.Signature.Value
3362 {Odoc_model.Lang.Value.id =
3363 {Odoc_model__Paths_types.iv =
3364 `Value
3365 ({Odoc_model__Paths_types.iv =
3366 `Module
3367 ({Odoc_model__Paths_types.iv =
3368 `Root
3369 (Some
3370 {Odoc_model__Paths_types.iv = `Page (None, None);
3371 ihash = 236059787; ikey = "p_None"},
3372 Root);
3373 ihash = 818126955; ikey = "r_Root.p_None"},
3374 Foo3);
3375 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3376 id);
3377 ihash = 424389437; ikey = "v_id.m_Foo3.r_Root.p_None"};
3378 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3379 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3380 type_ =
3381 Odoc_model.Lang.TypeExpr.Constr
3382 (`Identifier
3383 ({Odoc_model__Paths_types.iv =
3384 `Type
3385 ({Odoc_model__Paths_types.iv =
3386 `Module
3387 ({Odoc_model__Paths_types.iv =
3388 `Root
3389 (Some
3390 {Odoc_model__Paths_types.iv = `Page (None, None);
3391 ihash = 236059787; ikey = "p_None"},
3392 Root);
3393 ihash = 818126955; ikey = "r_Root.p_None"},
3394 Foo3);
3395 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3396 {t}5/shadowed/(XXXX));
3397 ihash = 995358055;
3398 ikey = "t_{t}5/shadowed/(XXXX).m_Foo3.r_Root.p_None"},
3399 false),
3400 [])}];
3401 compiled = false; removed = [];
3402 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
3403```
3404
3405
3406And overriding modules?
3407
3408<!-- $MDX version>=4.08,env=e1 -->
3409```ocaml
3410let test_data = {|
3411module Foo : sig
3412 module Bar : sig
3413 type t
3414 end
3415
3416 val id : Bar.t
3417end
3418
3419module Foo3 : sig
3420 include module type of struct include Foo end
3421
3422 module Bar : sig
3423 type u
3424 end
3425
3426 val id3 : Bar.u
3427end
3428|};;
3429let sg = Common.signature_of_mli_string test_data;;
3430```
3431
3432<!-- $MDX version>=4.08,env=e1 -->
3433```ocaml
3434# Common.LangUtils.Lens.get (module_expansion_include_sig "Foo3" 0) sg;;
3435- : Odoc_model.Lang.Signature.t =
3436{Odoc_model.Lang.Signature.items =
3437 [Odoc_model.Lang.Signature.Module (Odoc_model.Lang.Signature.Ordinary,
3438 {Odoc_model.Lang.Module.id =
3439 {Odoc_model__Paths_types.iv =
3440 `Module
3441 ({Odoc_model__Paths_types.iv =
3442 `Module
3443 ({Odoc_model__Paths_types.iv =
3444 `Root
3445 (Some
3446 {Odoc_model__Paths_types.iv = `Page (None, None);
3447 ihash = 236059787; ikey = "p_None"},
3448 Root);
3449 ihash = 818126955; ikey = "r_Root.p_None"},
3450 Foo3);
3451 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3452 {Bar}8/shadowed/(XXXX));
3453 ihash = 38422300;
3454 ikey = "m_{Bar}8/shadowed/(XXXX).m_Foo3.r_Root.p_None"};
3455 source_loc = None;
3456 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3457 type_ =
3458 Odoc_model.Lang.Module.Alias
3459 (`Dot
3460 (`Identifier
3461 ({Odoc_model__Paths_types.iv =
3462 `Module
3463 ({Odoc_model__Paths_types.iv =
3464 `Root
3465 (Some
3466 {Odoc_model__Paths_types.iv = `Page (None, None);
3467 ihash = 236059787; ikey = "p_None"},
3468 Root);
3469 ihash = 818126955; ikey = "r_Root.p_None"},
3470 Foo);
3471 ihash = 249248993; ikey = "m_Foo.r_Root.p_None"},
3472 false),
3473 Bar),
3474 None);
3475 canonical = None; hidden = false});
3476 Odoc_model.Lang.Signature.Value
3477 {Odoc_model.Lang.Value.id =
3478 {Odoc_model__Paths_types.iv =
3479 `Value
3480 ({Odoc_model__Paths_types.iv =
3481 `Module
3482 ({Odoc_model__Paths_types.iv =
3483 `Root
3484 (Some
3485 {Odoc_model__Paths_types.iv = `Page (None, None);
3486 ihash = 236059787; ikey = "p_None"},
3487 Root);
3488 ihash = 818126955; ikey = "r_Root.p_None"},
3489 Foo3);
3490 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3491 id);
3492 ihash = 424389437; ikey = "v_id.m_Foo3.r_Root.p_None"};
3493 source_loc = None; value = Odoc_model.Lang.Value.Abstract;
3494 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None};
3495 type_ =
3496 Odoc_model.Lang.TypeExpr.Constr
3497 (`DotT
3498 (`Identifier
3499 ({Odoc_model__Paths_types.iv =
3500 `Module
3501 ({Odoc_model__Paths_types.iv =
3502 `Module
3503 ({Odoc_model__Paths_types.iv =
3504 `Root
3505 (Some
3506 {Odoc_model__Paths_types.iv =
3507 `Page (None, None);
3508 ihash = 236059787; ikey = "p_None"},
3509 Root);
3510 ihash = 818126955; ikey = "r_Root.p_None"},
3511 Foo3);
3512 ihash = 670280318; ikey = "m_Foo3.r_Root.p_None"},
3513 {Bar}8/shadowed/(XXXX));
3514 ihash = 38422300;
3515 ikey = "m_{Bar}8/shadowed/(XXXX).m_Foo3.r_Root.p_None"},
3516 true),
3517 t),
3518 [])}];
3519 compiled = false; removed = [];
3520 doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}
3521```