|
| 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