Skip to content

Commit 956f2ca

Browse files
committed
Remove expansion from "unexpanded" module type of
We've been keeping each `module type of` expression's expansion around, even in the nominally unexpanded version of the type. This was needed in case the expression was invalidated so that we had the expansion on hand as a fallback. However, it led to exponential blowup in the case of deeply nested `module type of`s. Happily, we can do without the expansion if we do a little more work when substituting: We already track in the `subst` which module paths have been invalidated. When we need to invalidate a module path, we can stash the expression for the module's type in that `subst`. This is effectively the same data that we were keeping in the "unexpanded" expansion. And then when we need to expand an invalidated `module type of`, we can use the stashed expression.
1 parent 72ac2cf commit 956f2ca

File tree

16 files changed

+1341
-131
lines changed

16 files changed

+1341
-131
lines changed

src/document/generator.ml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,7 @@ module Make (Syntax : SYNTAX) = struct
15101510
and umty_hidden : Odoc_model.Lang.ModuleType.U.expr -> bool = function
15111511
| Path p -> Paths.Path.(is_hidden (p :> t))
15121512
| With (_, expr) -> umty_hidden expr
1513-
| TypeOf { t_desc = ModPath m; _ }
1514-
| TypeOf { t_desc = StructInclude m; _ } ->
1513+
| TypeOf (ModPath m) | TypeOf (StructInclude m) ->
15151514
Paths.Path.(is_hidden (m :> t))
15161515
| Signature _ -> false
15171516

@@ -1559,7 +1558,7 @@ module Make (Syntax : SYNTAX) = struct
15591558
| With (_, expr) when is_elidable_with_u expr ->
15601559
Syntax.Mod.open_tag ++ O.txt " ... " ++ Syntax.Mod.close_tag
15611560
| With (subs, expr) -> mty_with subs expr
1562-
| TypeOf { t_desc; _ } -> mty_typeof t_desc
1561+
| TypeOf t -> mty_typeof t
15631562

15641563
and mty : Odoc_model.Lang.ModuleType.expr -> text =
15651564
fun m ->

src/loader/cmt.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ and read_include env parent incl =
544544
let decl_modty =
545545
match unwrap_module_expr_desc incl.incl_mod.mod_desc with
546546
| Tmod_ident(p, _) ->
547-
Some (ModuleType.U.TypeOf {t_desc = ModuleType.StructInclude (Env.Path.read_module env p); t_expansion=None })
547+
Some (ModuleType.U.TypeOf (ModuleType.StructInclude (Env.Path.read_module env p)))
548548
| _ ->
549549
let mty = read_module_expr env parent container incl.incl_mod in
550550
umty_of_mty mty

src/model/lang.ml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,12 @@ and ModuleType : sig
9292
| Signature of Signature.t
9393
| Functor of FunctorParameter.t * simple_expansion
9494

95-
type typeof_t = {
96-
t_desc : type_of_desc;
97-
t_expansion : simple_expansion option;
98-
}
99-
10095
module U : sig
10196
type expr =
10297
| Path of Path.ModuleType.t
10398
| Signature of Signature.t
10499
| With of substitution list * expr
105-
| TypeOf of typeof_t
106-
107-
(* Nb. this may have an expansion! *)
100+
| TypeOf of type_of_desc
108101
end
109102

110103
type path_t = {
@@ -118,6 +111,11 @@ and ModuleType : sig
118111
w_expr : U.expr;
119112
}
120113

114+
type typeof_t = {
115+
t_desc : type_of_desc;
116+
t_expansion : simple_expansion option;
117+
}
118+
121119
type expr =
122120
| Path of path_t
123121
| Signature of Signature.t
@@ -534,7 +532,7 @@ let umty_of_mty : ModuleType.expr -> ModuleType.U.expr option = function
534532
| Signature sg -> Some (Signature sg)
535533
| Path { p_path; _ } -> Some (Path p_path)
536534
| Functor _ -> None
537-
| TypeOf t -> Some (TypeOf t)
535+
| TypeOf t -> Some (TypeOf t.t_desc)
538536
| With { w_substitutions; w_expr; _ } -> Some (With (w_substitutions, w_expr))
539537

540538
(** Query the top-comment of a signature. This is [s.doc] most of the time with

src/model_desc/lang_desc.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ and moduletype_u_expr =
173173
( "With",
174174
(t, e),
175175
Pair (List moduletype_substitution, moduletype_u_expr) )
176-
| TypeOf x -> C ("TypeOf", x, moduletype_typeof_t))
176+
| TypeOf x -> C ("TypeOf", x, moduletype_type_of_desc))
177177

178178
and moduletype_t =
179179
let open Lang.ModuleType in

src/xref2/compile.ml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,7 @@ and module_type_map_subs env id cexpr subs =
592592
| Path (`Resolved p) -> Some (`ModuleType p)
593593
| Path _ -> None
594594
| With (_, e) -> find_parent e
595-
| TypeOf { t_desc = ModPath (`Resolved p); _ }
596-
| TypeOf { t_desc = StructInclude (`Resolved p); _ } ->
595+
| TypeOf (ModPath (`Resolved p)) | TypeOf (StructInclude (`Resolved p)) ->
597596
Some (`Module p)
598597
| TypeOf _ -> None
599598
in
@@ -635,13 +634,13 @@ and u_module_type_expr :
635634
in
636635
let result : ModuleType.U.expr = With (subs', expr') in
637636
result
638-
| TypeOf { t_desc; t_expansion } ->
639-
let t_desc =
640-
match t_desc with
637+
| TypeOf t ->
638+
let t =
639+
match t with
641640
| ModPath p -> ModPath (module_path env p)
642641
| StructInclude p -> StructInclude (module_path env p)
643642
in
644-
TypeOf { t_desc; t_expansion }
643+
TypeOf t
645644
in
646645
inner expr
647646

src/xref2/component.ml

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,12 @@ and ModuleType : sig
199199
| Signature of Signature.t
200200
| Functor of FunctorParameter.t * simple_expansion
201201

202-
type typeof_t = {
203-
t_desc : type_of_desc;
204-
t_expansion : simple_expansion option;
205-
}
206-
207202
module U : sig
208203
type expr =
209204
| Path of Cpath.module_type
210205
| Signature of Signature.t
211206
| With of substitution list * expr
212-
| TypeOf of typeof_t
207+
| TypeOf of type_of_desc
213208
end
214209

215210
type path_t = {
@@ -223,6 +218,11 @@ and ModuleType : sig
223218
w_expr : U.expr;
224219
}
225220

221+
type typeof_t = {
222+
t_desc : type_of_desc;
223+
t_expansion : simple_expansion option;
224+
}
225+
226226
type expr =
227227
| Path of path_t
228228
| Signature of Signature.t
@@ -455,7 +455,7 @@ and Substitution : sig
455455
type_replacement : (TypeExpr.t * TypeDecl.Equation.t) PathTypeMap.t;
456456
module_type_replacement : ModuleType.expr ModuleTypeMap.t;
457457
path_invalidating_modules : Ident.path_module list;
458-
module_type_of_invalidating_modules : Ident.path_module list;
458+
module_type_of_invalidating_modules : ModuleType.expr PathModuleMap.t;
459459
unresolve_opaque_paths : bool;
460460
}
461461
end =
@@ -744,7 +744,7 @@ module Fmt = struct
744744
| With (subs, e) ->
745745
Format.fprintf ppf "%a with [%a]" u_module_type_expr e substitution_list
746746
subs
747-
| TypeOf { t_desc; _ } -> module_type_type_of_desc ppf t_desc
747+
| TypeOf t -> module_type_type_of_desc ppf t
748748

749749
and module_type_expr ppf mt =
750750
let open ModuleType in
@@ -2121,14 +2121,13 @@ module Of_Lang = struct
21212121
| With (w, e) ->
21222122
let w' = List.map (with_module_type_substitution ident_map) w in
21232123
With (w', u_module_type_expr ident_map e)
2124-
| TypeOf { t_desc; t_expansion } ->
2125-
let t_desc =
2126-
match t_desc with
2124+
| TypeOf t ->
2125+
let t =
2126+
match t with
21272127
| ModPath p -> ModuleType.ModPath (module_path ident_map p)
21282128
| StructInclude p -> StructInclude (module_path ident_map p)
21292129
in
2130-
let t_expansion = Opt.map (simple_expansion ident_map) t_expansion in
2131-
TypeOf { t_desc; t_expansion }
2130+
TypeOf t
21322131

21332132
and module_type_expr ident_map m =
21342133
let open Odoc_model in

src/xref2/component.mli

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,12 @@ and ModuleType : sig
182182
| Signature of Signature.t
183183
| Functor of FunctorParameter.t * simple_expansion
184184

185-
type typeof_t = {
186-
t_desc : type_of_desc;
187-
t_expansion : simple_expansion option;
188-
}
189-
190185
module U : sig
191186
type expr =
192187
| Path of Cpath.module_type
193188
| Signature of Signature.t
194189
| With of substitution list * expr
195-
| TypeOf of typeof_t
190+
| TypeOf of type_of_desc
196191
end
197192

198193
type path_t = {
@@ -206,6 +201,11 @@ and ModuleType : sig
206201
w_expr : U.expr;
207202
}
208203

204+
type typeof_t = {
205+
t_desc : type_of_desc;
206+
t_expansion : simple_expansion option;
207+
}
208+
209209
type expr =
210210
| Path of path_t
211211
| Signature of Signature.t
@@ -426,7 +426,7 @@ and Substitution : sig
426426
type_replacement : (TypeExpr.t * TypeDecl.Equation.t) PathTypeMap.t;
427427
module_type_replacement : ModuleType.expr ModuleTypeMap.t;
428428
path_invalidating_modules : Ident.path_module list;
429-
module_type_of_invalidating_modules : Ident.path_module list;
429+
module_type_of_invalidating_modules : ModuleType.expr PathModuleMap.t;
430430
unresolve_opaque_paths : bool;
431431
}
432432
end

src/xref2/expand_tools.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ let handle_expansion env id expansion =
2525
Subst.add_module (arg.id :> Ident.path_module) p rp Subst.identity
2626
in
2727
let subst =
28-
Subst.mto_invalidate_module (arg.id :> Ident.path_module) subst
28+
Subst.mto_invalidate_module
29+
(arg.id :> Ident.path_module)
30+
arg.expr subst
2931
in
3032
(env', Subst.module_type_expr subst expr)
3133
in

src/xref2/lang_of.ml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -772,18 +772,8 @@ and u_module_type_expr map identifier = function
772772
With
773773
( List.map (mty_substitution map identifier) subs,
774774
u_module_type_expr map identifier expr )
775-
| TypeOf { t_desc = ModPath p; t_expansion } ->
776-
TypeOf
777-
{
778-
t_desc = ModPath (Path.module_ map p);
779-
t_expansion = Opt.map (simple_expansion map identifier) t_expansion;
780-
}
781-
| TypeOf { t_desc = StructInclude p; t_expansion } ->
782-
TypeOf
783-
{
784-
t_desc = StructInclude (Path.module_ map p);
785-
t_expansion = Opt.map (simple_expansion map identifier) t_expansion;
786-
}
775+
| TypeOf (ModPath p) -> TypeOf (ModPath (Path.module_ map p))
776+
| TypeOf (StructInclude p) -> TypeOf (StructInclude (Path.module_ map p))
787777

788778
and module_type_expr map identifier = function
789779
| Component.ModuleType.Path { p_path; p_expansion } ->

src/xref2/link.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,8 @@ and u_module_type_expr :
748748
| Error e ->
749749
Errors.report ~what:(`Module_type_U cexpr) ~tools_error:e `Resolve;
750750
unresolved)
751-
| TypeOf { t_desc = StructInclude p; t_expansion } ->
752-
TypeOf { t_desc = StructInclude (module_path env p); t_expansion }
753-
| TypeOf { t_desc = ModPath p; t_expansion } ->
754-
TypeOf { t_desc = ModPath (module_path env p); t_expansion }
751+
| TypeOf (StructInclude p) -> TypeOf (StructInclude (module_path env p))
752+
| TypeOf (ModPath p) -> TypeOf (ModPath (module_path env p))
755753

756754
and module_type_expr :
757755
Env.t -> Id.Signature.t -> ModuleType.expr -> ModuleType.expr =

0 commit comments

Comments
 (0)