Skip to content

Commit a74f597

Browse files
authored
Fix single-element tuple generation in WIT bindings (#402)
* Fix single-element tuple generation in WIT bindings Single-element tuples in Rust require a trailing comma to distinguish them from parentheses used for grouping. The generator was producing (String) instead of (String,) for single-element tuples, causing compilation errors. This fix adds logic to append a comma when generating single-element tuples in the TypeDefKind::Tuple case. * Simplify tuple generation logic per reviewer feedback
1 parent 230310c commit a74f597

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

src/generator.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,9 @@ impl<'a> UnimplementedFunction<'a> {
376376
}
377377
TypeDefKind::Tuple(t) => {
378378
source.push('(');
379-
for (i, ty) in t.types.iter().enumerate() {
380-
if i > 0 {
381-
source.push_str(", ");
382-
}
379+
for ty in t.types.iter() {
383380
self.print_type(ty, trie, source)?;
381+
source.push_str(", ");
384382
}
385383
source.push(')');
386384
}

tests/new.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,59 @@ fn it_supports_the_proxy_option() -> Result<()> {
305305

306306
Ok(())
307307
}
308+
309+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
310+
async fn test_single_element_tuple_generation() -> Result<()> {
311+
let (server, config, _task) = spawn_server(["test"]).await?;
312+
313+
publish_wit(
314+
config,
315+
"test:tuples",
316+
"1.0.0",
317+
r#"package test:tuples@1.0.0;
318+
319+
world test-world {
320+
export test-interface: interface {
321+
test-function: func(params: tuple<string>) -> result<tuple<u32>, string>;
322+
another-function: func(single: tuple<bool>) -> tuple<list<string>>;
323+
}
324+
}
325+
"#,
326+
)
327+
.await?;
328+
329+
let project = server.project("test-tuple", true, ["--target", "test:tuples@1.0.0"])?;
330+
331+
project
332+
.cargo_component(["build"])
333+
.assert()
334+
.stderr(contains(
335+
"Finished `dev` profile [unoptimized + debuginfo] target(s)",
336+
))
337+
.success();
338+
339+
let lib_rs = fs::read_to_string(project.root().join("src/lib.rs"))?;
340+
341+
assert!(
342+
lib_rs.contains("params: (String,)"),
343+
"Single-element tuple parameter should have trailing comma. Generated code:\n{}",
344+
lib_rs
345+
);
346+
assert!(
347+
lib_rs.contains("Result<(u32,), String>") || lib_rs.contains("-> (u32,)"),
348+
"Single-element tuple return should have trailing comma. Generated code:\n{}",
349+
lib_rs
350+
);
351+
assert!(
352+
lib_rs.contains("single: (bool,)"),
353+
"Single-element tuple parameter should have trailing comma. Generated code:\n{}",
354+
lib_rs
355+
);
356+
assert!(
357+
lib_rs.contains("-> (Vec<String>,)"),
358+
"Single-element tuple return should have trailing comma. Generated code:\n{}",
359+
lib_rs
360+
);
361+
362+
Ok(())
363+
}

0 commit comments

Comments
 (0)