You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: design/mvp/WIT.md
+159Lines changed: 159 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -185,6 +185,165 @@ default world my-world {
185
185
If no `default` world is specified in the WIT document and no named world is
186
186
explicitly chosen then bindings cannot be generated.
187
187
188
+
### Union of Worlds with `include`
189
+
190
+
A World can be created by taking the union of two or more worlds. This operation allows
191
+
world builders to form larger worlds from smaller worlds.
192
+
193
+
Below is a simple example of a world that includes two other worlds.
194
+
195
+
```wit
196
+
// worlds.wit
197
+
world my-world-1 {
198
+
import a: self.a
199
+
import b: self.b
200
+
export c: self.c
201
+
}
202
+
203
+
world my-world-2 {
204
+
import foo: self.foo
205
+
import bar: self.bar
206
+
export baz: self.baz
207
+
}
208
+
209
+
world union-my-world {
210
+
include self.my-world-1
211
+
include self.my-world-2
212
+
}
213
+
```
214
+
215
+
The `include` statement is used to include the imports and exports of another World to the
216
+
current World. It says that the new World should be able to run all components that target
217
+
the included worlds and more.
218
+
219
+
The `union-my-world` World defined above is equivalent to the following World:
220
+
221
+
```wit
222
+
world union-my-world {
223
+
import a: self.a
224
+
import b: self.b
225
+
export c: self.c
226
+
import foo: self.foo
227
+
import bar: self.bar
228
+
export baz: self.baz
229
+
}
230
+
```
231
+
232
+
The `include` statement also works with [WIT package](#wit-packages-and-use) defined below with the same semantics. For example, the following World `union-my-world-1` is equivalent to `union-my-world-2`:
233
+
234
+
```wit
235
+
// b.wit
236
+
interface b { ... }
237
+
238
+
// a.wit
239
+
interface a { ... }
240
+
241
+
world my-world-1 {
242
+
import a: self.a
243
+
import b: pkg.b
244
+
import c: io.c // external package
245
+
export d: interface exp { ... }
246
+
}
247
+
248
+
// union.wit
249
+
250
+
world union-my-world-1 {
251
+
include pkg.my-world-1
252
+
}
253
+
254
+
world union-my-world-2 {
255
+
import a: pkg.a
256
+
import b: pkg.b
257
+
import c: io.c
258
+
export d: interface exp { ... }
259
+
}
260
+
```
261
+
262
+
### Name Conflicts
263
+
264
+
When two or more included Worlds have the same name for an import or export, the name is considered to be in conflict. The conflict needs to be explicitly resolved by the world author using the `with` keyword.
265
+
266
+
`with` allows the world author to rename the import or export to a different name. For all the imports and exports that are not explicitly renamed, the name of the import or export from the included world is used.
267
+
268
+
The following example shows how to resolve name conflicts where `union-my-world-1` and `union-my-world-2` are equivalent:
269
+
270
+
```wit
271
+
// my-world-1.wit
272
+
world my-world-1 {
273
+
import a: self.a
274
+
import b: self.b
275
+
export d: self.d
276
+
}
277
+
278
+
// my-world-2.wit
279
+
world my-world-2 {
280
+
import a: self.a
281
+
import b: self.b
282
+
export c: self.c
283
+
}
284
+
285
+
// union.wit
286
+
world union-my-world-1 {
287
+
include pkg.my-world-1 with { a as a1, b as b1 }
288
+
include pkg.my-world-2
289
+
}
290
+
291
+
world union-my-world-2 {
292
+
// resolve conflicts
293
+
import a1: pkg.my-world-1.a
294
+
import b1: pkg.my-world-1.b
295
+
export d: pkg.my-world-1.d
296
+
297
+
import a: pkg.my-world-2.a
298
+
import b: pkg.my-world-2.b
299
+
export c: pkg.my-world-2.c
300
+
}
301
+
```
302
+
303
+
### De-duplication (In the future)
304
+
305
+
As of now, the `include` statement requires the world author to explicitly rename the imports and exports that have the same name.
306
+
307
+
In the future, we may allow to de-duplicate the imports and exports of the included worlds if the yare structurally equivalent following the [Subtyping](Subtyping.md) rules. For example, the following world `union-my-world-3` is equivalent to `union-my-world-4`:
308
+
309
+
```wit
310
+
// a.wit
311
+
// b.wit
312
+
// c.wit
313
+
314
+
// my-world-1.wit
315
+
world my-world-1 {
316
+
import a: pkg.a
317
+
import b: pkg.b
318
+
export c: pkg.c
319
+
}
320
+
321
+
// my-world-2.wit
322
+
world my-world-2 {
323
+
import a: pkg.a
324
+
import b: pkg.b
325
+
export c: pkg.c
326
+
}
327
+
328
+
// union.wit
329
+
world union-my-world-3 {
330
+
include pkg.my-world-1
331
+
include pkg.my-world-2
332
+
}
333
+
334
+
world union-my-world-4 {
335
+
import a: pkg.a
336
+
import b: pkg.b
337
+
export c: pkg.c
338
+
}
339
+
```
340
+
341
+
### A Note on SubTyping
342
+
343
+
As of now, host bindings are required to implicitly interpret all exports as optional to make a component targeting an included World a subtype of the union World. This [comment](https://github.com/WebAssembly/component-model/issues/169#issuecomment-1446776193) describes the reasoning behind this decision.
344
+
345
+
In the future, when `optional` export is supported, the world author may explicitly mark exports as optional to make a component targeting an included World a subtype of the union World.
0 commit comments