Skip to content

Rust generator emits conflicting module and struct names for messages with nested types #3547

@BaldDemian

Description

@BaldDemian

Search before asking

  • I had searched in the issues and found no similar issues.

Version

0.16.0

Component(s)

Rust

Minimal reproduce step

FDL:

message foo {
    message Bar {
        string baz = 1;
    }
    Bar bar = 1;
}

Generated Rust code:

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// This file is generated by Apache Fory compiler.

use fory::{Fory, ForyObject};
use std::sync::OnceLock;

pub mod foo {
    use super::*;

    #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
    pub struct Bar {
        #[fory(id = 1)]
        pub baz: String,
    }

    impl Bar {
        pub fn to_bytes(&self) -> Result<Vec<u8>, fory::Error> {
            let fory = detail::get_fory();
            fory.serialize(self)
        }

        pub fn from_bytes(data: &[u8]) -> Result<Bar, fory::Error> {
            let fory = detail::get_fory();
            fory.deserialize(data)
        }
    }
}

#[derive(ForyObject, Debug, Clone, PartialEq, Default)]
pub struct foo {
    #[fory(id = 1)]
    pub bar: foo::Bar,
}

impl foo {
    pub fn to_bytes(&self) -> Result<Vec<u8>, fory::Error> {
        let fory = detail::get_fory();
        fory.serialize(self)
    }

    pub fn from_bytes(data: &[u8]) -> Result<foo, fory::Error> {
        let fory = detail::get_fory();
        fory.deserialize(data)
    }
}

pub fn register_types(fory: &mut Fory) -> Result<(), fory::Error> {
    fory.register_by_namespace::<foo::Bar>("default", "foo.Bar")?;
    fory.register_by_namespace::<foo>("default", "foo")?;
    Ok(())
}

mod detail {
    use super::*;

    pub(super) fn get_fory() -> &'static Fory {
        static FORY: OnceLock<Fory> = OnceLock::new();
        FORY.get_or_init(|| {
            let mut fory = Fory::default()
                .xlang(true)
                .track_ref(true)
                .compatible(true);
            register_types(&mut fory).expect("failed to register fory types");
            fory
        })
    }
}

What did you expect to see?

The generated Rust code should compile.

What did you see instead?

Compiling errors:

    Checking old_rust_escape_check v0.1.0 (/tmp/fory-old-rust-compile-sM2lgt)
error[E0428]: the name `foo` is defined multiple times
  --> src/generated.rs:46:1
   |
23 | pub mod foo {
   | ----------- previous definition of the module `foo` here
...
46 | pub struct foo {
   | ^^^^^^^^^^^^^^ `foo` redefined here
   |
   = note: `foo` must be defined only once in the type namespace of this module

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:46:12
   |
46 | pub struct foo {
   |            ^^^ not a type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:45:22
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                      ^^^^^ not a type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:45:29
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                             ^^^^^ not a type

error[E0574]: expected struct, variant or union type, found module `foo`
  --> src/generated.rs:45:29
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                             ^^^^^ not a struct, variant or union type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:45:36
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                                    ^^^^^^^^^ not a type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:45:47
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                                               ^^^^^^^ not a type

error[E0574]: expected struct, variant or union type, found module `foo`
  --> src/generated.rs:45:47
   |
45 | #[derive(ForyObject, Debug, Clone, PartialEq, Default)]
   |                                               ^^^^^^^ not a struct, variant or union type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:51:6
   |
51 | impl foo {
   |      ^^^ not a type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:57:46
   |
57 |     pub fn from_bytes(data: &[u8]) -> Result<foo, fory::Error> {
   |                                              ^^^ not a type

error[E0573]: expected type, found module `foo`
  --> src/generated.rs:65:34
   |
65 |     fory.register_by_namespace::<foo>("default", "foo")?;
   |                                  ^^^ not a type

warning: type `foo` should have an upper camel case name
  --> src/generated.rs:46:12
   |
46 | pub struct foo {
   |            ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
   |
   = note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default

Some errors have detailed explanations: E0428, E0573, E0574.
For more information about an error, try `rustc --explain E0428`.
warning: `old_rust_escape_check` (lib) generated 1 warning
error: could not compile `old_rust_escape_check` (lib) due to 11 previous errors; 1 warning emitted

Anything Else?

No response

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions