Santiago Medina created THRIFT-6058:
---------------------------------------
Summary: Rust codegen: `list<UnionType>` deserialization generates
shadowed variable and missing Box wrapping
Key: THRIFT-6058
URL: https://issues.apache.org/jira/browse/THRIFT-6058
Project: Thrift
Issue Type: Bug
Reporter: Santiago Medina
The Rust code generator produces incorrect deserialization code for
`list<UnionType>` and `set<UnionType>` fields in structs.
In `t_rs_generator::render_list_sync_read` (line 2016 of `t_rs_generator.cc`),
when the list element type is a union, the generated code looks like this:
```rust
match UnionType::read_from_in_protocol(i_prot) {
Ok(val) => { val.push(val); },
...
}
```
**Bugs:**
1. **Variable shadowing**: The match binding `val` shadows the outer list
variable `val`. As a result, `val.push(val)` attempts to call `.push()` on the
union element (which doesn't exist) instead of the `Vec`.
2. **Missing `Box::new()`**: The list type is `Vec<Box<UnionType>>`, but the
element is not wrapped in `Box::new()` before pushing.
**Correct generated code should be:**
```rust
match UnionType::read_from_in_protocol(i_prot) {
Ok(elem) => { val.push(Box::new(elem)); },
...
}
```
The same issue exists in `render_set_sync_read` (line 2051).
**Note:**
The single-field deserialization path (`render_struct_sync_read`, line 1718)
correctly handles boxing using `is_boxed ? "Box::new(val)" : "val"`, but the
collection paths do not.
**Reproduction:**
Any `.thrift` file containing a struct with a `list<UnionType>` or
`set<UnionType>` field.
**Example:**
```thrift
union MyUnion {
1: i32 int_value
2: string string_value
}
struct MyStruct {
3: optional list<MyUnion> items
}
```
--
This message was sent by Atlassian Jira
(v8.20.10#820010)