Sylwester Lachiewicz created THRIFT-6175:
--------------------------------------------

             Summary: Go maps keyed by a struct use pointer identity, so 
decoded keys never match and Equals compares by address
                 Key: THRIFT-6175
                 URL: https://issues.apache.org/jira/browse/THRIFT-6175
             Project: Thrift
          Issue Type: Bug
          Components: Go - Compiler
    Affects Versions: 0.24.0
            Reporter: Sylwester Lachiewicz


The Go generator emits a thrift {{map}} whose key is a struct or exception as 
{{map[*K]V}}. Because the key is a pointer, the map is keyed by address rather 
than by the key's contents:

* Every key read from the wire is a fresh allocation, so a decoded map can 
never be looked up by a value the caller constructs.
* The generated {{Equals}} indexes the other map by pointer, so two identical 
messages decoded separately compare unequal.

Reproduce with:

{code}
struct K { 1: i32 a }
struct S { 1: map<K, string> m }
{code}

{{thrift --gen go}} produces {{M map[*K]string}} and an {{Equals}} that does 
{{other.M[k]}} with the pointer {{k}}. A round-trip through {{TSerializer}} and 
{{TDeserializer}} followed by {{src.Equals(dst)}} returns false.

This is the struct-key half of THRIFT-2063. That ticket's fix represents maps 
with container keys (list, set, map) as {{[]thrift.MapEntry[K, V]}} and leaves 
struct keys alone because changing them alters the Go type of fields that 
compile today.

Proposed change: add a Go generator option {{struct_key_entries}} that routes 
struct and exception keys through the same entry-slice representation, so such 
a field becomes {{[]thrift.MapEntry[*K, V]}} and {{Equals}} compares key 
contents via the key struct's own {{Equals}}. The default output stays 
unchanged; a later major release can flip the default.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to