Skip to content

Commit 0a39c42

Browse files
Add explicit scenarios for feature gate usage
This commit addds some explanation of the intended usage pattern of feature gates in order to make the transition points and functionality easier to identify/reason about. Signed-off-by: Victor Adossi <[email protected]>
1 parent de2bc23 commit 0a39c42

File tree

1 file changed

+123
-7
lines changed

1 file changed

+123
-7
lines changed

design/mvp/WIT.md

+123-7
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ interface a {
642642
resource r;
643643
}
644644
interface b {
645-
use a.{r};
645+
use a.{r};
646646
foo: func() -> r;
647647
}
648648
@@ -966,17 +966,21 @@ required to always be paired up with either a `@since` or `@deprecated` gate.
966966
Together, these gates support a development flow in which new features start
967967
with an `@unstable` gate while the details are still being hashed out. Then,
968968
once the feature is stable (and, in a WASI context, voted upon), the
969-
`@unstable` gate is switched to a `@since` gate. To enable a smooth transition
970-
(during which producer toolchains are targeting a version earlier than the
971-
`@since`-specified `version`), the `@since` gate contains an optional `feature`
972-
field that, when present, says to enable the feature when *either* the target
973-
version is greator-or-equal *or* the feature name is explicitly enabled by the
974-
developer. Thus, `c` is enabled if the version is `0.2.2` or newer or the
969+
`@unstable` gate is switched to a `@since` gate.
970+
971+
To enable a smooth transition (during which producer toolchains are targeting a
972+
version earlier than the `@since`-specified `version`), the `@since` gate contains
973+
an optional `feature` field that, when present, says to enable the feature when
974+
*either* the target version is greater-or-equal *or* the feature name is explicitly
975+
enabled by the developer.
976+
977+
Thus, `c` is enabled if the version is `0.2.2` or newer or the
975978
`fancy-foo` feature is explicitly enabled by the developer. The `feature` field
976979
can be removed once producer toolchains have updated their default version to
977980
enable the feature by default.
978981

979982
Specifically, the syntax for feature gates is:
983+
980984
```wit
981985
gate ::= gate-item*
982986
gate-item ::= unstable-gate
@@ -993,6 +997,7 @@ version-field ::= 'version' '=' <valid semver>
993997

994998
As part of WIT validation, any item that refers to another gated item must also
995999
be compatibly gated. For example, this is an error:
1000+
9961001
```wit
9971002
interface i {
9981003
@since(version = 1.0.1)
@@ -1001,6 +1006,7 @@ interface i {
10011006
type t2 = t1; // error
10021007
}
10031008
```
1009+
10041010
Additionally, if an item is *contained* by a gated item, it must also be
10051011
compatibly gated. For example, this is an error:
10061012
```wit
@@ -1013,6 +1019,116 @@ interface i {
10131019
}
10141020
```
10151021

1022+
#### Scenario: Stabilization of a new feature
1023+
1024+
This section lays out the basic flow and expected usage of feature gate machinery when stabilizing a new feature.
1025+
1026+
Assume the following WIT package as the initial interface:
1027+
1028+
```wit
1029+
package examples:[email protected];
1030+
1031+
variant calc-error {
1032+
integer-overflow,
1033+
integer-underflow,
1034+
unexpected,
1035+
}
1036+
1037+
interface calc {
1038+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1039+
}
1040+
```
1041+
1042+
**First, add new items under an `@unstable` annotation with a `feature` specified:**
1043+
1044+
```wit
1045+
package examples:[email protected];
1046+
1047+
// ... elided ...
1048+
1049+
interface calc {
1050+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1051+
1052+
@unstable(feature = minus)
1053+
sub: func(x: i32, y: i32) -> result<i32, calc-error>;
1054+
}
1055+
```
1056+
1057+
At this point, consumers of the WIT can enable feature `minus` through their relevant tooling and get access to the `sub` function.
1058+
1059+
Note that if we had to *add* a new variant to `calc-error`, this would be a *breaking change* for most if not all downstream bindgen tooling (i.e. the enum would become a new object, incompatible with previous code).
1060+
1061+
**Second, when the feature is ready to be stabilized, switch to a `@since` annotation:**
1062+
1063+
```wit
1064+
package examples:[email protected];
1065+
1066+
// ... elided ...
1067+
1068+
interface calc {
1069+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1070+
1071+
@since(version = 0.1.2)
1072+
sub: func(x: i32, y: i32) -> result<i32, calc-error>;
1073+
}
1074+
```
1075+
1076+
While you *may* include the `feature` portion of `@since` (i.e. `@since(version = 0.1.2, feature = minus)`), it is *ignored* by tooling and is only informational once the feature is stabilized.
1077+
1078+
#### Scenario: Deprecation of an existing stable feature
1079+
1080+
This section lays out the basic flow and expected usage of feature gate machinery when stabilizing a new feature.
1081+
1082+
Assume the following WIT package as the initial interface:
1083+
1084+
```wit
1085+
package examples:[email protected];
1086+
1087+
variant calc-error {
1088+
integer-overflow,
1089+
integer-underflow,
1090+
unexpected,
1091+
}
1092+
1093+
interface calc {
1094+
add-one: func(x: i32) -> result<i32, calc-error>;
1095+
1096+
@since(version = 0.1.1)
1097+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1098+
}
1099+
```
1100+
1101+
**First: Add the `@deprecated` annotation to the relevant item in a new version**
1102+
1103+
```wit
1104+
package examples:[email protected];
1105+
1106+
// ... elided ..
1107+
1108+
interface calc {
1109+
@deprecated(version = 0.1.2)
1110+
add-one: func(x: i32) -> result<i32, calc-error>;
1111+
1112+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1113+
}
1114+
```
1115+
1116+
At this point, tooling consuming this WIT will be able to appropriately alert users to the now-deprecated `add-one` function.
1117+
1118+
**Second: cmpletely remove the deprecated item in the next SemVer-compliant major version**
1119+
1120+
```wit
1121+
package examples:[email protected];
1122+
1123+
// ... elided ..
1124+
1125+
interface calc {
1126+
add: func(x: i32, y: i32) -> result<i32, calc-error>;
1127+
}
1128+
```
1129+
1130+
In this new "major" version (this is considered a major version under SemVer 0.X rules) -- the `add-one` function can be fully removed.
1131+
10161132
## Package declaration
10171133
[package declaration]: #package-declaration
10181134

0 commit comments

Comments
 (0)