Path: blob/main/crates/component-macro/tests/codegen.rs
3054 views
#![allow(dead_code, reason = "lots of macro-generated code")]12macro_rules! gentest {3($id:ident $name:tt $path:tt) => {4mod $id {5mod sugar {6wasmtime::component::bindgen!(in $path);7}8mod async_ {9wasmtime::component::bindgen!({10path: $path,11imports: { default: async },12exports: { default: async },13});14}15mod concurrent {16wasmtime::component::bindgen!({17path: $path,18imports: { default: async | store },19exports: { default: async | store },20});21}22mod tracing {23wasmtime::component::bindgen!({24path: $path,25imports: { default: tracing | verbose_tracing },26exports: { default: tracing | verbose_tracing },27ownership: Borrowing {28duplicate_if_necessary: true29}30});31}32mod imports_with_store {33wasmtime::component::bindgen!({34path: $path,35imports: { default: store },36});37}38}39};40}4142component_macro_test_helpers::foreach!(gentest);4344mod with_key_and_resources {45use wasmtime::Result;46use wasmtime::component::Resource;4748wasmtime::component::bindgen!({49inline: "50package demo:pkg;5152interface bar {53resource a;54resource b;55}5657world foo {58resource a;59resource b;6061import foo: interface {62resource a;63resource b;64}6566import bar;67}68",69with: {70"a": MyA,71"b": MyA,72"foo.a": MyA,73"foo.b": MyA,74"demo:pkg/bar.a": MyA,75"demo:pkg/bar.b": MyA,76},77});7879pub struct MyA;8081struct MyComponent;8283impl FooImports for MyComponent {}8485impl HostA for MyComponent {86fn drop(&mut self, _: Resource<MyA>) -> Result<()> {87loop {}88}89}9091impl HostB for MyComponent {92fn drop(&mut self, _: Resource<MyA>) -> Result<()> {93loop {}94}95}9697impl foo::Host for MyComponent {}9899impl foo::HostA for MyComponent {100fn drop(&mut self, _: Resource<MyA>) -> Result<()> {101loop {}102}103}104105impl foo::HostB for MyComponent {106fn drop(&mut self, _: Resource<MyA>) -> Result<()> {107loop {}108}109}110111impl demo::pkg::bar::Host for MyComponent {}112113impl demo::pkg::bar::HostA for MyComponent {114fn drop(&mut self, _: Resource<MyA>) -> Result<()> {115loop {}116}117}118119impl demo::pkg::bar::HostB for MyComponent {120fn drop(&mut self, _: Resource<MyA>) -> Result<()> {121loop {}122}123}124}125126mod trappable_errors_with_versioned_and_unversioned_packages {127wasmtime::component::bindgen!({128world: "foo:foo/nope",129inline: "130package foo:[email protected];131132interface a {133variant error {134other(string),135}136137f: func() -> result<_, error>;138}139140world foo {141import a;142}143",144path: "tests/codegen/unversioned-foo.wit",145trappable_error_type: {146"foo:foo/[email protected]" => MyX,147},148});149150type MyX = u64;151}152153mod trappable_errors {154wasmtime::component::bindgen!({155inline: "156package demo:pkg;157158interface a {159type b = u64;160161z1: func() -> result<_, b>;162z2: func() -> result<_, b>;163}164165interface b {166use a.{b};167z: func() -> result<_, b>;168}169170interface c {171type b = u64;172}173174interface d {175use c.{b};176z: func() -> result<_, b>;177}178179world foo {180import a;181import b;182import d;183}184",185trappable_error_type: {186"demo:pkg/a.b" => MyX,187"demo:pkg/c.b" => MyX,188},189});190191type MyX = u32;192}193194mod interface_name_with_rust_keyword {195wasmtime::component::bindgen!({196inline: "197package foo:foo;198199interface crate { }200201world foo {202export crate;203}204"205});206}207208mod with_works_with_hierarchy {209mod bindings {210wasmtime::component::bindgen!({211inline: "212package foo:foo;213214interface a {215record t {216x: u32,217}218x: func() -> t;219}220221interface b {222use a.{t};223x: func() -> t;224}225226interface c {227use b.{t};228x: func() -> t;229}230231world foo {232import c;233}234"235});236}237238mod with_just_one_interface {239wasmtime::component::bindgen!({240inline: "241package foo:foo;242243interface a {244record t {245x: u32,246}247x: func() -> t;248}249250interface b {251use a.{t};252x: func() -> t;253}254255interface c {256use b.{t};257x: func() -> t;258}259260world foo {261use c.{t};262263import x: func() -> t;264}265",266with: { "foo:foo/a": super::bindings::foo::foo::a }267});268269struct X;270271impl FooImports for X {272fn x(&mut self) -> super::bindings::foo::foo::a::T {273loop {}274}275}276}277278mod with_whole_package {279wasmtime::component::bindgen!({280inline: "281package foo:foo;282283interface a {284record t {285x: u32,286}287x: func() -> t;288}289290interface b {291use a.{t};292x: func() -> t;293}294295interface c {296use b.{t};297x: func() -> t;298}299300world foo {301use c.{t};302303import x: func() -> t;304}305",306with: { "foo:foo": super::bindings::foo::foo }307});308309struct X;310311impl FooImports for X {312fn x(&mut self) -> super::bindings::foo::foo::a::T {313loop {}314}315}316}317318mod with_whole_namespace {319wasmtime::component::bindgen!({320inline: "321package foo:foo;322323interface a {324record t {325x: u32,326}327x: func() -> t;328}329330interface b {331use a.{t};332x: func() -> t;333}334335interface c {336use b.{t};337x: func() -> t;338}339340world foo {341use c.{t};342343import x: func() -> t;344}345",346with: { "foo": super::bindings::foo }347});348349struct X;350351impl FooImports for X {352fn x(&mut self) -> super::bindings::foo::foo::a::T {353loop {}354}355}356}357}358359mod trappable_imports {360mod none {361wasmtime::component::bindgen!({362inline: "363package foo:foo;364365world foo {366import foo: func();367}368",369});370struct X;371372impl FooImports for X {373fn foo(&mut self) {}374}375}376377mod all {378wasmtime::component::bindgen!({379inline: "380package foo:foo;381382world foo {383import foo: func();384}385",386imports: { default: trappable },387});388struct X;389390impl FooImports for X {391fn foo(&mut self) -> wasmtime::Result<()> {392Ok(())393}394}395}396397mod some {398wasmtime::component::bindgen!({399inline: "400package foo:foo;401402world foo {403import foo: func();404import bar: func();405}406",407imports: { "foo": trappable },408});409struct X;410411impl FooImports for X {412fn foo(&mut self) -> wasmtime::Result<()> {413Ok(())414}415fn bar(&mut self) {}416}417}418419mod across_interfaces {420use wasmtime::component::Resource;421422wasmtime::component::bindgen!({423inline: "424package foo:foo;425426interface a {427foo: func();428bar: func();429430resource r {431constructor();432foo: func();433bar: static func();434}435}436437world foo {438import a;439import foo: func();440import bar: func();441import i: interface {442foo: func();443bar: func();444}445446}447",448imports: {449"foo": trappable | exact,450"i.foo": trappable,451"foo:foo/a.foo": trappable,452},453with: { "foo:foo/a.r": R },454});455456struct X;457pub struct R;458459impl FooImports for X {460fn foo(&mut self) -> wasmtime::Result<()> {461Ok(())462}463fn bar(&mut self) {}464}465466impl i::Host for X {467fn foo(&mut self) -> wasmtime::Result<()> {468Ok(())469}470fn bar(&mut self) {}471}472473impl foo::foo::a::Host for X {474fn foo(&mut self) -> wasmtime::Result<()> {475Ok(())476}477fn bar(&mut self) {}478}479480impl foo::foo::a::HostR for X {481fn new(&mut self) -> Resource<R> {482loop {}483}484fn foo(&mut self, _: Resource<R>) {}485fn bar(&mut self) {}486fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {487Ok(())488}489}490}491492mod resources {493use wasmtime::component::Resource;494495wasmtime::component::bindgen!({496inline: "497package foo:foo;498499interface a {500resource r {501constructor();502foo: func();503bar: static func();504}505}506507world foo {508import a;509510}511",512imports: {513"foo:foo/a.[constructor]r": trappable,514"foo:foo/a.[method]r.foo": trappable,515"foo:foo/a.[static]r.bar": trappable,516},517with: { "foo:foo/a.r": R },518});519520struct X;521pub struct R;522523impl foo::foo::a::Host for X {}524525impl foo::foo::a::HostR for X {526fn new(&mut self) -> wasmtime::Result<Resource<R>> {527loop {}528}529fn foo(&mut self, _: Resource<R>) -> wasmtime::Result<()> {530Ok(())531}532fn bar(&mut self) -> wasmtime::Result<()> {533Ok(())534}535fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {536Ok(())537}538}539}540}541542mod custom_derives {543use std::collections::{HashSet, hash_map::RandomState};544545wasmtime::component::bindgen!({546inline: "547package my:inline;548549interface blah {550variant abc {551a,552b,553c554}555556record foo {557field1: string,558field2: list<u32>,559field3: abc560}561562bar: func(cool: foo);563}564565world baz {566import blah;567}568",569// Clone is included by default almost everywhere, so include it here to make sure it570// doesn't conflict571additional_derives: [serde::Serialize, serde::Deserialize, Hash, Clone, PartialEq, Eq],572});573574use my::inline::blah::{Abc, Foo, Host};575576struct X;577578impl Host for X {579fn bar(&mut self, cool: Foo) {580// Check that built in derives that I've added actually work by seeing that this hashes581let _blah: HashSet<Foo, RandomState> = HashSet::from_iter([Foo {582field1: "hello".to_string(),583field2: vec![1, 2, 3],584field3: Abc::B,585}]);586587// Check that the attributes from an external crate actually work. If they don't work,588// compilation will fail here589let _ = serde_json::to_string(&cool);590}591}592}593594mod with_and_mixing_async {595mod with_async {596wasmtime::component::bindgen!({597inline: "598package my:inline;599interface foo {600type t = u32;601foo: func() -> t;602}603interface bar {604use foo.{t};605bar: func() -> t;606}607world x {608import bar;609}610",611imports: {612"my:inline/bar.bar": async,613},614});615}616617mod without_async {618wasmtime::component::bindgen!({619inline: "620package my:inline;621interface foo {622type t = u32;623foo: func() -> t;624}625interface bar {626use foo.{t};627bar: func() -> t;628}629world x {630import bar;631}632",633with: {634"my:inline/foo": super::with_async::my::inline::foo,635},636require_store_data_send: true,637});638}639640mod third {641wasmtime::component::bindgen!({642inline: "643package my:inline;644interface foo {645type t = u32;646foo: func() -> t;647}648interface bar {649use foo.{t};650bar: func() -> t;651}652interface baz {653use bar.{t};654baz: func() -> t;655}656world x {657import baz;658}659",660with: {661"my:inline/foo": super::with_async::my::inline::foo,662"my:inline/bar": super::without_async::my::inline::bar,663},664require_store_data_send: true,665});666}667}668669mod trappable_error_type_and_versions {670struct MyError;671672mod package_no_version_path_no_version {673wasmtime::component::bindgen!({674inline: "675package my:inline;676interface i {677enum e { a, b, c }678}679world foo {}680",681trappable_error_type: {682"my:inline/i.e" => super::MyError,683},684});685}686mod package_version_path_no_version {687wasmtime::component::bindgen!({688inline: "689package my:[email protected];690interface i {691enum e { a, b, c }692}693world foo {}694",695trappable_error_type: {696"my:inline/i.e" => super::MyError,697},698});699}700mod package_version_path_version {701wasmtime::component::bindgen!({702inline: "703package my:[email protected];704interface i {705enum e { a, b, c }706}707world foo {}708",709trappable_error_type: {710"my:inline/[email protected]" => super::MyError,711},712});713}714}715716mod paths {717mod multiple_paths {718wasmtime::component::bindgen!({719world: "test:paths/test",720inline: r#"721package test:paths;722world test {723import paths:path1/test;724export paths:path2/test;725}726"#,727path: ["tests/codegen/path1", "tests/codegen/path2"],728});729}730}731732mod import_async_interface {733pub mod async_interface_implementation {734wasmtime::component::bindgen!({735world: "test:async-import/blah-impl",736inline: r#"737package test:async-import;738739interface blah {740foo: func();741}742743world blah-impl {744import blah;745}746747world bar {748import blah;749}750"#,751imports: { default: async },752});753754use test::async_import::blah::Host;755struct X;756757impl Host for X {758async fn foo(&mut self) {}759}760}761762mod require_t_send {763wasmtime::component::bindgen!({764world: "test:async-import/bar",765inline: r#"766package test:async-import;767768interface blah {769foo: func();770}771772world blah-impl {773import blah;774}775776world bar {777import blah;778}779"#,780with: {781"test:async-import/blah": super::async_interface_implementation::test::async_import::blah,782},783imports: { default: async },784});785}786}787788789