bytecodealliance / bytecodealliance/wit-bindgen
"associated functions" and "associated methods" on non-resource types
- Dominant language
- Rust
- Stars
- 1.5k
- Forks
- 286
- Avg merge
- 6h 32m
- Merged PRs (30d)
- 19
Description
Given the following wit:
```wit
record color {
r: float32,
g: float32,
b: float32,
a: float32
}
record vec4 {
x: float32,
y: float32,
z: float32,
w: float32
}
// (pseudocode) associated method for color
color.from-rgba: func(r: u8, g: u8, b: u8, a: u8) -> color;
// (pseudocode) associated function
color.to-vec: func(self: color) -> vec4;
```
when Rust bindings are generated, I'd like to allow a Rust guest to write:
```rs
let foo = Color { r: 0.1, g: 0.2, b: 0.3, a: 1.0 }; // can construct the type by struct literal syntax
let r = foo.r; // can access a field
let bar = Color::from_rgba(180, 180, 180, 255); // can construct the type with an associated function
let vec: Vec4 = bar.to_vec(); // can call an associated method
```
The closest I could find to this in the wit IDL document is a [`resource`](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#item-resource).
> As syntactic sugar, resource statements can also declare any number of
> *methods*, which are functions that implicitly take a `self` parameter that is
> a handle. A resource statement can also contain any number of *static
> functions*, which do not have an implicit `self` parameter but are meant to be
> lexically nested in the scope of the resource type. Lastly, a resource
> statement can contain at most one *constructor* function, which is syntactic
> sugar for a function returning a handle of the containing resource type.
>
> For example, the following resource definition:
> ```wit
> resource blob {
> constructor(init: list);
> write: func(bytes: list);
> read: func(n: u32) -> list;
> merge: static func(lhs: borrow, rhs: borrow) -> blob;
> }
> ```
> desugars into:
> ```wit
> resource blob;
> %[constructor]blob: func(self: borrow, bytes: list) -> blob;
> %[method]blob.write: func(self: borrow, bytes: list);
> %[method]blob.read: func(self: borrow, n: u32) -> list;
> %[static]blob.merge: func(lhs: borrow, rhs: borrow) -> blob;
> ```
> These `%`-prefixed [`name`s](Explainer.md) embed the resource type name so that
> bindings generators can generate idiomatic syntax for the target language or
> (for languages like C) fall back to an appropriately-prefixed free function
> name.
The wit IDL document refers to these as syntactic sugar, and references a "desugaring" of sub-definitions within a `resource`.
This seems to imply (if it isn't purely illustrative) that `%[method]blob.write: func(self: borrow, bytes: list);` should be valid wit.
And in the [component model document](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#import-and-export-definitions), a `plainname` like this is valid:
> ```ebnf
> exportname ::=
> |
> importname ::=
> |
> |
> |
> plainname ::=
> | '[constructor]'
> | '[method]' '.'
> | '[static]' '.'
> label ::=
> | '-'
> word ::= [a-z] [0-9a-z]*
> | [A-Z] [0-9A-Z]*
> ...
> ```
The obvious attempt was to do:
```wit
%[constructor]color: func(r: float32, g: float32, b: float32, a: float32) -> color;
%[static]color.from-rgba: func(r: u8, g: u8, b: u8, a: u8) -> color;
%[static]color.from-hex: func(hex: u32) -> color;
%[method]color.to-vec: func(self: borrow) -> vec4;
%[static]color.from-vec: func(vec: vec4) -> vec4;
```
However, this fails like so:
```
Caused by:
identifiers must have characters between '-'s
--> C:\Users\...\host.wit:43:3
|
43 | %[constructor]color: func(r: float32, g: float32, b: float32, a: float32) -> color;
| ^
```
So there seems no `wit-bindgen`-compatible way to express a `plainname` of `'[constructor]' | '[method]' '.' | '[static]' '.' ` and/or no `wit-bindgen`-compatible way to express "associated functions" and "associated methods" on non-resource types.
Is this something that is supported by wit? Is this something supported by the component model itself?
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.