Skip to content

Commit c90da2e

Browse files
authored
Fix exponential short-paths issue (#182)
* Fix exponential short-paths issue * Revert "Fix exponential short-paths issue" This reverts commit 263e7ac. * Avoid exponential expansion by only calling find_module when necessary
1 parent 77eb6cb commit c90da2e

File tree

1 file changed

+121
-24
lines changed

1 file changed

+121
-24
lines changed

src/ocaml/typing/short_paths_graph.ml

Lines changed: 121 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ module rec Type : sig
265265

266266
val resolve : Graph.t -> t -> resolved
267267

268+
val is_defined : t -> bool
269+
268270
end = struct
269271

270272
open Desc.Type
@@ -351,12 +353,23 @@ end = struct
351353
end
352354

353355
let normalize root t =
354-
match t with
355-
| Definition { sort = Sort.Defined } -> normalize_loop root t
356-
| Definition { sort = Sort.Declared _ } | Declaration _ ->
357-
match Graph.find_type root (raw_path t) with
358-
| exception Not_found -> normalize_loop root t
359-
| t -> normalize_loop root t
356+
(* If [t] is a declaration but it's defined in [root], then we need to look it up in
357+
[root] before continuing normalization. *)
358+
let need_to_check_root =
359+
match t with
360+
| Definition { sort = Sort.Defined } -> false
361+
| Definition { sort = Sort.Declared ids } ->
362+
Ident_set.exists (Graph.is_type_defined root) ids
363+
| Declaration { id; _} -> Graph.is_type_defined root id
364+
in
365+
let t =
366+
if need_to_check_root
367+
then
368+
try Graph.find_type root (raw_path t)
369+
with Not_found -> t
370+
else t
371+
in
372+
normalize_loop root t
360373

361374
let origin root t =
362375
raw_origin (normalize root t)
@@ -388,6 +401,11 @@ end = struct
388401
end
389402
| Definition { definition = Alias _ } -> assert false
390403

404+
let is_defined t =
405+
match t with
406+
| Declaration _ -> false
407+
| Definition _ -> true
408+
391409
end
392410

393411
and Class_type : sig
@@ -417,6 +435,8 @@ and Class_type : sig
417435

418436
val resolve : Graph.t -> t -> resolved
419437

438+
val is_defined : t -> bool
439+
420440
end = struct
421441

422442
open Desc.Class_type
@@ -501,12 +521,23 @@ end = struct
501521
end
502522

503523
let normalize root t =
504-
match t with
505-
| Definition { sort = Sort.Defined } -> normalize_loop root t
506-
| Definition { sort = Sort.Declared _ } | Declaration _ ->
507-
match Graph.find_class_type root (raw_path t) with
508-
| exception Not_found -> normalize_loop root t
509-
| t -> normalize_loop root t
524+
(* If [t] is a declaration but it's defined in [root], then we need to look it up in
525+
[root] before continuing normalization. *)
526+
let need_to_check_root =
527+
match t with
528+
| Definition { sort = Sort.Defined } -> false
529+
| Definition { sort = Sort.Declared ids } ->
530+
Ident_set.exists (Graph.is_class_type_defined root) ids
531+
| Declaration { id; _} -> Graph.is_class_type_defined root id
532+
in
533+
let t =
534+
if need_to_check_root
535+
then
536+
try Graph.find_class_type root (raw_path t)
537+
with Not_found -> t
538+
else t
539+
in
540+
normalize_loop root t
510541

511542
let origin root t =
512543
raw_origin (normalize root t)
@@ -534,6 +565,11 @@ end = struct
534565
end
535566
| Definition { definition = Alias _ } -> assert false
536567

568+
let is_defined t =
569+
match t with
570+
| Declaration _ -> false
571+
| Definition _ -> true
572+
537573
end
538574

539575
and Module_type : sig
@@ -559,6 +595,8 @@ and Module_type : sig
559595

560596
val sort : Graph.t -> t -> Sort.t
561597

598+
val is_defined : t -> bool
599+
562600
end = struct
563601

564602
open Desc.Module_type
@@ -645,12 +683,23 @@ end = struct
645683
end
646684

647685
let normalize root t =
648-
match t with
649-
| Definition { sort = Sort.Defined } -> normalize_loop root t
650-
| Definition { sort = Sort.Declared _ } | Declaration _ ->
651-
match Graph.find_module_type root (raw_path t) with
652-
| exception Not_found -> normalize_loop root t
653-
| t -> normalize_loop root t
686+
(* If [t] is a declaration but it's defined in [root], then we need to look it up in
687+
[root] before continuing normalization. *)
688+
let need_to_check_root =
689+
match t with
690+
| Definition { sort = Sort.Defined } -> false
691+
| Definition { sort = Sort.Declared ids } ->
692+
Ident_set.exists (Graph.is_module_type_defined root) ids
693+
| Declaration { id; _} -> Graph.is_module_type_defined root id
694+
in
695+
let t =
696+
if need_to_check_root
697+
then
698+
try Graph.find_module_type root (raw_path t)
699+
with Not_found -> t
700+
else t
701+
in
702+
normalize_loop root t
654703

655704
let origin root t =
656705
raw_origin (normalize root t)
@@ -661,6 +710,11 @@ end = struct
661710
let sort root t =
662711
raw_sort (normalize root t)
663712

713+
let is_defined t =
714+
match t with
715+
| Declaration _ -> false
716+
| Definition _ -> true
717+
664718
end
665719

666720
and Module : sig
@@ -717,6 +771,8 @@ and Module : sig
717771

718772
val raw_sort : normalized -> Sort.t
719773

774+
val is_defined : t -> bool
775+
720776
end = struct
721777

722778
open Desc.Module
@@ -854,12 +910,23 @@ end = struct
854910
end
855911

856912
let normalize root t =
857-
match t with
858-
| Definition { sort = Sort.Defined } -> normalize_loop root t
859-
| Definition { sort = Sort.Declared _ } | Declaration _ ->
860-
match Graph.find_module root (raw_path t) with
861-
| exception Not_found -> normalize_loop root t
862-
| t -> normalize_loop root t
913+
(* If [t] is a declaration but it's defined in [root], then we need to look it up in
914+
[root] before continuing normalization. *)
915+
let need_to_check_root =
916+
match t with
917+
| Definition { sort = Sort.Defined } -> false
918+
| Definition { sort = Sort.Declared ids } ->
919+
Ident_set.exists (Graph.is_module_defined root) ids
920+
| Declaration { id; _} -> Graph.is_module_defined root id
921+
in
922+
let t =
923+
if need_to_check_root
924+
then
925+
try Graph.find_module root (raw_path t)
926+
with Not_found -> t
927+
else t
928+
in
929+
normalize_loop root t
863930

864931
let unnormalize t = t
865932

@@ -1024,6 +1091,11 @@ end = struct
10241091
r.applications <- Path_map.add arg_path md applications;
10251092
md
10261093

1094+
let is_defined t =
1095+
match t with
1096+
| Declaration _ -> false
1097+
| Definition _ -> true
1098+
10271099
end
10281100

10291101
and Diff : sig
@@ -1137,6 +1209,11 @@ and Graph : sig
11371209

11381210
val is_module_ident_visible : t -> Ident.t -> bool
11391211

1212+
val is_type_defined : t -> Ident.t -> bool
1213+
val is_class_type_defined : t -> Ident.t -> bool
1214+
val is_module_type_defined : t -> Ident.t -> bool
1215+
val is_module_defined : t -> Ident.t -> bool
1216+
11401217
end = struct
11411218

11421219
type defs =
@@ -1538,6 +1615,26 @@ end = struct
15381615
"Short_paths_graph.Graph.is_module_type_path_visible: \
15391616
invalid module type path"
15401617

1618+
let is_type_defined t id =
1619+
match Ident_map.find id t.types with
1620+
| exception Not_found -> false
1621+
| ty -> Type.is_defined ty
1622+
1623+
let is_class_type_defined t id =
1624+
match Ident_map.find id t.class_types with
1625+
| exception Not_found -> false
1626+
| cls -> Class_type.is_defined cls
1627+
1628+
let is_module_type_defined t id =
1629+
match Ident_map.find id t.module_types with
1630+
| exception Not_found -> false
1631+
| mdty -> Module_type.is_defined mdty
1632+
1633+
let is_module_defined t id =
1634+
match Ident_map.find id t.modules with
1635+
| exception Not_found -> false
1636+
| md -> Module.is_defined md
1637+
15411638
end
15421639

15431640
type graph = Graph.t

0 commit comments

Comments
 (0)