Skip to content

Commit e4a7c10

Browse files
JasonGrossclaude
andcommitted
Add tests and changelog for module subtyping performance fixes
The test exercises Include-self chains over empty and non-empty parameter signatures (including definitions checked up to conversion, inductive types and submodules in the parameter signature), rejection of ill-typed chains, prefix-shaped chains that re-check the same fields at every stage, repeated functor applications, and rollback (Reset) followed by a redo of a check whose universe constraints must be re-produced. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019ttctspSoVoquHLQtbPVZw
1 parent 6382b6e commit e4a7c10

2 files changed

Lines changed: 163 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
- **Fixed:**
2+
quadratic compilation time of chains of ``<+`` over functor module
3+
types (and, more generally, of repeated module subtyping checks
4+
against a large accumulated signature): the "Include Self" subtyping
5+
check now looks fields up in the environment on demand instead of
6+
eagerly strengthening and indexing the whole accumulated signature,
7+
and successful field checks are cached so that re-checking the same
8+
fields (e.g. against every prefix of a chain, or on repeated
9+
applications of the same functor) hits a fast path
10+
(`#22281 <https://github.com/rocq-prover/rocq/pull/22281>`_,
11+
fixes `#22279 <https://github.com/rocq-prover/rocq/issues/22279>`_,
12+
written by Claude (Anthropic), for Jason Gross).
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
(* Include-self subtyping checks for chains of functor module types
2+
(see rocq-prover/rocq#22279).
3+
4+
Each [<+] of a functor module type instantiates the functor's parameter
5+
with the module type under construction, which triggers a subtyping
6+
check of the accumulated signature against the parameter's signature.
7+
These tests exercise that path with empty and non-empty parameter
8+
signatures, definitions (checked up to conversion), inductive types,
9+
submodules, and prefix-shaped chains where the same fields are
10+
re-checked at every stage. *)
11+
12+
(* Chains over an empty parameter signature *)
13+
14+
Module Type EmptyArgs. End EmptyArgs.
15+
Module Type E1 (Import args : EmptyArgs). Parameter e1 : Type. End E1.
16+
Module Type E2 (Import args : EmptyArgs). Parameter e2 : Type. End E2.
17+
Module Type E3 (Import args : EmptyArgs). Parameter e3 : Type. End E3.
18+
19+
Module Type EChain := E1 <+ E2 <+ E3.
20+
21+
(* Chains over a shared parameter signature with a couple of fields,
22+
including fields referring to each other and a definition *)
23+
24+
Module Type Args.
25+
Parameter t : Type.
26+
Parameter op : t -> t.
27+
Parameter e : t.
28+
Definition twice (x : t) : t := op (op x).
29+
End Args.
30+
31+
Module Type I1 (Import args : Args).
32+
Parameter f1 : t -> t.
33+
End I1.
34+
Module Type I2 (Import args : Args).
35+
Parameter f2 : twice e = twice e.
36+
End I2.
37+
38+
Module Type Chain := Args <+ I1 <+ I2.
39+
40+
(* The definition [twice] in the accumulated signature is checked, up to
41+
conversion, against the definition expected by each parameter. *)
42+
43+
Module Type ArgsEta.
44+
Parameter t : Type.
45+
Parameter op : t -> t.
46+
Parameter e : t.
47+
Definition twice : t -> t := fun x => op (op x).
48+
End ArgsEta.
49+
50+
Module Type I3 (Import args : ArgsEta).
51+
Parameter f3 : t.
52+
End I3.
53+
54+
Module Type ChainEta := Args <+ I3.
55+
56+
(* A parameter cannot implement an expected definition *)
57+
58+
Module Type ArgsDef.
59+
Definition d : nat := 0.
60+
End ArgsDef.
61+
Module Type UsesDef (Import args : ArgsDef).
62+
Parameter u : d = 0.
63+
End UsesDef.
64+
65+
Module Type BadArgsDef.
66+
Parameter d : nat.
67+
End BadArgsDef.
68+
69+
Fail Module Type BadDefChain := BadArgsDef <+ UsesDef.
70+
Module Type GoodDefChain := ArgsDef <+ UsesDef.
71+
72+
(* Type mismatches are still detected *)
73+
74+
Module Type BadArgs.
75+
Parameter t : Type.
76+
Parameter op : t.
77+
Parameter e : t.
78+
Definition twice (x : t) : t := x.
79+
End BadArgs.
80+
81+
Fail Module Type BadChain := BadArgs <+ I1.
82+
83+
(* Inductive types and submodules in the parameter signature *)
84+
85+
Module Type ArgsInd.
86+
Inductive w : Set := A : w.
87+
Module Sub.
88+
Definition x : nat := 0.
89+
End Sub.
90+
End ArgsInd.
91+
92+
Module Type I4 (Import args : ArgsInd).
93+
Parameter f4 : w -> w.
94+
End I4.
95+
96+
Module Type ChainInd := ArgsInd <+ I4.
97+
98+
(* Prefix-shaped chains: stage [k] is parameterized by the whole chain up
99+
to stage [k-1], so the same fields are re-checked at every stage. *)
100+
101+
Module Type P0. Parameter t0 : Type. End P0.
102+
Module Type A0 := P0.
103+
Module Type P1 (Import a : A0). Parameter t1 : Type. End P1.
104+
Module Type A1 := A0 <+ P1.
105+
Module Type P2 (Import a : A1). Parameter t2 : Type. End P2.
106+
Module Type A2 := A1 <+ P2.
107+
Module Type P3 (Import a : A2). Parameter t3 : Type. End P3.
108+
Module Type A3 := A2 <+ P3.
109+
Module Type P4 (Import a : A3). Parameter t4 : Type. End P4.
110+
Module Type A4 := A3 <+ P4.
111+
112+
(* Functors applied to modules keep checking their argument *)
113+
114+
Module Type Sig.
115+
Parameter t : Type.
116+
Parameter e : t.
117+
End Sig.
118+
119+
Module M.
120+
Definition t : Type := nat.
121+
Definition e : t := 0.
122+
End M.
123+
124+
Module F (X : Sig).
125+
Definition v := X.e.
126+
End F.
127+
128+
Module App1 := F M.
129+
Module App2 := F M.
130+
Module App3 := F M.
131+
132+
Module BadM.
133+
Definition t : Type := nat.
134+
Definition e : bool := true.
135+
End BadM.
136+
137+
Fail Module BadApp := F BadM.
138+
139+
(* Includes of applied functors whose argument is a functor parameter *)
140+
141+
Module G (X : Args).
142+
Include I1 X.
143+
End G.
144+
145+
(* Rolling back and redoing a check must reproduce its universe
146+
constraints (cached subtyping verdicts are flushed on rollback) *)
147+
148+
Set Warnings "-undo-batch-mode".
149+
Module App4 := F M.
150+
Reset App4.
151+
Module App4 := F M.

0 commit comments

Comments
 (0)