diff --git a/design/mvp/Binary.md b/design/mvp/Binary.md index 590a3924..9aa67221 100644 --- a/design/mvp/Binary.md +++ b/design/mvp/Binary.md @@ -401,8 +401,9 @@ Notes: `[static]` matches the `plainname` of a preceding `resource` import or export, respectively, in the same scope (component, component type or instance type). -* Validation of `[constructor]` names requires that the `func` returns a - `(result (own $R))`, where `$R` is the resource labeled `r`. +* Validation of `[constructor]` names requires a `func` type whose result type + is either `(own $R)` or `(result (own $R) E?)` where `$R` is a resource type + labeled `r`. * Validation of `[method]` names requires the first parameter of the function to be `(param "self" (borrow $R))`, where `$R` is the resource labeled `r`. * 🔗 Validation requires that `versionsuffix` is preceded by an `interfaceversion` diff --git a/design/mvp/Explainer.md b/design/mvp/Explainer.md index 9d1f6c6f..9c99e433 100644 --- a/design/mvp/Explainer.md +++ b/design/mvp/Explainer.md @@ -2454,9 +2454,19 @@ generators to insert the function into the nested scope of a class, abstract data type, object, namespace, package, module or whatever resources get bound to. For example, a function named `[method]C.foo` could be bound in C++ to a member function `foo` in a class `C`. The JS API [below](#JS-API) describes how -the native JavaScript bindings could look. Validation described in -[Binary.md](Binary.md) inspects the contents of `plainname` and ensures that -the function has a compatible signature. +the native JavaScript bindings could look. + +To restrict the set of cases that bindings generators need to consider, these +annotations trigger additional type-validation rules (listed in +[Binary.md](Binary.md)) such as: +* An import or export named `[static]R.foo` must be a function and `R` must + be the name of an imported or exported resource type in the same `instance` + or `component` type. +* Similarly, an import or export named `[constructor]R` must be a function + whose return type must be `(own $R)` or `(result (own $R) (error )?)` + where `$R` is the type-index of the resource type named `R`. +* Similarly, an import or export named `[method]R.foo` must be a function whose + first parameter must be `(param "self" (borrow $R))`. When a function is annotated with `async`, bindings generators are expected to emit whatever asynchronous language construct is appropriate (such as an diff --git a/design/mvp/WIT.md b/design/mvp/WIT.md index 313d6770..dd0d425d 100644 --- a/design/mvp/WIT.md +++ b/design/mvp/WIT.md @@ -1641,6 +1641,10 @@ 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. +Constructors can be fallible or infallible. Fallible constructors have an +explicitly-written return type which must be of the form `result` +where `r` is the name of the containing `resource`. Infallible constructors +have no written return type and are given the implicit return type `r`. For example, the following resource definition: ```wit @@ -1650,11 +1654,15 @@ resource blob { read: func(n: u32) -> list; merge: static func(lhs: borrow, rhs: borrow) -> blob; } +resource blob2 { + constructor(init: list) -> result; +} ``` desugars into: ```wit resource blob; %[constructor]blob: func(init: list) -> blob; +%[constructor]blob2: func(init: list) -> result; %[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;