Skip to content

Commit 9be80b5

Browse files
authored
fix: support named fixed-length list types in code generation (#1537)
The `define_type` function dispatches to `type_fixed_length_list` on the `InterfaceGenerator` trait for named fixed-length list types like `type my-array = list<u32, 4>`. This makes `type_fixed_length_list` a required trait method (no default) and adds implementations in all backends: - Rust: generates `pub type Name = [T; N];` - Go: generates `type Name = [N]Type` - Markdown: delegates to `type_alias` - Moonbit: no-op (maps to `FixedArray[T]` natively) - C, C++, C#: explicit `todo!()` (not yet supported) Also adds a shared codegen test in `tests/codegen/named-fixed-length-list.wit` with expected failures for backends that don't yet support this.
1 parent d61d370 commit 9be80b5

File tree

14 files changed

+108
-5
lines changed

14 files changed

+108
-5
lines changed

crates/c/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,17 @@ void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
17351735
self.finish_typedef_struct(id);
17361736
}
17371737

1738+
fn type_fixed_length_list(
1739+
&mut self,
1740+
_id: TypeId,
1741+
_name: &str,
1742+
_ty: &Type,
1743+
_size: u32,
1744+
_docs: &Docs,
1745+
) {
1746+
todo!("named fixed-length list types are not yet supported in the C backend")
1747+
}
1748+
17381749
fn type_future(&mut self, id: TypeId, _name: &str, _ty: &Option<Type>, docs: &Docs) {
17391750
self.src.h_defs("\n");
17401751
self.docs(docs, SourceType::HDefs);

crates/core/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub trait InterfaceGenerator<'a> {
165165
fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs);
166166
fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
167167
fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
168+
fn type_fixed_length_list(&mut self, id: TypeId, name: &str, ty: &Type, size: u32, docs: &Docs);
168169
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
169170
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
170171
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
@@ -199,7 +200,9 @@ where
199200
TypeDefKind::Future(t) => generator.type_future(id, name, t, &ty.docs),
200201
TypeDefKind::Stream(t) => generator.type_stream(id, name, t, &ty.docs),
201202
TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
202-
TypeDefKind::FixedLengthList(..) => todo!(),
203+
TypeDefKind::FixedLengthList(t, size) => {
204+
generator.type_fixed_length_list(id, name, t, *size, &ty.docs)
205+
}
203206
TypeDefKind::Map(..) => todo!(),
204207
TypeDefKind::Unknown => unreachable!(),
205208
}

crates/cpp/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,17 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for CppInterfaceGenerator<'a>
22212221
// nothing to do here
22222222
}
22232223

2224+
fn type_fixed_length_list(
2225+
&mut self,
2226+
_id: TypeId,
2227+
_name: &str,
2228+
_ty: &wit_bindgen_core::wit_parser::Type,
2229+
_size: u32,
2230+
_docs: &wit_bindgen_core::wit_parser::Docs,
2231+
) {
2232+
todo!("named fixed-length list types are not yet supported in the C++ backend")
2233+
}
2234+
22242235
fn type_builtin(
22252236
&mut self,
22262237
_id: TypeId,

crates/csharp/src/interface.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,17 @@ impl<'a> CoreInterfaceGenerator<'a> for InterfaceGenerator<'a> {
15441544
self.type_name(&Type::Id(id));
15451545
}
15461546

1547+
fn type_fixed_length_list(
1548+
&mut self,
1549+
_id: TypeId,
1550+
_name: &str,
1551+
_ty: &Type,
1552+
_size: u32,
1553+
_docs: &Docs,
1554+
) {
1555+
todo!("named fixed-length list types are not yet supported in the C# backend")
1556+
}
1557+
15471558
fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
15481559
unimplemented!();
15491560
}

crates/go/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,6 +2874,13 @@ const (
28742874
uwriteln!(self.src, "{docs}type {name} = []{ty}");
28752875
}
28762876

2877+
fn type_fixed_length_list(&mut self, _: TypeId, name: &str, ty: &Type, size: u32, docs: &Docs) {
2878+
let name = name.to_upper_camel_case();
2879+
let ty = self.type_name(self.resolve, *ty);
2880+
let docs = format_docs(docs);
2881+
uwriteln!(self.src, "{docs}type {name} = [{size}]{ty}");
2882+
}
2883+
28772884
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
28782885
_ = (id, name, ty, docs);
28792886
todo!()

crates/markdown/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,17 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
650650
self.type_alias(id, name, &Type::Id(id), docs);
651651
}
652652

653+
fn type_fixed_length_list(
654+
&mut self,
655+
id: TypeId,
656+
name: &str,
657+
_ty: &Type,
658+
_size: u32,
659+
docs: &Docs,
660+
) {
661+
self.type_alias(id, name, &Type::Id(id), docs);
662+
}
663+
653664
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
654665
_ = (id, name, ty, docs);
655666
todo!()

crates/moonbit/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,17 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
13191319
// Not needed. They will become `Array[T]` or `FixedArray[T]` in Moonbit
13201320
}
13211321

1322+
fn type_fixed_length_list(
1323+
&mut self,
1324+
_id: TypeId,
1325+
_name: &str,
1326+
_ty: &Type,
1327+
_size: u32,
1328+
_docs: &Docs,
1329+
) {
1330+
// Not needed. They will become `FixedArray[T]` in Moonbit
1331+
}
1332+
13221333
fn type_future(&mut self, _id: TypeId, _name: &str, _ty: &Option<Type>, _docs: &Docs) {
13231334
unimplemented!() // Not needed
13241335
}

crates/rust/src/interface.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2889,6 +2889,24 @@ impl<'a> {camel}Borrow<'a>{{
28892889
}
28902890
}
28912891

2892+
fn type_fixed_length_list(
2893+
&mut self,
2894+
id: TypeId,
2895+
_name: &str,
2896+
ty: &Type,
2897+
size: u32,
2898+
docs: &Docs,
2899+
) {
2900+
for (name, mode) in self.modes_of(id) {
2901+
self.rustdoc(docs);
2902+
self.push_str(&format!("pub type {name}"));
2903+
self.print_generics(mode.lifetime);
2904+
self.push_str(" = [");
2905+
self.print_ty(ty, mode);
2906+
self.push_str(&format!("; {size}];\n"));
2907+
}
2908+
}
2909+
28922910
fn type_future(&mut self, _id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
28932911
let async_support = self.r#gen.async_support_path();
28942912
let mode = TypeMode {

crates/test/src/c.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ impl LanguageMethods for C {
5252

5353
fn should_fail_verify(
5454
&self,
55-
_name: &str,
55+
name: &str,
5656
config: &crate::config::WitConfig,
5757
_args: &[String],
5858
) -> bool {
59-
config.error_context
59+
config.error_context || name.starts_with("named-fixed-length-list.wit")
6060
}
6161

6262
fn codegen_test_variants(&self) -> &[(&str, &[&str])] {

crates/test/src/cpp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl LanguageMethods for Cpp {
4646
_args: &[String],
4747
) -> bool {
4848
return match name {
49-
"issue1514-6.wit" => true,
49+
"issue1514-6.wit" | "named-fixed-length-list.wit" => true,
5050
_ => false,
5151
} || config.async_;
5252
}

0 commit comments

Comments
 (0)