bytecodealliance / bytecodealliance/wit-bindgen

"associated functions" and "associated methods" on non-resource types

Open
#815 1 comment 2 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.