Flavien Raynaud created THRIFT-4617:
---------------------------------------

             Summary: Avoid generating conflicting struct names in Rust code
                 Key: THRIFT-4617
                 URL: https://issues.apache.org/jira/browse/THRIFT-4617
             Project: Thrift
          Issue Type: Bug
          Components: Rust - Compiler
            Reporter: Flavien Raynaud


If a thrift definition file contains multiple services, with functions having 
the same name, the generated code is not valid. There are conflicting 
definitions of {{*Args}} and {{*Result}} structs.
{noformat}
service backend {
  i32 send(
    1: i32 arg
  );
}

service other_backend {
  string send(
    1: i32 arg
  )
}
{noformat}

Will generate the following code in the same file (I only pasted the 
interesting bits):
{noformat}
struct SendResult {
  result_value: Option<i32>,
}
// ...
struct SendResult {
  result_value: Option<String>,
}
{noformat}

And rustc would complain with errors like:
{noformat}
error[E0428]: the name `SendResult` is defined multiple times
   --> src/test.rs:496:1
    |
234 | struct SendResult {
    | ----------------- previous definition of the type `SendResult` here
...
496 | struct SendResult {
    | ^^^^^^^^^^^^^^^^^ `SendResult` redefined here
    |
    = note: `SendResult` must be defined only once in the type namespace of 
this module
{noformat}

----

Another (very similar) issue occurs if a user-defined struct happens to be 
called (keeping the same example as before) {{SendResult}}:
{noformat}
struct SendResult {
    1: i32 resultCode,
    2: optional string errorCause,
}

service backend {
  SendResult send(
    1: i32 arg
  );
}
{noformat}

Will generate the following code in the same file (I only pasted the 
interesting bits)::
{noformat}
pub struct SendResult {
  pub result_code: Option<i32>,
  pub error_cause: Option<String>,
}
// ...
struct SendResult {
  result_value: Option<SendResult>,
}
{noformat}

Again, conflicting definitions of structs and rustc would complain.

----

The approach taken by the Go generator (I haven't looked at other languages too 
much, some other generators probably do the same) for generating internal 
structs related to a service call is to [prepend the service 
name|https://github.com/apache/thrift/blob/master/compiler/cpp/src/thrift/generate/t_go_generator.cc#L502]
 to each of the structs.
 Using the same mechanism would solve both the issues cited above.

I will give it a try and open a PR, but am also definitely open to any feedback 
on the idea :)



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to