Skip to content

Commit 672a70a

Browse files
committed
add codegen tests for futures, streams, and error-contexts
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 2f37f79 commit 672a70a

27 files changed

+461
-14
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ clap = { version = "4.3.19", features = ["derive"] }
3131
indexmap = "2.0.0"
3232
prettyplease = "0.2.20"
3333
syn = { version = "2.0", features = ["printing"] }
34+
futures = "0.3.31"
3435

3536
wasmparser = { git = "https://github.com/dicej/wasm-tools", branch = "async" }
3637
wasm-encoder = { git = "https://github.com/dicej/wasm-tools", branch = "async" }

crates/c/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,21 @@ void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
13421342
self.finish_typedef_struct(id);
13431343
}
13441344

1345+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
1346+
_ = (id, name, ty, docs);
1347+
todo!()
1348+
}
1349+
1350+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1351+
_ = (id, name, ty, docs);
1352+
todo!()
1353+
}
1354+
1355+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
1356+
_ = (id, name, docs);
1357+
todo!()
1358+
}
1359+
13451360
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
13461361
let _ = (id, name, ty, docs);
13471362
}

crates/c/tests/codegen.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ use std::process::Command;
66
use wit_parser::{Resolve, UnresolvedPackageGroup};
77

88
macro_rules! codegen_test {
9+
// TODO: implement support for stream, future, and error-context, and then
10+
// remove these lines:
11+
(streams $name:tt $test:tt) => {};
12+
(futures $name:tt $test:tt) => {};
13+
(resources_with_streams $name:tt $test:tt) => {};
14+
(resources_with_futures $name:tt $test:tt) => {};
15+
(error_context $name:tt $test:tt) => {};
16+
917
($id:ident $name:tt $test:tt) => {
1018
#[test]
1119
fn $id() {

crates/core/src/abi.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -845,9 +845,7 @@ fn needs_post_return(resolve: &Resolve, ty: &Type) -> bool {
845845
.filter_map(|t| t.as_ref())
846846
.any(|t| needs_post_return(resolve, t)),
847847
TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
848-
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {
849-
unimplemented!()
850-
}
848+
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => false,
851849
TypeDefKind::Unknown => unreachable!(),
852850
},
853851

crates/core/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ pub trait InterfaceGenerator<'a> {
170170
fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
171171
fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
172172
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
173+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
174+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
175+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs);
173176
fn types(&mut self, iface: InterfaceId) {
174177
let iface = &self.resolve().interfaces[iface];
175178
for (name, id) in iface.types.iter() {
@@ -190,12 +193,10 @@ pub trait InterfaceGenerator<'a> {
190193
TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
191194
TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
192195
TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
193-
TypeDefKind::Future(_) => panic!("future types do not require definition"),
194-
TypeDefKind::Stream(_) => panic!("stream types do not require definition"),
196+
TypeDefKind::Future(t) => self.type_future(id, name, t, &ty.docs),
197+
TypeDefKind::Stream(t) => self.type_stream(id, name, t, &ty.docs),
195198
TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
196-
TypeDefKind::ErrorContext => {
197-
panic!("the error-context type does not require definition")
198-
}
199+
TypeDefKind::ErrorContext => self.type_error_context(id, name, &ty.docs),
199200
TypeDefKind::Unknown => unreachable!(),
200201
}
201202
}

crates/core/src/types.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ impl Types {
193193
info = self.optional_type_info(resolve, r.ok.as_ref());
194194
info |= self.optional_type_info(resolve, r.err.as_ref());
195195
}
196-
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {}
196+
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {
197+
info.has_resource = true;
198+
}
197199
TypeDefKind::Unknown => unreachable!(),
198200
}
199201
let prev = self.type_info.insert(ty, info);

crates/csharp/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,6 +1903,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
19031903
self.type_name(&Type::Id(id));
19041904
}
19051905

1906+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
1907+
_ = (id, name, ty, docs);
1908+
todo!()
1909+
}
1910+
1911+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1912+
_ = (id, name, ty, docs);
1913+
todo!()
1914+
}
1915+
1916+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
1917+
_ = (id, name, docs);
1918+
todo!()
1919+
}
1920+
19061921
fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
19071922
unimplemented!();
19081923
}

crates/csharp/tests/codegen.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ use std::{
88
use wit_component::StringEncoding;
99

1010
macro_rules! codegen_test {
11+
// TODO: implement support for stream, future, and error-context, and then
12+
// remove these lines:
13+
(streams $name:tt $test:tt) => {};
14+
(futures $name:tt $test:tt) => {};
15+
(resources_with_streams $name:tt $test:tt) => {};
16+
(resources_with_futures $name:tt $test:tt) => {};
17+
(error_context $name:tt $test:tt) => {};
18+
1119
($id:ident $name:tt $test:tt) => {
1220
#[test]
1321
fn $id() {

crates/go/src/interface.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
12661266
// no impl since these types are generated as anonymous types
12671267
}
12681268

1269+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
1270+
_ = (id, name, ty, docs);
1271+
todo!()
1272+
}
1273+
1274+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1275+
_ = (id, name, ty, docs);
1276+
todo!()
1277+
}
1278+
1279+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
1280+
_ = (id, name, docs);
1281+
todo!()
1282+
}
1283+
12691284
fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
12701285
todo!("type_builtin")
12711286
}

crates/go/tests/codegen.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ use heck::*;
88
macro_rules! codegen_test {
99
(issue668 $name:tt $test:tt) => {};
1010
(multiversion $name:tt $test:tt) => {};
11+
12+
// TODO: implement support for stream, future, and error-context, and then
13+
// remove these lines:
14+
(streams $name:tt $test:tt) => {};
15+
(futures $name:tt $test:tt) => {};
16+
(resources_with_streams $name:tt $test:tt) => {};
17+
(resources_with_futures $name:tt $test:tt) => {};
18+
(error_context $name:tt $test:tt) => {};
19+
1120
($id:ident $name:tt $test:tt) => {
1221
#[test]
1322
fn $id() {

crates/markdown/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
656656
self.type_alias(id, name, &Type::Id(id), docs);
657657
}
658658

659+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
660+
_ = (id, name, ty, docs);
661+
todo!()
662+
}
663+
664+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
665+
_ = (id, name, ty, docs);
666+
todo!()
667+
}
668+
669+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
670+
_ = (id, name, docs);
671+
todo!()
672+
}
673+
659674
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
660675
self.type_alias(id, name, ty, docs)
661676
}

crates/moonbit/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
14991499
// Not needed
15001500
}
15011501

1502+
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
1503+
_ = (id, name, ty, docs);
1504+
todo!()
1505+
}
1506+
1507+
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
1508+
_ = (id, name, ty, docs);
1509+
todo!()
1510+
}
1511+
1512+
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
1513+
_ = (id, name, docs);
1514+
todo!()
1515+
}
1516+
15021517
fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
15031518
unimplemented!();
15041519
}

crates/moonbit/tests/codegen.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ use std::path::Path;
22
use std::process::Command;
33

44
macro_rules! codegen_test {
5+
// TODO: implement support for stream, future, and error-context, and then
6+
// remove these lines:
7+
(streams $name:tt $test:tt) => {};
8+
(futures $name:tt $test:tt) => {};
9+
(resources_with_streams $name:tt $test:tt) => {};
10+
(resources_with_futures $name:tt $test:tt) => {};
11+
(error_context $name:tt $test:tt) => {};
12+
513
($id:ident $name:tt $test:tt) => {
614
#[test]
715
fn $id() {

crates/rust/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ syn = { workspace = true }
2727
prettyplease = { workspace = true }
2828

2929
[dev-dependencies]
30+
futures = { workspace = true }
3031
wit-bindgen = { path = '../guest-rust' }
3132
wit-bindgen-rt = { path = '../guest-rust/rt' }
3233
test-helpers = { path = '../test-helpers' }

crates/rust/src/interface.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,6 +2694,48 @@ impl<'a> {camel}Borrow<'a>{{
26942694
}
26952695
}
26962696

2697+
fn type_future(&mut self, _id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
2698+
let stream_and_future_support = self.path_to_stream_and_future_support();
2699+
let mode = TypeMode {
2700+
style: TypeOwnershipStyle::Owned,
2701+
lists_borrowed: false,
2702+
lifetime: None,
2703+
};
2704+
self.rustdoc(docs);
2705+
self.push_str(&format!("pub type {}", name.to_upper_camel_case()));
2706+
self.print_generics(mode.lifetime);
2707+
self.push_str(" = ");
2708+
self.push_str(&format!("{stream_and_future_support}::FutureReader<"));
2709+
self.print_optional_ty(ty.as_ref(), mode);
2710+
self.push_str(">");
2711+
self.push_str(";\n");
2712+
}
2713+
2714+
fn type_stream(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
2715+
let stream_and_future_support = self.path_to_stream_and_future_support();
2716+
let mode = TypeMode {
2717+
style: TypeOwnershipStyle::Owned,
2718+
lists_borrowed: false,
2719+
lifetime: None,
2720+
};
2721+
self.rustdoc(docs);
2722+
self.push_str(&format!("pub type {}", name.to_upper_camel_case()));
2723+
self.print_generics(mode.lifetime);
2724+
self.push_str(" = ");
2725+
self.push_str(&format!("{stream_and_future_support}::StreamReader<"));
2726+
self.print_ty(ty, mode);
2727+
self.push_str(">");
2728+
self.push_str(";\n");
2729+
}
2730+
2731+
fn type_error_context(&mut self, _id: TypeId, name: &str, docs: &Docs) {
2732+
let async_support = self.path_to_async_support();
2733+
self.rustdoc(docs);
2734+
self.push_str(&format!("pub type {} = ", name.to_upper_camel_case()));
2735+
self.push_str(&format!("{async_support}::ErrorContext"));
2736+
self.push_str(";\n");
2737+
}
2738+
26972739
fn type_builtin(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
26982740
self.rustdoc(docs);
26992741
self.src
@@ -2784,17 +2826,27 @@ impl<'a, 'b> wit_bindgen_core::AnonymousTypeGenerator<'a> for AnonTypeGenerator<
27842826

27852827
fn anonymous_type_future(&mut self, _id: TypeId, ty: &Option<Type>, _docs: &Docs) {
27862828
let stream_and_future_support = self.interface.path_to_stream_and_future_support();
2829+
let mode = TypeMode {
2830+
style: TypeOwnershipStyle::Owned,
2831+
lists_borrowed: false,
2832+
lifetime: None,
2833+
};
27872834
self.interface
27882835
.push_str(&format!("{stream_and_future_support}::FutureReader<"));
2789-
self.interface.print_optional_ty(ty.as_ref(), self.mode);
2836+
self.interface.print_optional_ty(ty.as_ref(), mode);
27902837
self.interface.push_str(">");
27912838
}
27922839

27932840
fn anonymous_type_stream(&mut self, _id: TypeId, ty: &Type, _docs: &Docs) {
27942841
let stream_and_future_support = self.interface.path_to_stream_and_future_support();
2842+
let mode = TypeMode {
2843+
style: TypeOwnershipStyle::Owned,
2844+
lists_borrowed: false,
2845+
lifetime: None,
2846+
};
27952847
self.interface
27962848
.push_str(&format!("{stream_and_future_support}::StreamReader<"));
2797-
self.interface.print_ty(ty, self.mode);
2849+
self.interface.print_ty(ty, mode);
27982850
self.interface.push_str(">");
27992851
}
28002852

crates/rust/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ impl RustWasm {
441441
self.src.push_str("}\n");
442442
if emitted.contains(&RuntimeItem::StreamAndFutureSupport) {
443443
self.src
444-
.push_str("pub use _rt::stream_and_future_support;\n");
444+
.push_str("#[allow(unused_imports)]\npub use _rt::stream_and_future_support;\n");
445445
}
446446
}
447447

crates/rust/src/stream_and_future_support.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use {
88
std::{
99
collections::hash_map::Entry,
1010
convert::Infallible,
11+
fmt,
1112
future::{Future, IntoFuture},
1213
iter,
1314
marker::PhantomData,
@@ -33,6 +34,14 @@ pub struct FutureWriter<T: FuturePayload> {
3334
_phantom: PhantomData<T>,
3435
}
3536

37+
impl<T: FuturePayload> fmt::Debug for FutureWriter<T> {
38+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39+
f.debug_struct("FutureWriter")
40+
.field("handle", &self.handle)
41+
.finish()
42+
}
43+
}
44+
3645
impl<T: FuturePayload> FutureWriter<T> {
3746
/// Write the specified value to this `future`.
3847
pub async fn write(self, v: T) {
@@ -101,6 +110,14 @@ pub struct FutureReader<T: FuturePayload> {
101110
_phantom: PhantomData<T>,
102111
}
103112

113+
impl<T: FuturePayload> fmt::Debug for FutureReader<T> {
114+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115+
f.debug_struct("FutureReader")
116+
.field("handle", &self.handle)
117+
.finish()
118+
}
119+
}
120+
104121
impl<T: FuturePayload> FutureReader<T> {
105122
#[doc(hidden)]
106123
pub fn from_handle(handle: u32) -> Self {
@@ -219,6 +236,14 @@ pub struct StreamWriter<T: StreamPayload> {
219236
_phantom: PhantomData<T>,
220237
}
221238

239+
impl<T: StreamPayload> fmt::Debug for StreamWriter<T> {
240+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241+
f.debug_struct("StreamWriter")
242+
.field("handle", &self.handle)
243+
.finish()
244+
}
245+
}
246+
222247
impl<T: StreamPayload> Sink<Vec<T>> for StreamWriter<T> {
223248
type Error = Infallible;
224249

@@ -334,6 +359,14 @@ pub struct StreamReader<T: StreamPayload> {
334359
_phantom: PhantomData<T>,
335360
}
336361

362+
impl<T: StreamPayload> fmt::Debug for StreamReader<T> {
363+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364+
f.debug_struct("StreamReader")
365+
.field("handle", &self.handle)
366+
.finish()
367+
}
368+
}
369+
337370
impl<T: StreamPayload> StreamReader<T> {
338371
#[doc(hidden)]
339372
pub fn from_handle(handle: u32) -> Self {

0 commit comments

Comments
 (0)