Skip to content

Commit c8f071e

Browse files
authored
fix mismatch in stability attributes error in wit-parser (#2076)
When a new interface is marked as @unstable (feature = somefeaturegate) and it uses a stable type from another package via use package:interface/type.{name} the resulting package should be able to be imported into other packages that use it. The use case for this is adding a unstable interface such as wasi-tls to wasi-cli. Once we get to resolve_include's processing we've already verified that everything checks out from a feature/version perspective for those features. i.e. we can't be trying to consolidate an interface type with a feature that hasn't already been resolved. Signed-off-by: James Sturtevant <[email protected]>
1 parent 4e8c4c3 commit c8f071e

File tree

4 files changed

+513
-18
lines changed

4 files changed

+513
-18
lines changed

crates/wit-parser/src/lib.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -1176,18 +1176,21 @@ fn find_futures_and_streams(resolve: &Resolve, ty: Type, results: &mut Vec<TypeI
11761176
///
11771177
/// This is added for WebAssembly/component-model#332 where @since and @unstable
11781178
/// annotations were added to WIT.
1179-
#[derive(Debug, Clone, PartialEq, Eq)]
1179+
///
1180+
/// The order of the of enum values is significant since it is used with Ord and PartialOrd
1181+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
11801182
#[cfg_attr(feature = "serde", derive(serde_derive::Deserialize, Serialize))]
11811183
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
11821184
pub enum Stability {
1183-
/// `@since(version = 1.2.3)`
1185+
/// This item does not have either `@since` or `@unstable`.
1186+
Unknown,
1187+
1188+
/// `@unstable(feature = foo)`
11841189
///
1185-
/// This item is explicitly tagged with `@since` as stable since the
1186-
/// specified version. This may optionally have a feature listed as well.
1187-
Stable {
1188-
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_version"))]
1189-
#[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_version"))]
1190-
since: Version,
1190+
/// This item is explicitly tagged `@unstable`. A feature name is listed and
1191+
/// this item is excluded by default in `Resolve` unless explicitly enabled.
1192+
Unstable {
1193+
feature: String,
11911194
#[cfg_attr(
11921195
feature = "serde",
11931196
serde(
@@ -1200,12 +1203,14 @@ pub enum Stability {
12001203
deprecated: Option<Version>,
12011204
},
12021205

1203-
/// `@unstable(feature = foo)`
1206+
/// `@since(version = 1.2.3)`
12041207
///
1205-
/// This item is explicitly tagged `@unstable`. A feature name is listed and
1206-
/// this item is excluded by default in `Resolve` unless explicitly enabled.
1207-
Unstable {
1208-
feature: String,
1208+
/// This item is explicitly tagged with `@since` as stable since the
1209+
/// specified version. This may optionally have a feature listed as well.
1210+
Stable {
1211+
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_version"))]
1212+
#[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_version"))]
1213+
since: Version,
12091214
#[cfg_attr(
12101215
feature = "serde",
12111216
serde(
@@ -1217,9 +1222,6 @@ pub enum Stability {
12171222
)]
12181223
deprecated: Option<Version>,
12191224
},
1220-
1221-
/// This item does not have either `@since` or `@unstable`.
1222-
Unknown,
12231225
}
12241226

12251227
impl Stability {

crates/wit-parser/src/resolve.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -3411,7 +3411,7 @@ impl Remap {
34113411
},
34123412
) => {
34133413
assert_eq!(*aid, *bid);
3414-
update_stability(astability, bstability)?;
3414+
merge_stability(astability, bstability)?;
34153415
}
34163416
(WorldItem::Interface { .. }, _) => unreachable!(),
34173417
(WorldItem::Function(_), _) => unreachable!(),
@@ -3837,7 +3837,28 @@ fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {
38373837

38383838
// Failing all that this means that the two attributes are different so
38393839
// generate an error.
3840-
bail!("mismatch in stability attributes")
3840+
bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
3841+
}
3842+
3843+
/// Compares the two attributes and if the `from` is more stable than the `into` then
3844+
/// it will elevate the `into` to the same stability.
3845+
/// This should be used after its already been confirmed that the types are the same and
3846+
/// should be apart of the component because versions/features are enabled.
3847+
fn merge_stability(from: &Stability, into: &mut Stability) -> Result<()> {
3848+
// If the two stability annotations are equal then
3849+
// there's nothing to do here.
3850+
if from == into {
3851+
return Ok(());
3852+
}
3853+
3854+
// if the from is more stable elevate stability of into
3855+
if from > into {
3856+
*into = from.clone();
3857+
return Ok(());
3858+
}
3859+
3860+
// otherwise `into`` already has higher stability
3861+
return Ok(());
38413862
}
38423863

38433864
/// An error that can be returned during "world elaboration" during various
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package wasmtime:test;
2+
3+
world test{
4+
@unstable(feature = active)
5+
include wasi:unstable/imports@0.2.3;
6+
include wasi:foo/imports@0.2.3;
7+
}
8+
9+
world test-ordered{
10+
include wasi:foo/imports@0.2.3;
11+
@unstable(feature = active)
12+
include wasi:unstable/imports@0.2.3;
13+
}
14+
15+
package wasi:unstable@0.2.3 {
16+
@unstable(feature = active)
17+
world imports {
18+
@unstable(feature = active)
19+
use wasi:dep2/[email protected].{stable-resource};
20+
@unstable(feature = active)
21+
use wasi:dep-unversioned/unversioned.{unversioned-resource};
22+
@unstable(feature = active)
23+
use wasi:dep-unstable/unstable.{unstable-resource};
24+
}
25+
}
26+
27+
package wasi:foo@0.2.3 {
28+
@since(version = 0.2.0)
29+
world imports {
30+
@since(version = 0.2.0)
31+
include wasi:dep2/[email protected];
32+
include wasi:dep-unversioned/imports;
33+
include wasi:dep-unstable/imports;
34+
}
35+
}
36+
37+
package wasi:dep2@0.2.3 {
38+
@since(version = 0.2.0)
39+
world imports {
40+
@since(version = 0.2.0)
41+
import stable;
42+
}
43+
@since(version = 0.2.1)
44+
interface stable {
45+
resource stable-resource {
46+
}
47+
}
48+
}
49+
50+
package wasi:dep-unversioned{
51+
world imports {
52+
import unversioned;
53+
}
54+
interface unversioned {
55+
resource unversioned-resource {
56+
57+
}
58+
}
59+
}
60+
61+
package wasi:dep-unstable{
62+
@unstable(feature = active)
63+
world imports {
64+
@unstable(feature = active)
65+
import unstable;
66+
}
67+
@unstable(feature = active)
68+
interface unstable {
69+
@unstable(feature = active)
70+
resource unstable-resource {
71+
72+
}
73+
}
74+
}
75+

0 commit comments

Comments
 (0)