From a4dcbe8e0b6c8c67581b407edca223d2af8ad38e Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 23 Feb 2024 13:42:59 -0600 Subject: [PATCH 1/2] Split 'use' inside worlds into 'use import' and 'use export' --- design/mvp/WIT.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/design/mvp/WIT.md b/design/mvp/WIT.md index eec4b325..62c67c90 100644 --- a/design/mvp/WIT.md +++ b/design/mvp/WIT.md @@ -1051,7 +1051,8 @@ world-items ::= gate world-definition world-definition ::= export-item | import-item - | use-item + | use-export-item + | use-import-item | typedef-item | include-item @@ -1060,6 +1061,9 @@ export-item ::= 'export' id ':' extern-type import-item ::= 'import' id ':' extern-type | 'import' use-path ';' +use-import-item ::= 'use' 'import' use-item-body +use-export-item ::= 'use' 'export' use-item-body + extern-type ::= func-type ';' | 'interface' '{' interface-items* '}' ``` @@ -1068,6 +1072,27 @@ from the root of a component and used within functions imported and exported. The `interface` item here additionally defines the grammar for IDs used to refer to `interface` items. +The `use export`/`use import` items work just like `use` inside an `interface` +except that they exclusively refer to exports/imports, respectively. This +allows a world to import and export the same interface and be able to +independently refer to same type in both. For example, the following world +defines a single function using both an imported and exported version of the +same interface's resource type: + +```wit +interface i { + resource r; +} + +world w { + import i; + export i; + use import i.{r as r1}; + use export i.{r as r2}; + export transform: func(in: r1) -> r2; +} +``` + [`componenttype`]: Explainer.md#type-definitions ## Item: `include` @@ -1144,7 +1169,9 @@ use my:dependency/the-interface.{more, names as foo} Specifically the structure of this is: ```ebnf -use-item ::= 'use' use-path '.' '{' use-names-list '}' ';' +use-item ::= 'use' use-item-body + +use-item-body ::= use-path '.' '{' use-names-list '}' ';' use-names-list ::= use-names-item | use-names-item ',' use-names-list? From 63ad7c1b20ed11a61c80b12752f8f5ed6f85f2e3 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 11 Jul 2024 12:46:09 -0500 Subject: [PATCH 2/2] Add optional 'using' clause to world imports and exports --- design/mvp/WIT.md | 65 ++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/design/mvp/WIT.md b/design/mvp/WIT.md index 62c67c90..5b3e9ec4 100644 --- a/design/mvp/WIT.md +++ b/design/mvp/WIT.md @@ -1051,20 +1051,26 @@ world-items ::= gate world-definition world-definition ::= export-item | import-item - | use-export-item - | use-import-item + | world-use-item | typedef-item | include-item export-item ::= 'export' id ':' extern-type - | 'export' use-path ';' + | 'export' use-path using-clause? ';' import-item ::= 'import' id ':' extern-type - | 'import' use-path ';' + | 'import' use-path using-clause? ';' -use-import-item ::= 'use' 'import' use-item-body -use-export-item ::= 'use' 'export' use-item-body +extern-type ::= func-type ';' | 'interface' '{' interface-items* '}' using-clause? -extern-type ::= func-type ';' | 'interface' '{' interface-items* '}' +using-clause ::= 'using' '{' using-item (',' using-item)* '}' +using-item ::= use-path '=' world-use-path +world-use-path ::= 'import' use-path + | 'export' use-path + +world-use-item ::= 'use' world-use-path use-projection ';' +use-projection ::= '.' '{' projection-item (',' projection-item)* '}' +projection-item ::= id + | id 'as' id ``` Note that worlds can import types and define their own types to be exported @@ -1072,13 +1078,11 @@ from the root of a component and used within functions imported and exported. The `interface` item here additionally defines the grammar for IDs used to refer to `interface` items. -The `use export`/`use import` items work just like `use` inside an `interface` -except that they exclusively refer to exports/imports, respectively. This -allows a world to import and export the same interface and be able to -independently refer to same type in both. For example, the following world -defines a single function using both an imported and exported version of the -same interface's resource type: - +The `use` items work just like `use` inside an `interface` except that they can +explicitly prefix the `use-path` with `export` or `import`, allowing a world +to import and export the same interface and independently refer to both. An +unqualified `use-path` may not be used if `use-path` is both imported and +exported. For example: ```wit interface i { resource r; @@ -1093,6 +1097,29 @@ world w { } ``` +A `using` clause may be added after imports or exports of interfaces to +override the default type-sharing behavior within the imported `interface` and +all `interface`s transitively `use`d by it. For example: +```wit +interface blob-store { + resource blob { ... } +} + +interface blob-transform { + use blob-store.{blob}; + transform: func(in: blob) -> blob; +} + +interface compressed-blob-store { + resource blob { ... } +} + +world w { + import compressed-blob-store; + export blob-transform using { blob-store = import compressed-blob-store }; +} +``` + [`componenttype`]: Explainer.md#type-definitions ## Item: `include` @@ -1169,15 +1196,7 @@ use my:dependency/the-interface.{more, names as foo} Specifically the structure of this is: ```ebnf -use-item ::= 'use' use-item-body - -use-item-body ::= use-path '.' '{' use-names-list '}' ';' - -use-names-list ::= use-names-item - | use-names-item ',' use-names-list? - -use-names-item ::= id - | id 'as' id +use-item ::= 'use' use-path use-projection ';' ``` Note: Here `use-names-list?` means at least one `use-name-list` term.