this repo has no description
at main 3521 lines 131 kB view raw view rendered
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```