Skip to content

Commit d71bd1b

Browse files
committed
Fix test structure and model for union serialization unused variable issue
- Remove unused TestInput imports and fix structure references - Perfect test model to only include unit struct member to demonstrate unused variable issue - Ensure tests properly use serializer code to avoid dead code warnings - Update test model structure names to match generated code expectations
1 parent 4cba820 commit d71bd1b

File tree

4 files changed

+75
-62
lines changed

4 files changed

+75
-62
lines changed

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/serialize/JsonSerializerGenerator.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,14 +555,28 @@ class JsonSerializerGenerator(
555555
}
556556
rustBlock("match input") {
557557
for (member in context.shape.members()) {
558+
val memberShape = model.expectShape(member.target)
558559
val variantName =
559560
if (member.isTargetUnit()) {
560561
"${symbolProvider.toMemberName(member)}"
562+
} else if (memberShape.isStructureShape &&
563+
memberShape.asStructureShape().get().allMembers.isEmpty()
564+
) {
565+
// Unit structs don't serialize inner, so it is never accessed
566+
"${symbolProvider.toMemberName(member)}(_inner)"
561567
} else {
562568
"${symbolProvider.toMemberName(member)}(inner)"
563569
}
564570
withBlock("#T::$variantName => {", "},", unionSymbol) {
565-
serializeMember(MemberContext.unionMember(context, "inner", member, jsonName))
571+
val innerRef =
572+
if (memberShape.isStructureShape &&
573+
memberShape.asStructureShape().get().allMembers.isEmpty()
574+
) {
575+
"_inner"
576+
} else {
577+
"inner"
578+
}
579+
serializeMember(MemberContext.unionMember(context, innerRef, member, jsonName))
566580
}
567581
}
568582
if (codegenTarget.renderUnknownVariant()) {

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/serialize/QuerySerializerGenerator.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,18 @@ abstract class QuerySerializerGenerator(private val codegenContext: CodegenConte
371371
"$memberName(inner)"
372372
}
373373
withBlock("#T::$variantName => {", "},", unionSymbol) {
374+
val innerRef =
375+
if (memberShape.isStructureShape &&
376+
memberShape.asStructureShape().get().allMembers.isEmpty()
377+
) {
378+
"_inner"
379+
} else {
380+
"inner"
381+
}
374382
serializeMember(
375383
MemberContext.unionMember(
376384
context.copy(writerExpression = "writer"),
377-
"inner",
385+
innerRef,
378386
member,
379387
),
380388
)

codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/serialize/JsonSerializerGeneratorTest.kt

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,6 @@ import software.amazon.smithy.rust.codegen.core.util.inputShape
3333
import software.amazon.smithy.rust.codegen.core.util.lookup
3434

3535
class JsonSerializerGeneratorTest {
36-
private val unionWithUnitStructModel =
37-
"""
38-
namespace test
39-
use aws.protocols#restJson1
40-
41-
union TestUnion {
42-
unitMember: Unit,
43-
dataMember: String
44-
}
45-
46-
structure Unit {}
47-
48-
@http(uri: "/test", method: "POST")
49-
operation TestOp {
50-
input: TestInput
51-
}
52-
53-
structure TestInput {
54-
union: TestUnion
55-
}
56-
""".asSmithyModel()
57-
5836
private val baseModel =
5937
"""
6038
namespace test
@@ -370,7 +348,8 @@ class JsonSerializerGeneratorTest {
370348
@Test
371349
fun `union with unit struct doesn't cause unused variable warning`() {
372350
// Regression test for https://github.com/smithy-lang/smithy-rs/issues/4308
373-
val model = RecursiveShapeBoxer().transform(OperationNormalizer.transform(unionWithUnitStructModel))
351+
// This test ensures that union serialization with unit structs compiles without unused variable warnings.
352+
val model = RecursiveShapeBoxer().transform(OperationNormalizer.transform(QuerySerializerGeneratorTest.unionWithUnitStructModel))
374353

375354
val codegenContext = testCodegenContext(model)
376355
val symbolProvider = codegenContext.symbolProvider
@@ -398,13 +377,19 @@ class JsonSerializerGeneratorTest {
398377
unitTest(
399378
"json_union_serialization",
400379
"""
401-
use test_model::{TestInput, TestUnion, Unit};
380+
use test_model::{TestUnion, Unit};
381+
382+
// Create a test input to actually use the serializer
383+
let input = crate::test_input::TestOpInput::builder()
384+
.union(TestUnion::UnitMember(Unit::builder().build()))
385+
.build()
386+
.unwrap();
402387
403-
// Generate the serialization function that contains union match arms with (inner)
404-
${format(operationGenerator!!)};
388+
// This will generate and use the serialization code that should not have unused variable warnings
389+
let _serialized = ${format(operationGenerator!!)};
390+
let _result = _serialized(&input);
405391
406-
// Test that the code compiles - this validates our fix works
407-
let _test_passed = true;
392+
// Test that the code compiles and runs - this validates our fix works
408393
""",
409394
)
410395
}

codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/serialize/QuerySerializerGeneratorTest.kt

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,40 @@ import software.amazon.smithy.rust.codegen.core.util.inputShape
2222
import software.amazon.smithy.rust.codegen.core.util.lookup
2323

2424
class QuerySerializerGeneratorTest {
25+
companion object {
26+
val unionWithUnitStructModel =
27+
"""
28+
namespace test
29+
30+
union TestUnion {
31+
unitMember: Unit
32+
}
33+
34+
structure Unit {}
35+
36+
@http(uri: "/test", method: "POST")
37+
operation TestOp {
38+
input: TestInput
39+
}
40+
41+
structure TestInput {
42+
union: TestUnion
43+
}
44+
""".asSmithyModel()
45+
}
46+
2547
@Test
2648
fun `union with unit struct doesn't cause unused variable warning`() {
2749
// Regression test for https://github.com/smithy-lang/smithy-rs/issues/4308
28-
val model =
29-
RecursiveShapeBoxer().transform(
30-
OperationNormalizer.transform(
31-
"""
32-
namespace test
33-
34-
union TestUnion {
35-
unitMember: Unit,
36-
dataMember: String
37-
}
38-
39-
structure Unit {}
40-
41-
@http(uri: "/test", method: "POST")
42-
operation TestOp {
43-
input: TestInput
44-
}
45-
46-
structure TestInput {
47-
union: TestUnion
48-
}
49-
""".asSmithyModel(),
50-
),
51-
)
50+
val model = RecursiveShapeBoxer().transform(OperationNormalizer.transform(unionWithUnitStructModel))
5251

5352
val codegenContext = testCodegenContext(model)
5453
val symbolProvider = codegenContext.symbolProvider
55-
val parserSerializer = AwsQuerySerializerGenerator(codegenContext)
56-
val operationGenerator = parserSerializer.operationInputSerializer(model.lookup("test#TestOp"))
57-
5854
val project = TestWorkspace.testProject(symbolProvider)
5955

56+
val querySerializer = Ec2QuerySerializerGenerator(codegenContext)
57+
val operationGenerator = querySerializer.operationInputSerializer(model.lookup("test#TestOp"))
58+
6059
// Render all necessary structures and unions
6160
model.lookup<StructureShape>("test#Unit").renderWithModelBuilder(model, symbolProvider, project)
6261
model.lookup<OperationShape>("test#TestOp").inputShape(model).renderWithModelBuilder(model, symbolProvider, project)
@@ -68,14 +67,21 @@ class QuerySerializerGeneratorTest {
6867
// Generate the serialization module that will contain the union serialization code
6968
project.lib {
7069
unitTest(
71-
"query_union_serialization",
70+
"test_query_union_serialization",
7271
"""
73-
use test_model::{TestInput, TestUnion, Unit};
72+
use test_model::{TestUnion, Unit};
73+
74+
// Create a test input to actually use the serializer
75+
let input = crate::test_input::TestOpInput::builder()
76+
.union(TestUnion::UnitMember(Unit::builder().build()))
77+
.build()
78+
.unwrap();
7479
75-
// This will generate the serialization code that should not have unused variable warnings
76-
${format(operationGenerator!!)};
80+
// This will generate and use the serialization code that should not have unused variable warnings
81+
let _serialized = ${format(operationGenerator!!)};
82+
let _result = _serialized(&input);
7783
78-
// The test passes if the code compiles without unused variable warnings
84+
// Test that the code compiles and runs - this validates our fix works
7985
""",
8086
)
8187
}

0 commit comments

Comments
 (0)