@@ -643,7 +643,7 @@ interface a {
643643 resource r;
644644}
645645interface b {
646- use a.{r};
646+ use a.{r};
647647 foo: func() -> r;
648648}
649649
@@ -946,33 +946,36 @@ required to always be paired up with either a `@since` or `@deprecated` gate.
946946Together, these gates support a development flow in which new features start
947947with an ` @unstable ` gate while the details are still being hashed out. Then,
948948once the feature is stable (and, in a WASI context, voted upon), the
949- ` @unstable ` gate is switched to a ` @since ` gate. To enable a smooth transition
950- (during which producer toolchains are targeting a version earlier than the
951- ` @since ` -specified ` version ` ), the ` @since ` gate contains an optional ` feature `
952- field that, when present, says to enable the feature when * either* the target
953- version is greator-or-equal * or* the feature name is explicitly enabled by the
954- developer. Thus, ` c ` is enabled if the version is ` 0.2.2 ` or newer or the
949+ ` @unstable ` gate is switched to a ` @since ` gate.
950+
951+ Thus, ` c ` is enabled if the version is ` 0.2.2 ` or newer or the
955952` fancy-foo ` feature is explicitly enabled by the developer. The ` feature ` field
956953can be removed once producer toolchains have updated their default version to
957954enable the feature by default.
958955
959- Specifically, the syntax for feature gates is:
956+ #### Feature gate syntax
957+
958+ The grammar that governs feature gate syntax is:
959+
960960``` wit
961961gate ::= gate-item*
962962gate-item ::= unstable-gate
963963 | since-gate
964964 | deprecated-gate
965965
966966unstable-gate ::= '@unstable' '(' feature-field ')'
967- since-gate ::= '@since' '(' version-field ( ',' feature-field )? ')'
967+ since-gate ::= '@since' '(' version-field ')'
968968deprecated-gate ::= '@deprecated' '(' version-field ')'
969969
970970feature-field ::= 'feature' '=' id
971971version-field ::= 'version' '=' <valid semver>
972972```
973973
974+ #### Rules for feature gate usage
975+
974976As part of WIT validation, any item that refers to another gated item must also
975977be compatibly gated. For example, this is an error:
978+
976979``` wit
977980interface i {
978981 @since(version = 1.0.1)
@@ -981,6 +984,7 @@ interface i {
981984 type t2 = t1; // error
982985}
983986```
987+
984988Additionally, if an item is * contained* by a gated item, it must also be
985989compatibly gated. For example, this is an error:
986990``` wit
@@ -993,6 +997,157 @@ interface i {
993997}
994998```
995999
1000+ The following rules apply to the use of feature gates:
1001+
1002+ - Either ` @since ` * or* ` @unstable ` should be used, but not both (exclusive or).
1003+ - If a package contains a feature gate, it's version must be specified (i.e. ` namespace:package@x.y.z ` )
1004+
1005+ #### Scenario: Stabilization of a new feature
1006+
1007+ This section lays out the basic flow and expected usage of feature gate machinery
1008+ when stabilizing new features and deprecating old ones.
1009+
1010+ Assume the following WIT package as the initial interface:
1011+
1012+ ``` wit
1013+ package examples:fgates-calc@0.1.0;
1014+
1015+ @since(version = 0.1.0)
1016+ interface calc {
1017+ @since(version = 0.1.0)
1018+ variant calc-error {
1019+ integer-overflow,
1020+ integer-underflow,
1021+ unexpected,
1022+ }
1023+
1024+ @since(version = 0.1.0)
1025+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1026+ }
1027+ ```
1028+
1029+ ** First, add new items under an ` @unstable ` annotation with a ` feature ` specified:**
1030+
1031+ ``` wit
1032+ package examples:fgates-calc@0.1.1;
1033+
1034+ @since(version = 0.1.0)
1035+ interface calc {
1036+ @since(version = 0.1.0)
1037+ variant calc-error {
1038+ integer-overflow,
1039+ integer-underflow,
1040+ unexpected,
1041+ }
1042+
1043+ @since(version = 0.1.0)
1044+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1045+
1046+ /// By convention, feature flags should be prefixed with package name to reduce chance of collisions
1047+ ///
1048+ /// see: https://github.com/WebAssembly/WASI/blob/main/Contributing.md#filing-changes-to-existing-phase-3-proposals
1049+ @unstable(feature = fgates-calc-minus)
1050+ sub: func(x: i32, y: i32) -> result<i32, calc-error>;
1051+ }
1052+ ```
1053+
1054+ At this point, consumers of the WIT can enable feature ` fgates-calc-minus ` through their relevant tooling and get access to the ` sub ` function.
1055+
1056+ Note that, at least until subtyping is relaxed in the Component Model, if we had to * add* a new case to ` calc-error ` , this would be a * breaking change* and require either a new major version or adding a second, distinct ` variant ` definition used by new functions.
1057+
1058+ ** Second, when the feature is ready to be stabilized, switch to a ` @since ` annotation:**
1059+
1060+ ``` wit
1061+ package examples:fgates-calc@0.1.2;
1062+
1063+ @since(version = 0.1.0)
1064+ interface calc {
1065+ @since(version = 0.1.0)
1066+ variant calc-error {
1067+ integer-overflow,
1068+ integer-underflow,
1069+ unexpected,
1070+ }
1071+
1072+ @since(version = 0.1.0)
1073+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1074+
1075+ @since(version = 0.1.2)
1076+ sub: func(x: i32, y: i32) -> result<i32, calc-error>;
1077+ }
1078+ ```
1079+
1080+ #### Scenario: Deprecation of an existing stable feature
1081+
1082+ This section lays out the basic flow and expected usage of feature gate machinery when stabilizing a new feature.
1083+
1084+ Assume the following WIT package as the initial interface:
1085+
1086+ ``` wit
1087+ package examples:fgates-deprecation@0.1.1;
1088+
1089+ @since(version = 0.1.0)
1090+ interface calc {
1091+ @since(version = 0.1.0)
1092+ variant calc-error {
1093+ integer-overflow,
1094+ integer-underflow,
1095+ unexpected,
1096+ }
1097+
1098+ @since(version = 0.1.0)
1099+ add-one: func(x: i32) -> result<i32, calc-error>;
1100+
1101+ @since(version = 0.1.1)
1102+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1103+ }
1104+ ```
1105+
1106+ ** First: Add the ` @deprecated ` annotation to the relevant item in a new version**
1107+
1108+ ``` wit
1109+ package examples:fgates-deprecation@0.1.2;
1110+
1111+ @since(version = 0.1.0)
1112+ interface calc {
1113+ @since(version = 0.1.0)
1114+ variant calc-error {
1115+ integer-overflow,
1116+ integer-underflow,
1117+ unexpected,
1118+ }
1119+
1120+ @deprecated(version = 0.1.2)
1121+ add-one: func(x: i32) -> result<i32, calc-error>;
1122+
1123+ @since(version = 0.1.1)
1124+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1125+ }
1126+ ```
1127+
1128+ At this point, tooling consuming this WIT will be able to appropriately alert users to the now-deprecated ` add-one ` function.
1129+
1130+ ** Second: completely remove the deprecated item in some future SemVer-compliant major version**
1131+
1132+ ``` wit
1133+ package examples:fgates-deprecation@0.2.0;
1134+
1135+ @since(version = 0.1.0)
1136+ interface calc {
1137+ @since(version = 0.1.0)
1138+ variant calc-error {
1139+ integer-overflow,
1140+ integer-underflow,
1141+ unexpected,
1142+ }
1143+
1144+ @since(version = 0.1.1)
1145+ add: func(x: i32, y: i32) -> result<i32, calc-error>;
1146+ }
1147+ ```
1148+
1149+ In this new "major" version (this is considered a major version under SemVer 0.X rules) -- the ` add-one ` function can be fully removed.
1150+
9961151## Package declaration
9971152[ package declaration ] : #package-declaration
9981153
0 commit comments