Skip to content
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
9 changes: 9 additions & 0 deletions crates/guest-rust/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ impl Parse for Config {
Opt::EnableMethodChaining(enable) => {
opts.enable_method_chaining = enable.value();
}
Opt::MergeStructurallyEqualTypes(enable) => {
opts.merge_structurally_equal_types = Some(Some(enable.value()))
}
}
}
} else {
Expand Down Expand Up @@ -322,6 +325,7 @@ mod kw {
syn::custom_keyword!(imports);
syn::custom_keyword!(debug);
syn::custom_keyword!(enable_method_chaining);
syn::custom_keyword!(merge_structurally_equal_types);
}

#[derive(Clone)]
Expand Down Expand Up @@ -403,6 +407,7 @@ enum Opt {
Async(AsyncFilterSet, Span),
Debug(syn::LitBool),
EnableMethodChaining(syn::LitBool),
MergeStructurallyEqualTypes(syn::LitBool),
}

impl Parse for Opt {
Expand Down Expand Up @@ -586,6 +591,10 @@ impl Parse for Opt {
}
Ok(Opt::Async(set, span))
}
} else if l.peek(kw::merge_structurally_equal_types) {
input.parse::<kw::merge_structurally_equal_types>()?;
input.parse::<Token![:]>()?;
Ok(Opt::MergeStructurallyEqualTypes(input.parse()?))
} else {
Err(l.error())
}
Expand Down
9 changes: 9 additions & 0 deletions crates/guest-rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,15 @@ extern crate std;
/// // returning `-> &Self`, to permit method chaining (e.g. for builder).
/// // This expectation is also imposed on exports.
/// enable_method_chaining: true,
///
/// // Find all structurally equal types and only generate one type
/// // definition for each equivalence class.
/// //
/// // Other types in the same class will be type aliases to the generated
/// // type. This avoids clone when converting between types that are
/// // structurally equal, which is useful when import and export the same
/// // interface.
/// merge_structurally_equal_types: true,
/// });
/// ```
///
Expand Down
66 changes: 66 additions & 0 deletions crates/rust/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,69 @@ mod method_chaining {
enable_method_chaining: true
});
}

#[allow(unused, reason = "testing codegen, not functionality")]
mod merge_structurally_equal_types {
wit_bindgen::generate!({
inline: r#"
package test:merge-structurally-equal-types;

interface blag {
variant kind1 { a, b(u64), c }
variant kind2 { a, b(u64), c }
record kind3 { a: input-stream }
record kind4 { a: input-stream }
record tree { l: t1, r: t1 }
record t1 { l: t2, r: t2 }
record t2 { l: t3, r: t3 }
record t3 { l: kind1, r: kind2 }
record t-stream { tree: tree, %stream: option<borrow<input-stream>> }
resource input-stream {
read: func(len: u64) -> list<u8>;
}
f: func(x: kind1) -> kind2;
g: func(x: kind3) -> kind4;
h: func(x: t-stream) -> tree;
}

interface blah {
use blag.{input-stream, kind4, t-stream};
variant kind5 { a, b(u64), c }
variant kind6 { a, c, b(u64) }
record kind7 { a: borrow<input-stream> }
record tt { l: t2, r: t2 }
record t1 { l: t3, r: t3 }
record t2 { l: t1, r: t1 }
record t3 { l: kind5, r: kind5 }
variant custom-result { ok(tt), err }
f: func(x: kind6) -> kind5;
g: func(x: kind7) -> kind4;
h: func(x: t-stream) -> custom-result;

record r1 { a: u8 }
type a1 = u8;
record r2 { a: a1 }
alias-type: func(x: r1) -> r2;
}

interface resources {
resource r1;
type r2 = r1;

record t1 { a: r1 }
record t2 { a: r2 }
alias-own: func(x: t1) -> t2;
alias-aggregate: func(x: option<t1>) -> option<t2>;
}

world proxy {
import blag;
export blag;
import blah;
export blah;
}
"#,
generate_all,
merge_structurally_equal_types: true
});
}
Loading