Dushistov / flapigen-rs

Tool for connecting programs or libraries written in Rust with other languages
BSD 3-Clause "New" or "Revised" License
775 stars 59 forks source link

Bug when Vec<T> is used as parameter type and as return type. #435

Closed stephan57160 closed 2 years ago

stephan57160 commented 2 years ago

Initial source files are those found in cpp-example.

I modify libs.rs like below:

impl Foo {
    fn new(val: i32) -> Foo {
        Foo { data: val }
    }

    fn return_array_u8(&self) -> Vec<u8> {
       return vec!(0,1);
    }

    fn param_is_array_u8(&self, arg: Vec<u8>) {
    }
}

Then, in cpp-glue.in.rs, I add the counterpart:

use super::{f2, Foo};

foreign_class!(class Foo {
    self_type Foo;
    constructor Foo::new(_: i32) -> Foo;
    fn Foo::return_array_u8(&self) -> Vec<u8>;
    fn Foo::param_is_array_u8(&self, _: Vec<u8>);
});

Then, after cargo buid, the file rust_vec_u8.h is generated with a duplicate code portion;

#ifdef __cplusplus

#include "rust_vec_impl.hpp"

namespace rust {
using RustVecu8 = RustVec<CRustVecu8, CRustVecu8_free>;
}

#endif

#ifdef __cplusplus

#include "rust_vec_impl.hpp"

namespace rust {
using RustVecu8 = RustVec<CRustVecu8, CRustVecu8_free>;
}

#endif

I noticed that if I have only return_array_u8 or param_is_array_u8, this part is not duplicated. This is possibly why not seen with testing cases.

I tried to figure out why this code is duplicated, but I was not able to.

Dushistov commented 2 years ago

I tried to figure out why this code is duplicated, but I was not able to.

The code "duplication" happens here: https://github.com/Dushistov/flapigen-rs/blob/77af435749954ee1cf63e66e6e48ade3d0bd62a3/macroslib/src/cpp/mod.rs#L518

In this case this harmless, because of duplication of #include "rust_vec_impl.hpp" is ok, because of rust_vec_impl.hpp contains #pragma once, so there is no really duplication. And identical using also ok according to c++ standard.

But for some other rule this may be the problem, so I suppose there is need for cache of TypeMapConvRuleInfo in CppContext to prevent this.

Here should be noted that different rules can cause write to the same file, so you can just check if file exists and has the proper content, there is need per TypeMapConvRuleInfo cache.

stephan57160 commented 2 years ago

so there is no really duplication. And identical using also ok according to c++ standard: Code is duplicated. It's harmless, I agree, but still duplicated :-)

But for some other rule this may be the problem: Well... I'm using flapigen CPP code as a base for another language support attempt... I'm also using similar rules than cpp-include.rs and ... I get the duplicated code, and, at least for this case, it is a problem :-)

I'll have a deeper look. Not sure to be able to fix it via CppContext, though ... But ... let's see.

stephan57160 commented 2 years ago

OK. Seems easy, even for me :-)

stephan57160 commented 2 years ago

OK. I created a new field foreign_code_cache: &Vec<(SmolStr, String)> in CppContext, as it's the easiest way, for me, at the moment. Then, before writing to the FileCache, I check if fcode is already present in this cache or not, then, I write, if not already cached.

Now, working on a small test case...

stephan57160 commented 2 years ago

This issue could be closed, no ?