Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove implicit import behavior of 'use' #402

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions design/mvp/WIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ interface types {

More information about [`use`][use] and [types] are described below, but this
is an example of a collection of items within an `interface`. All items defined
in an `interface`, including [`use`][use] items, are considered as exports from
the interface. This means that types can further be used from the interface by
other interfaces. An interface has a single namespace which means that none of
the defined names can collide.
in an `interface` are considered as exports from the interface. This means that
types can further be used from the interface by other interfaces. An interface
has a single namespace which means that none of the defined names can collide.

A WIT package can contain any number of interfaces listed at the top-level and
in any order. The WIT validator will ensure that all references between
Expand Down Expand Up @@ -589,23 +588,22 @@ use wasi:http/[email protected] as http-types2;
### Transitive imports and worlds

A `use` statement is not implemented by copying type information around but
instead retains that it's a reference to a type defined elsewhere. This
representation is plumbed all the way through to the final component, meaning
that `use`d types have an impact on the structure of the final generated
component.
instead retains that it's a reference to a type that must have already been
imported or exported.

For example this document:

```wit
package local:demo;

interface shared {
record metadata {
resource metadata {
// ...
}
}

world my-world {
import shared; // required by 'use'
import host: interface {
use shared.{metadata};

Expand All @@ -617,52 +615,53 @@ world my-world {
would generate this component:

```wasm
(component
(component $C
(import "local:demo/shared" (instance $shared
(type $metadata (record (; ... ;)))
(export "metadata" (type (eq $metadata)))
(export "metadata" (type (sub resource)))
))
(alias export $shared "metadata" (type $metadata_from_shared))
(import "host" (instance $host
(export $metadata_in_host "metadata" (type (eq $metadata_from_shared)))
(export "get" (func (result $metadata_in_host)))
(alias outer $C $metadata_from_shared (type $metadata))
(export "get" (func (result $metadata)))
))
)
```

Here it can be seen that despite the `world` only listing `host` as an import
the component additionally imports a `local:demo/shared` interface. This is due
to the fact that the `use shared.{ ... }` implicitly requires that `shared` is
imported into the component as well.
Thus, the `metadata` resource type defined in the `shared` interface is
directly shared (via Component Model `alias` definitions) with the `host`
interface. If the `import shared;` line were deleted, this WIT document would
fail to validate since there is no `shared.metadata` type to `use`.

Note that the name `"local:demo/shared"` here is derived from the name of the
`interface` plus the package name `local:demo`.

For `export`ed interfaces, any transitively `use`d interface is assumed to be an
import unless it's explicitly listed as an export. For example, here `w1` is
equivalent to `w2`:
For `export`ed interfaces, any transitively `use`d interfaces can be satisfied
by *either* imports or exports.

For example, the following world `w` uses both the imported `r` defined by `a`
and the exported `s` defined by `b`:
```wit
interface a {
resource r;
}
interface b {
use a.{r};
foo: func() -> r;
}

world w1 {
export b;
resource s;
}
world w2 {
world w {
import a;
export b;
export converter: interface {
use a.{r};
use b.{s};
convert: func(in: r) -> s;
}
}
```

> **Note**: It's planned in the future to have "power user syntax" to configure
> this on a more fine-grained basis for exports, for example being able to
> configure that a `use`'d interface is a particular import or a particular
> export.
> **Note**: It's planned in the future to add additional syntax to support and
> disambiguate the case where the same interface is both imported and exported.
> With this addition, `w` could contain `import b` and `converter` could `use`
> *both* the imported `s` *and* the exported `s`.

## WIT Functions
[functions]: #wit-functions
Expand Down Expand Up @@ -1898,6 +1897,7 @@ package wasi:http;

world proxy {
import wasi:logging/logger;
import types;
import handler;
export handler;
}
Expand Down
Loading