Component WAT restates imported types instead of pointing at them
I was writing a proposal to allow type declarations at package scope in WIT, and got asked to show an encoding that actually passes wasm-tools validate.
In WIT, use reads like a reference to a type that lives somewhere else:
package other:app;
use local:demo/point;
interface api {
move-to: func(p: point);
}
So I expected the WAT to name local:demo/point and stop there. It does not. You restate the whole record, then import it to say where it came from:
(component
(type (export "api") (component
(type $point (record (field "x" u32) (field "y" u32)))
(import "local:demo/point" (type $point' (eq $point)))
(export "other:app/api" (instance
(export "move-to" (func (param "p" $point')))
))
))
)
That (type $point (record ...)) line looks redundant. I kept trying to delete it, and kept getting:
error: unknown type: failed to find name `$point`
(import "local:demo/point" (type $point' (eq $point)))
^
The import is not fetching the type. The local definition is the type, and the import only names where it came from. (eq $point) ties the two together.
The reason: a component carries every type it needs to be validated and compiled on its own, without fetching other packages just to pull out a definition. Same as importing an interface from another package and restating its types locally, with imports recording the provenance.
I was expecting something fancier here.
Luke Wagner spelled out the encoding on component-model#699, where he hoists the record to the outer component and exports it there.