Skip to content

fix mismatch in stability attributes error in wit-parser #2076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions crates/wit-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,18 +1079,21 @@ fn find_futures_and_streams(resolve: &Resolve, ty: Type, results: &mut Vec<TypeI
///
/// This is added for WebAssembly/component-model#332 where @since and @unstable
/// annotations were added to WIT.
#[derive(Debug, Clone, PartialEq, Eq)]
///
/// The order of the of enum values is significant since it is used with Ord and PartialOrd
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde_derive::Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
pub enum Stability {
/// `@since(version = 1.2.3)`
/// This item does not have either `@since` or `@unstable`.
Unknown,

/// `@unstable(feature = foo)`
///
/// This item is explicitly tagged with `@since` as stable since the
/// specified version. This may optionally have a feature listed as well.
Stable {
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_version"))]
#[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_version"))]
since: Version,
/// This item is explicitly tagged `@unstable`. A feature name is listed and
/// this item is excluded by default in `Resolve` unless explicitly enabled.
Unstable {
feature: String,
#[cfg_attr(
feature = "serde",
serde(
Expand All @@ -1103,12 +1106,14 @@ pub enum Stability {
deprecated: Option<Version>,
},

/// `@unstable(feature = foo)`
/// `@since(version = 1.2.3)`
///
/// This item is explicitly tagged `@unstable`. A feature name is listed and
/// this item is excluded by default in `Resolve` unless explicitly enabled.
Unstable {
feature: String,
/// This item is explicitly tagged with `@since` as stable since the
/// specified version. This may optionally have a feature listed as well.
Stable {
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_version"))]
#[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_version"))]
since: Version,
#[cfg_attr(
feature = "serde",
serde(
Expand All @@ -1120,9 +1125,6 @@ pub enum Stability {
)]
deprecated: Option<Version>,
},

/// This item does not have either `@since` or `@unstable`.
Unknown,
}

impl Stability {
Expand Down
25 changes: 23 additions & 2 deletions crates/wit-parser/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3414,7 +3414,7 @@ impl Remap {
},
) => {
assert_eq!(*aid, *bid);
update_stability(astability, bstability)?;
merge_stability(astability, bstability)?;
}
(WorldItem::Interface { .. }, _) => unreachable!(),
(WorldItem::Function(_), _) => unreachable!(),
Expand Down Expand Up @@ -3833,7 +3833,28 @@ fn update_stability(from: &Stability, into: &mut Stability) -> Result<()> {

// Failing all that this means that the two attributes are different so
// generate an error.
bail!("mismatch in stability attributes")
bail!("mismatch in stability from '{:?}' to '{:?}'", from, into)
}

/// Compares the two attributes and if the `from` is more stable than the `into` then
/// it will elevate the `into` to the same stability.
/// This should be used after its already been confirmed that the types are the same and
/// should be apart of the component because versions/features are enabled.
fn merge_stability(from: &Stability, into: &mut Stability) -> Result<()> {
// If the two stability annotations are equal then
// there's nothing to do here.
if from == into {
return Ok(());
}

// if the from is more stable elevate stability of into
if from > into {
*into = from.clone();
return Ok(());
}

// otherwise `into`` already has higher stability
return Ok(());
}

/// An error that can be returned during "world elaboration" during various
Expand Down
75 changes: 75 additions & 0 deletions crates/wit-parser/tests/ui/gated-include-use-with-stable.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package wasmtime:test;

world test{
@unstable(feature = active)
include wasi:unstable/[email protected];
include wasi:foo/[email protected];
}

world test-ordered{
include wasi:foo/[email protected];
@unstable(feature = active)
include wasi:unstable/[email protected];
}

package wasi:[email protected] {
@unstable(feature = active)
world imports {
@unstable(feature = active)
use wasi:dep2/[email protected].{stable-resource};
@unstable(feature = active)
use wasi:dep-unversioned/unversioned.{unversioned-resource};
@unstable(feature = active)
use wasi:dep-unstable/unstable.{unstable-resource};
}
}

package wasi:[email protected] {
@since(version = 0.2.0)
world imports {
@since(version = 0.2.0)
include wasi:dep2/[email protected];
include wasi:dep-unversioned/imports;
include wasi:dep-unstable/imports;
}
}

package wasi:[email protected] {
@since(version = 0.2.0)
world imports {
@since(version = 0.2.0)
import stable;
}
@since(version = 0.2.1)
interface stable {
resource stable-resource {
}
}
}

package wasi:dep-unversioned{
world imports {
import unversioned;
}
interface unversioned {
resource unversioned-resource {

}
}
}

package wasi:dep-unstable{
@unstable(feature = active)
world imports {
@unstable(feature = active)
import unstable;
}
@unstable(feature = active)
interface unstable {
@unstable(feature = active)
resource unstable-resource {

}
}
}

Loading