Socket
Book a DemoSign in
Socket

wit-bindgen-core

Package Overview
Dependencies
Maintainers
0
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

wit-bindgen-core - cargo Package Compare versions

Comparing version
0.52.0
to
0.53.0
+1
-1
.cargo_vcs_info.json
{
"git": {
"sha1": "3dfc82a753ac7e514802a618ddedb24dd51048fe"
"sha1": "51080a08cafd3e056abf17f75bf9b7a01a98a8a7"
},
"path_in_vcs": "crates/core"
}

@@ -120,2 +120,8 @@ # This file is automatically @generated by Cargo.

[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "hashbrown"

@@ -125,2 +131,5 @@ version = "0.16.1"

checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
dependencies = [
"foldhash",
]

@@ -135,5 +144,5 @@ [[package]]

name = "id-arena"
version = "2.2.1"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"

@@ -286,5 +295,5 @@ [[package]]

name = "wasmparser"
version = "0.244.0"
version = "0.245.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
checksum = "48a767a48974f0c8b66f211b96e01aa77feed58b8ccce4e7f0cff0ae55b174d4"
dependencies = [

@@ -313,3 +322,3 @@ "bitflags",

name = "wit-bindgen-core"
version = "0.52.0"
version = "0.53.0"
dependencies = [

@@ -325,7 +334,8 @@ "anyhow",

name = "wit-parser"
version = "0.244.0"
version = "0.245.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
checksum = "b5cda4f69fdc5a8d54f7032262217dd89410a933e3f86fdad854f5833caf3ccb"
dependencies = [
"anyhow",
"hashbrown",
"id-arena",

@@ -332,0 +342,0 @@ "indexmap",

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "wit-bindgen-core"
version = "0.52.0"
version = "0.53.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]

@@ -61,3 +61,3 @@ build = false

[dependencies.wit-parser]
version = "0.244.0"
version = "0.245.0"

@@ -64,0 +64,0 @@ [lints.clippy]

@@ -26,3 +26,6 @@ use std::fmt::Write;

pub trait WorldGenerator {
fn generate(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> Result<()> {
fn generate(&mut self, resolve: &mut Resolve, id: WorldId, files: &mut Files) -> Result<()> {
if self.uses_nominal_type_ids() {
resolve.generate_nominal_type_ids(id);
}
let world = &resolve.worlds[id];

@@ -46,3 +49,3 @@ self.preprocess(resolve, id);

}
WorldItem::Type(id) => types.push((unwrap_name(name), *id)),
WorldItem::Type { id, .. } => types.push((unwrap_name(name), *id)),
}

@@ -71,3 +74,3 @@ }

WorldItem::Interface { id, .. } => interfaces.push((name, id)),
WorldItem::Type(_) => unreachable!(),
WorldItem::Type { .. } => unreachable!(),
}

@@ -87,2 +90,9 @@ }

/// Whether or not this bindings generator expects
/// [`Resolve::generate_nominal_type_ids`] to be used before generating
/// bindings.
fn uses_nominal_type_ids(&self) -> bool {
true
}
fn finish_imports(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) {

@@ -173,24 +183,31 @@ let _ = (resolve, world, files);

fn define_type(&mut self, name: &str, id: TypeId) {
let ty = &self.resolve().types[id];
match &ty.kind {
TypeDefKind::Record(record) => self.type_record(id, name, record, &ty.docs),
TypeDefKind::Resource => self.type_resource(id, name, &ty.docs),
TypeDefKind::Flags(flags) => self.type_flags(id, name, flags, &ty.docs),
TypeDefKind::Tuple(tuple) => self.type_tuple(id, name, tuple, &ty.docs),
TypeDefKind::Enum(enum_) => self.type_enum(id, name, enum_, &ty.docs),
TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs),
TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs),
TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
TypeDefKind::Future(t) => self.type_future(id, name, t, &ty.docs),
TypeDefKind::Stream(t) => self.type_stream(id, name, t, &ty.docs),
TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
TypeDefKind::FixedSizeList(..) => todo!(),
TypeDefKind::Map(..) => todo!(),
TypeDefKind::Unknown => unreachable!(),
}
define_type(self, name, id)
}
}
pub fn define_type<'a, T>(generator: &mut T, name: &str, id: TypeId)
where
T: InterfaceGenerator<'a> + ?Sized,
{
let ty = &generator.resolve().types[id];
match &ty.kind {
TypeDefKind::Record(record) => generator.type_record(id, name, record, &ty.docs),
TypeDefKind::Resource => generator.type_resource(id, name, &ty.docs),
TypeDefKind::Flags(flags) => generator.type_flags(id, name, flags, &ty.docs),
TypeDefKind::Tuple(tuple) => generator.type_tuple(id, name, tuple, &ty.docs),
TypeDefKind::Enum(enum_) => generator.type_enum(id, name, enum_, &ty.docs),
TypeDefKind::Variant(variant) => generator.type_variant(id, name, variant, &ty.docs),
TypeDefKind::Option(t) => generator.type_option(id, name, t, &ty.docs),
TypeDefKind::Result(r) => generator.type_result(id, name, r, &ty.docs),
TypeDefKind::List(t) => generator.type_list(id, name, t, &ty.docs),
TypeDefKind::Type(t) => generator.type_alias(id, name, t, &ty.docs),
TypeDefKind::Future(t) => generator.type_future(id, name, t, &ty.docs),
TypeDefKind::Stream(t) => generator.type_stream(id, name, t, &ty.docs),
TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
TypeDefKind::FixedLengthList(..) => todo!(),
TypeDefKind::Map(..) => todo!(),
TypeDefKind::Unknown => unreachable!(),
}
}
pub trait AnonymousTypeGenerator<'a> {

@@ -227,3 +244,3 @@ fn resolve(&self) -> &'a Resolve;

TypeDefKind::Handle(handle) => self.anonymous_type_handle(id, handle, &ty.docs),
TypeDefKind::FixedSizeList(t, size) => {
TypeDefKind::FixedLengthList(t, size) => {
self.anonymous_type_fixed_length_list(id, t, *size, &ty.docs)

@@ -230,0 +247,0 @@ }

@@ -8,2 +8,3 @@ use std::collections::HashMap;

type_info: HashMap<TypeId, TypeInfo>,
equal_types: UnionFind,
}

@@ -85,3 +86,5 @@

}
WorldItem::Interface { id, stability: _ } => {
WorldItem::Interface {
id, stability: _, ..
} => {
for (_, f) in resolve.interfaces[*id].functions.iter() {

@@ -91,3 +94,3 @@ self.type_info_func(resolve, f, import);

}
WorldItem::Type(_) => {}
WorldItem::Type { .. } => {}
}

@@ -98,5 +101,40 @@ }

/// Populates the return value of [`Types::get_representative_type`] with
/// the `resolve` passed in.
///
/// The `may_alias_another_type` closure is used to determine whether the
/// language's definition of the provided `TypeId` might possibly alias
/// some other type in a language. This is a language-specific deduction
/// which can also be affected by options to a binding generator. If a type
/// can't be aliased by anything else then it can't be considered equal to
/// anything else. Note that in this situations other types may still
/// be equal to it, such as aliased types at the WIT level (e.g. `type foo
/// = some-record`).
pub fn collect_equal_types(
&mut self,
resolve: &Resolve,
may_alias_another_type: &dyn Fn(TypeId) -> bool,
) {
for (i, (ty, _)) in resolve.types.iter().enumerate() {
if !may_alias_another_type(ty) {
continue;
}
// TODO: we could define a hash function for TypeDefKind to prevent the inner loop.
for (earlier, _) in resolve.types.iter().take(i) {
if self.equal_types.find(ty) == self.equal_types.find(earlier) {
continue;
}
// The correctness of is_structurally_equal relies on the fact
// that resolve.types.iter() is in topological order.
if self.is_structurally_equal(resolve, ty, earlier) {
self.equal_types.union(ty, earlier);
break;
}
}
}
}
fn type_info_func(&mut self, resolve: &Resolve, func: &Function, import: bool) {
let mut live = LiveTypes::default();
for (_, ty) in func.params.iter() {
for Param { ty, .. } in func.params.iter() {
self.type_info(resolve, ty);

@@ -210,3 +248,3 @@ live.add_type(resolve, ty);

}
TypeDefKind::FixedSizeList(ty, _) => {
TypeDefKind::FixedLengthList(ty, _) => {
info = self.type_info(resolve, ty);

@@ -239,2 +277,183 @@ }

}
fn is_structurally_equal(&mut self, resolve: &Resolve, a: TypeId, b: TypeId) -> bool {
let a_def = &resolve.types[a].kind;
let b_def = &resolve.types[b].kind;
if self.equal_types.find(a) == self.equal_types.find(b) {
return true;
}
match (a_def, b_def) {
// Peel off typedef layers and continue recursing.
(TypeDefKind::Type(a), _) => self.type_id_equal_to_type(resolve, b, a),
(_, TypeDefKind::Type(b)) => self.type_id_equal_to_type(resolve, a, b),
(TypeDefKind::Record(ra), TypeDefKind::Record(rb)) => {
ra.fields.len() == rb.fields.len()
// Fields are ordered in WIT, so record {a: T, b: U} is different from {b: U, a: T}
&& ra.fields.iter().zip(rb.fields.iter()).all(|(fa, fb)| {
fa.name == fb.name && self.types_equal(resolve, &fa.ty, &fb.ty)
})
}
(TypeDefKind::Record(_), _) => false,
(TypeDefKind::Variant(va), TypeDefKind::Variant(vb)) => {
va.cases.len() == vb.cases.len()
&& va.cases.iter().zip(vb.cases.iter()).all(|(ca, cb)| {
ca.name == cb.name && self.optional_types_equal(resolve, &ca.ty, &cb.ty)
})
}
(TypeDefKind::Variant(_), _) => false,
(TypeDefKind::Enum(ea), TypeDefKind::Enum(eb)) => {
ea.cases.len() == eb.cases.len()
&& ea
.cases
.iter()
.zip(eb.cases.iter())
.all(|(ca, cb)| ca.name == cb.name)
}
(TypeDefKind::Enum(_), _) => false,
(TypeDefKind::Flags(fa), TypeDefKind::Flags(fb)) => {
fa.flags.len() == fb.flags.len()
&& fa
.flags
.iter()
.zip(fb.flags.iter())
.all(|(fa, fb)| fa.name == fb.name)
}
(TypeDefKind::Flags(_), _) => false,
(TypeDefKind::Tuple(ta), TypeDefKind::Tuple(tb)) => {
ta.types.len() == tb.types.len()
&& ta
.types
.iter()
.zip(tb.types.iter())
.all(|(a, b)| self.types_equal(resolve, a, b))
}
(TypeDefKind::Tuple(_), _) => false,
(TypeDefKind::List(la), TypeDefKind::List(lb)) => self.types_equal(resolve, la, lb),
(TypeDefKind::List(_), _) => false,
(TypeDefKind::FixedLengthList(ta, sa), TypeDefKind::FixedLengthList(tb, sb)) => {
sa == sb && self.types_equal(resolve, ta, tb)
}
(TypeDefKind::FixedLengthList(..), _) => false,
(TypeDefKind::Option(oa), TypeDefKind::Option(ob)) => self.types_equal(resolve, oa, ob),
(TypeDefKind::Option(_), _) => false,
(TypeDefKind::Result(ra), TypeDefKind::Result(rb)) => {
self.optional_types_equal(resolve, &ra.ok, &rb.ok)
&& self.optional_types_equal(resolve, &ra.err, &rb.err)
}
(TypeDefKind::Result(_), _) => false,
(TypeDefKind::Map(ak, av), TypeDefKind::Map(bk, bv)) => {
self.types_equal(resolve, ak, bk) && self.types_equal(resolve, av, bv)
}
(TypeDefKind::Map(..), _) => false,
(TypeDefKind::Future(a), TypeDefKind::Future(b)) => {
self.optional_types_equal(resolve, a, b)
}
(TypeDefKind::Future(..), _) => false,
(TypeDefKind::Stream(a), TypeDefKind::Stream(b)) => {
self.optional_types_equal(resolve, a, b)
}
(TypeDefKind::Stream(..), _) => false,
(TypeDefKind::Handle(a), TypeDefKind::Handle(b)) => match (a, b) {
(Handle::Own(a), Handle::Own(b)) | (Handle::Borrow(a), Handle::Borrow(b)) => {
self.is_structurally_equal(resolve, *a, *b)
}
(Handle::Own(_) | Handle::Borrow(_), _) => false,
},
(TypeDefKind::Handle(_), _) => false,
(TypeDefKind::Unknown, _) => unreachable!(),
// Resources are only equal if their original ids are equal,
// otherwise all resources are un-equal to each other.
(TypeDefKind::Resource, TypeDefKind::Resource) => a == b,
(TypeDefKind::Resource, _) => false,
}
}
fn types_equal(&mut self, resolve: &Resolve, a: &Type, b: &Type) -> bool {
match (a, b) {
// Peel off typedef layers and continue recursing.
(Type::Id(a), b) => self.type_id_equal_to_type(resolve, *a, b),
(a, Type::Id(b)) => self.type_id_equal_to_type(resolve, *b, a),
// When both a and b are primitives, they're only equal of
// the primitives are the same.
(
Type::Bool
| Type::U8
| Type::S8
| Type::U16
| Type::S16
| Type::U32
| Type::S32
| Type::U64
| Type::S64
| Type::F32
| Type::F64
| Type::Char
| Type::String
| Type::ErrorContext,
_,
) => a == b,
}
}
fn type_id_equal_to_type(&mut self, resolve: &Resolve, a: TypeId, b: &Type) -> bool {
let ak = &resolve.types[a].kind;
match (ak, b) {
(TypeDefKind::Type(a), b) => self.types_equal(resolve, a, b),
(_, Type::Id(b)) => self.is_structurally_equal(resolve, a, *b),
// Type `a` isn't a typedef, and type `b` is a primitive, so it's no
// longer possible for them to be equal.
_ => false,
}
}
fn optional_types_equal(
&mut self,
resolve: &Resolve,
a: &Option<Type>,
b: &Option<Type>,
) -> bool {
match (a, b) {
(Some(a), Some(b)) => self.types_equal(resolve, a, b),
(Some(_), None) | (None, Some(_)) => false,
(None, None) => true,
}
}
pub fn get_representative_type(&mut self, id: TypeId) -> TypeId {
self.equal_types.find(id)
}
}
#[derive(Default)]
pub struct UnionFind {
parent: HashMap<TypeId, TypeId>,
}
impl UnionFind {
fn find(&mut self, id: TypeId) -> TypeId {
// Path compression
let parent = self.parent.get(&id).copied().unwrap_or(id);
if parent != id {
let root = self.find(parent);
self.parent.insert(id, root);
root
} else {
id
}
}
fn union(&mut self, a: TypeId, b: TypeId) {
let ra = self.find(a);
let rb = self.find(b);
if ra != rb {
// Use smaller id as root for determinism
if ra < rb {
self.parent.insert(rb, ra);
} else {
self.parent.insert(ra, rb);
}
}
}
}

Sorry, the diff of this file is too big to display