|
49 | 49 | (type $A (sub (descriptor $A.desc (struct))))
|
50 | 50 | ;; CHECK: (type $A.desc (sub (describes $A (struct))))
|
51 | 51 | (type $A.desc (sub (describes $A (struct))))
|
52 |
| - ;; CHECK: (type $B (sub (descriptor $B.desc (struct)))) |
| 52 | + ;; CHECK: (type $B (sub $A (descriptor $B.desc (struct)))) |
53 | 53 | (type $B (sub $A (descriptor $B.desc (struct))))
|
54 | 54 | ;; CHECK: (type $B.desc (sub $A.desc (describes $B (struct))))
|
55 | 55 | (type $B.desc (sub $A.desc (describes $B (struct))))
|
56 | 56 | )
|
57 | 57 |
|
58 |
| - ;; Now we directly require B.desc <: A.desc. This does *not* imply B <: A, so |
59 |
| - ;; we can optimize $B (but not $B.desc). |
| 58 | + ;; Now we require B.desc <: A.desc, which similarly implies B <: A. |
60 | 59 | ;; CHECK: (global $B.desc (ref null $B.desc) (ref.null none))
|
61 | 60 | (global $B.desc (ref null $B.desc) (ref.null none))
|
62 | 61 | ;; CHECK: (global $A.desc (ref null $A.desc) (global.get $B.desc))
|
|
134 | 133 | ;; CHECK: (global $bot-mid-desc (ref null $mid.desc) (struct.new_default $bot.desc))
|
135 | 134 | (global $bot-mid-desc (ref null $mid.desc) (struct.new $bot.desc))
|
136 | 135 | )
|
| 136 | + |
| 137 | +(module |
| 138 | + (rec |
| 139 | + ;; CHECK: (rec |
| 140 | + ;; CHECK-NEXT: (type $top (sub (descriptor $top.desc (struct)))) |
| 141 | + (type $top (sub (descriptor $top.desc (struct)))) |
| 142 | + ;; CHECK: (type $mid (sub $top (descriptor $mid.desc (struct)))) |
| 143 | + (type $mid (sub $top (descriptor $mid.desc (struct)))) |
| 144 | + ;; CHECK: (type $bot (sub $mid (descriptor $bot.desc (struct)))) |
| 145 | + (type $bot (sub $mid (descriptor $bot.desc (struct)))) |
| 146 | + ;; CHECK: (type $top.desc (sub (describes $top (struct)))) |
| 147 | + (type $top.desc (sub (describes $top (struct)))) |
| 148 | + ;; CHECK: (type $mid.desc (sub $top.desc (describes $mid (struct)))) |
| 149 | + (type $mid.desc (sub $top.desc (describes $mid (struct)))) |
| 150 | + ;; CHECK: (type $bot.desc (sub $mid.desc (describes $bot (struct)))) |
| 151 | + (type $bot.desc (sub $mid.desc (describes $bot (struct)))) |
| 152 | + ) |
| 153 | + |
| 154 | + ;; Now go the other direction: |
| 155 | + ;; |
| 156 | + ;; top ---> top.desc |
| 157 | + ;; ^ |
| 158 | + ;; mid -> mid.desc |(2) |
| 159 | + ;; ^ (1) | |
| 160 | + ;; bot ---> bot.desc |
| 161 | + ;; |
| 162 | + ;; bot.desc <: top.desc implies bot <: top, but we already have bot <: mid, so |
| 163 | + ;; that gives us bot <: mid <: top. This is only valid if we also have |
| 164 | + ;; bot.desc <: mid.desc <: top.desc. |
| 165 | + |
| 166 | + ;; CHECK: (global $bot-mid (ref null $mid) (struct.new_default $bot |
| 167 | + ;; CHECK-NEXT: (ref.null none) |
| 168 | + ;; CHECK-NEXT: )) |
| 169 | + (global $bot-mid (ref null $mid) (struct.new $bot (ref.null none))) |
| 170 | + ;; CHECK: (global $bot-top-desc (ref null $top.desc) (struct.new_default $bot.desc)) |
| 171 | + (global $bot-top-desc (ref null $top.desc) (struct.new $bot.desc)) |
| 172 | +) |
| 173 | + |
| 174 | +(module |
| 175 | + (rec |
| 176 | + ;; CHECK: (rec |
| 177 | + ;; CHECK-NEXT: (type $top (sub (descriptor $top.desc (struct)))) |
| 178 | + (type $top (sub (descriptor $top.desc (struct)))) |
| 179 | + ;; CHECK: (type $mid (sub $top (descriptor $mid.desc (struct)))) |
| 180 | + (type $mid (sub $top (descriptor $mid.desc (struct)))) |
| 181 | + ;; CHECK: (type $bot (sub $mid (descriptor $bot.desc (struct)))) |
| 182 | + (type $bot (sub $mid (descriptor $bot.desc (struct)))) |
| 183 | + ;; CHECK: (type $top.desc (sub (describes $top (struct)))) |
| 184 | + (type $top.desc (sub (describes $top (struct)))) |
| 185 | + ;; CHECK: (type $mid.desc (sub $top.desc (describes $mid (struct)))) |
| 186 | + (type $mid.desc (sub $top.desc (describes $mid (struct)))) |
| 187 | + ;; CHECK: (type $bot.desc (sub $mid.desc (describes $bot (struct)))) |
| 188 | + (type $bot.desc (sub $mid.desc (describes $bot (struct)))) |
| 189 | + ) |
| 190 | + |
| 191 | + ;; Same as above, but the order of the initial subtypings is reversed. |
| 192 | + ;; |
| 193 | + ;; top ---> top.desc |
| 194 | + ;; ^ |
| 195 | + ;; mid -> mid.desc |(1) |
| 196 | + ;; ^ (2) | |
| 197 | + ;; bot ---> bot.desc |
| 198 | + ;; |
| 199 | + ;; bot.desc <: top.desc implies bot <: top. When we add bot <: mid, that gives |
| 200 | + ;; us bot <: mid <: top. This is only valid if we also have |
| 201 | + ;; bot.desc <: mid.desc <: top.desc. |
| 202 | + ;; CHECK: (global $bot-top-desc (ref null $top.desc) (struct.new_default $bot.desc)) |
| 203 | + (global $bot-top-desc (ref null $top.desc) (struct.new $bot.desc)) |
| 204 | + ;; CHECK: (global $bot-mid (ref null $mid) (struct.new_default $bot |
| 205 | + ;; CHECK-NEXT: (ref.null none) |
| 206 | + ;; CHECK-NEXT: )) |
| 207 | + (global $bot-mid (ref null $mid) (struct.new $bot (ref.null none))) |
| 208 | +) |
0 commit comments