Skip to content

Commit

Permalink
Always require type exports to ascribe a type
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewagner committed Sep 21, 2023
1 parent 673d5c4 commit 07b1f8a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 33 deletions.
8 changes: 5 additions & 3 deletions design/mvp/Binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,11 @@ Notes:
* Validation requires that all resource types transitively used in the type of an
export are introduced by a preceding `importdecl` or `exportdecl`.
* Validation requires any exported `sortidx` to have a valid `externdesc`
(which disallows core sorts other than `core module`). When the optional
`externdesc` immediate is present, validation requires it to be a supertype
of the inferred `externdesc` of the `sortidx`.
(which disallows core sorts other than `core module`).
* When an export's optional `externdesc` immediate is present, validation
requires it to be a supertype of the inferred `externdesc` of the `sortidx`.
* Resource type exports must have an explicit ascribed `externdesc` (indicating
`(sub resource)` or `(eq <typeidx>)`).
* The `name` fields of `exportname` and `importname` must be unique among all
imports and exports in the containing component definition, component type or
instance type. (An import and export cannot use the same `name`.)
Expand Down
42 changes: 12 additions & 30 deletions design/mvp/Explainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -931,46 +931,28 @@ bind a fresh abstract type. For example, in the following component:
all four types aliases in the outer component are unequal, reflecting the fact
that each instance of `$C` generates two fresh resource types.

If a single resource type definition is exported more than once, the exports
after the first are equality-bound to the first export. For example, the
following component:
When a component exports a type, the component must explicitly specify how the
type should appear to the outside world by explicitly ascribing a `typebound`.
For example, in the following component:
```wasm
(component
(type $r (resource (rep i32)))
(export "r1" (type $r))
(export "r2" (type $r))
(export $r1 "r1" (type $r) (type (sub resource)))
(export "r2" (type $r) (type (eq $r1)))
(export "r3" (type $r) (type (sub resource)))
)
```
is assigned the following `componenttype`:
the inferred `componenttype` is:
```wasm
(component
(export $r1 "r1" (type (sub resource)))
(export "r2" (type (eq $r1)))
)
```
Thus, from an external perspective, `r1` and `r2` are two labels for the same
type.

If a component wants to hide this fact and force clients to assume `r1` and
`r2` are distinct types (thereby allowing the implementation to actually use
separate types in the future without breaking clients), an explicit type can be
ascribed to the export that replaces the `eq` bound with a less-precise `sub`
bound.
```wasm
(component
(type $r (resource (rep i32)))
(export "r1" (type $r)
(export "r2" (type $r) (type (sub resource)))
)
```
This component is assigned the following `componenttype`:
```wasm
(component
(export "r1" (type (sub resource)))
(export "r2" (type (sub resource)))
(export "r2" (type (eq $r1)))
(export "r3" (type (sub resource)))
)
```
The assignment of this type to the above component mirrors the *introduction*
This type exposes to clients of this component only that `r1` and `r2` are
equal even though all three exports are of the same internal type definition.
The assignment of these types to the above component mirrors the *introduction*
rule of [existential types] (∃T).

When supplying a resource type (imported *or* defined) to a type import via
Expand Down

0 comments on commit 07b1f8a

Please sign in to comment.