@@ -643,7 +643,7 @@ interface a {
643
643
resource r;
644
644
}
645
645
interface b {
646
- use a.{r};
646
+ use a.{r};
647
647
foo: func() -> r;
648
648
}
649
649
@@ -946,33 +946,36 @@ required to always be paired up with either a `@since` or `@deprecated` gate.
946
946
Together, these gates support a development flow in which new features start
947
947
with an ` @unstable ` gate while the details are still being hashed out. Then,
948
948
once 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
955
952
` fancy-foo ` feature is explicitly enabled by the developer. The ` feature ` field
956
953
can be removed once producer toolchains have updated their default version to
957
954
enable the feature by default.
958
955
959
- Specifically, the syntax for feature gates is:
956
+ #### Feature gate syntax
957
+
958
+ The grammar that governs feature gate syntax is:
959
+
960
960
``` wit
961
961
gate ::= gate-item*
962
962
gate-item ::= unstable-gate
963
963
| since-gate
964
964
| deprecated-gate
965
965
966
966
unstable-gate ::= '@unstable' '(' feature-field ')'
967
- since-gate ::= '@since' '(' version-field ( ',' feature-field )? ')'
967
+ since-gate ::= '@since' '(' version-field ')'
968
968
deprecated-gate ::= '@deprecated' '(' version-field ')'
969
969
970
970
feature-field ::= 'feature' '=' id
971
971
version-field ::= 'version' '=' <valid semver>
972
972
```
973
973
974
+ #### Rules for feature gate usage
975
+
974
976
As part of WIT validation, any item that refers to another gated item must also
975
977
be compatibly gated. For example, this is an error:
978
+
976
979
``` wit
977
980
interface i {
978
981
@since(version = 1.0.1)
@@ -981,6 +984,7 @@ interface i {
981
984
type t2 = t1; // error
982
985
}
983
986
```
987
+
984
988
Additionally, if an item is * contained* by a gated item, it must also be
985
989
compatibly gated. For example, this is an error:
986
990
``` wit
@@ -993,6 +997,157 @@ interface i {
993
997
}
994
998
```
995
999
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:[email protected] ` )
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:[email protected] ;
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:[email protected] ;
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:[email protected] ;
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:[email protected] ;
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:[email protected] ;
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:[email protected] ;
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
+
996
1151
## Package declaration
997
1152
[ package declaration ] : #package-declaration
998
1153
0 commit comments