Skip to content

Add [implements=<I>]L plainname for multiple imports#613

Open
ricochet wants to merge 1 commit intomainfrom
implements
Open

Add [implements=<I>]L plainname for multiple imports#613
ricochet wants to merge 1 commit intomainfrom
implements

Conversation

@ricochet
Copy link
Contributor

@ricochet ricochet commented Feb 25, 2026

Add [implements=<I>]L plainname for multiple imports of the same interface

Extend the WIT extern-type grammar to allow use-path as a third case,
enabling import id: use-path and export id: use-path to create
plain-named imports/exports whose instance type matches a named interface.

This allows importing the same interface multiple times under different
plain names (e.g., import primary: store; import secondary: store;),
encoded using the [implements=<interfacename>]label annotation pattern.

Fixes #287

Copy link
Member

@lukewagner lukewagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for writing this up! The PR looks great; just minor nits. I think what'll be important for this change is seeing how it "plays out" in the producer and consumer tooling, so I think we'll want to keep this PR open until we get some experience from tool implementations, but so far so good from my perspective.

Comment on lines 416 to 418
* Validation requires that `[implements=<I>]` annotated `plainname`s only
occur on `instance` imports or exports and that `I` is a valid
`interfacename`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the grammatical rules (the EBNF in Explainer.md) force I to be a valid interfacename without validation having to say so here.

Requiring [implements=<I>]L to only annotate instance-typed imports/exports makes sense, but if we do it here, then I think we should also require it for plain interfacename-named imports/exports too. This restriction actually makes sense and shouldn't break anyone b/c it matches what you can do in WIT today (thereby removing an expressivity gap from #614), so I'm in favor.

Comment on lines 2699 to 2702
Here, both imports implement `wasi:keyvalue/store` but have distinct plain
names `primary` and `secondary`. Bindings generators can use the
`[implements=<I>]` annotation to know which interface the instance implements,
enabling them to generate the same typed bindings for both imports.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resource types (e.g. bucket) defined directly in wasi:keyvalue/store will be treated as different, so "generate the same typed bindings for both imports" isn't quite right. (And this makes sense: if we want to allow two totally different implementations of these two keyvalue stores, each implementation should be able to have its own implementation of bucket.) However I suppose bindings generators could/should share types for value types (like the key-response record), since they're not tied to the implementation; they just need predictable names. So maybe "enabling them to share value type bindings"?

Second, it might also be good to give some examples of how the interfacename helps hosts/clients of a component.

Comment on lines 2840 to 2842
* An `[implements=<I>]L` name and a bare `I` `interfacename` are always
strongly-unique (they are different name kinds: `plainname` vs
`interfacename`).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might totally be forgetting a case, but I think we don't need this bullet at all; the "Otherwise" clause gives us the behavior we want.

Comment on lines 1423 to 1424
import primary: store;
import secondary: store;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're using wasi:http/incoming-handler for the export, maybe use fully-qualified wasi:keyvalue/store for the imports (to avoid making a distinction that is beside the main point)?

instance type of the `store` interface. The plain name of the import is the
`id` before the colon (e.g., `primary`), not the interface name. This
contrasts with `import store;` (without the `id :` prefix), which would create
a single import using the full interface name `local:demo/store`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also speak to the export which has the name my-handler and how this is different than export wasi:http/incoming-handler (and perhaps we could switch to wasi:http/handler in anticipation of p3 :).

ricochet added a commit to ricochet/wasm-tools that referenced this pull request Feb 27, 2026
Add parsing, validation, and uniqueness rules for the new
`[implements=<interface>]label` extern name form from the component
model `implements` proposal. An implements name labels an instance
import/export that implements a named interface.

Uniqueness: `[implements=<I>]L` conflicts with bare label `L` and with
`[method]L.L` / `[static]L.L` (the existing l.l edge case), but is
strongly unique from interface names, constructors, and normal
method/static names.

See implements feature:
WebAssembly/component-model#613
Extend the WIT `extern-type` grammar to allow `use-path` as a third case,
enabling `import id: use-path` and `export id: use-path` to create
plain-named imports/exports whose instance type matches a named interface.

This allows importing the same interface multiple times under different
plain names (e.g., `import primary: store; import secondary: store;`),
encoded using the `[implements=<interfacename>]label` annotation pattern.

Fixes #287

Co-authored-by: Luke Wagner <mail@lukewagner.name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support multiple imports of the same interface with different names

2 participants