Danaozhong / rust-zserio

zserio serialization protocol bindings for rust.
https://zserio.org/
Other
3 stars 0 forks source link

compilation errors with current NDS.Live #118

Closed wichert closed 1 month ago

wichert commented 1 month ago

Using a function call for a parameterized type results in code that does not compile. This is a minimal example:

struct ParametrizedChild(bit:5 numIndexBits) { };

struct Parent {
    ParametrizedChild(numVertices()) children[6];

  function varsize numVertices()
  {
    return 1;
  }
}

Which results in:

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> tests/reference-module-lib/src/reference_modules/parameter_passing/function_parameter/parent.rs:26:38
   |
25 |         for element in &mut self.children {
   |                        ------------------
   |                        |
   |                        mutable borrow occurs here
   |                        mutable borrow later used here
26 |             element.num_index_bits = self.num_vertices().clone() as u64;
   |                                      ^^^^ immutable borrow occurs here

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> tests/reference-module-lib/src/reference_modules/parameter_passing/function_parameter/parent.rs:47:38
   |
46 |         for element in &mut self.children {
   |                        ------------------
   |                        |
   |                        mutable borrow occurs here
   |                        mutable borrow later used here
47 |             element.num_index_bits = self.num_vertices().clone() as u64;
   |                                      ^^^^ immutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `reference-module-lib` (lib) due to 2 previous errors
wichert commented 1 month ago

The generated code looks like this:

self.children = vec![Default::default(); children_array_length];                                                 
for element in &mut self.children {                                                                              
    element.num_index_bits = self.num_vertices().clone() as u64;                                                 
}                                                                                                                

The best fix here is probably to do something like this:

self.children = vec![
    ParametrizedChild{
        num_index_bits: self.num_vertices().clone() as u64,
        ..Default::default()
    }; children_array_length];                                                 
wichert commented 1 month ago

That solution will fail for cases where @index operator is used, such as in this test:

struct IndexTest
{
    uint16                  numBlocks;
    BlockHeader             headers[numBlocks];
    Block(headers[@index])  blocks[numBlocks];
};
wichert commented 1 month ago

fixed with #119