dojo icon indicating copy to clipboard operation
dojo copied to clipboard

[BUG] derive Introspect doesn't work in embedded generics

Open zsluedem opened this issue 2 years ago • 3 comments

Describe the bug A clear and concise description of what the bug is. derive Introspect doesn't work in embedded generics

To Reproduce Steps to reproduce the behavior:

#[derive(Introspect, Serde, Copy, Drop)]
struct A<T>{
    a: T,
    b: u64
}

#[derive(Introspect, Serde, Copy, Drop)]
struct B<T>{
    a: A<T>,
    b: u64
}

failed with

error: Variable not dropped.
 --> gg.cairo[impls]:8:16
            c: core::serde::Serde::deserialize(ref serialized)?,
               ^**********************************************^
note: the variable needs to be dropped due to the divergence here:
  --> gg.cairo[impls]:9:16
            d: core::serde::Serde::deserialize(ref serialized)?,
               ^**********************************************^
note: Trait has no implementation in context: core::traits::Drop::<kingdom_lord::gg::A::<T>>
note: Trait has no implementation in context: core::traits::Destruct::<kingdom_lord::gg::A::<T>>

error: Variable not dropped.
 -->gg.cairo[impls]:8:16
            c: core::serde::Serde::deserialize(ref serialized)?,
               ^**********************************************^
note: the variable needs to be dropped due to the potential panic here:
  -->gg.cairo[impls]:9:16
            d: core::serde::Serde::deserialize(ref serialized)?,
               ^*********************************************^
note: Trait has no implementation in context: core::traits::Drop::<kingdom_lord::gg::A::<T>>
note: Trait has no implementation in context: core::traits::Destruct::<kingdom_lord::gg::A::<T>>
note: Trait has no implementation in context: core::traits::PanicDestruct::<kingdom_lord::gg::A::<T>>

Expected behavior Build should work,

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

zsluedem avatar Feb 26 '24 14:02 zsluedem

Hi @zsluedem !

Thanks for the bug report !

After some investigations, this is not a Dojo bug but a strange behaviour in Cairo. I tried to compile the following Cairo code outside Dojo and I get the same error:

#[derive(Serde, Copy, Drop)]
struct A<T> {
    a: T,
}

#[derive(Serde, Copy, Drop)]
struct B<T> {
    a: A<T>,
    b: u8
}

But, if I move the a field of struct B at the end of the struct, it compiles properly.

On a same idea, this code does not compile:

#[derive(Serde, Copy, Drop)]
struct A<T> {
    a: T,
}

#[derive(Serde, Copy, Drop)]
struct C<T> {
    c: T,
}

#[derive(Serde, Copy, Drop)]
struct B<T> {
    b: u8
    a: A<T>,
    c: C<T>
}

I continue the investigation to know if it's a known limitation, a bug to fix or if there is a specific syntax for these cases.

@tarrencev could you assign this issue to me please ?

remybar avatar Mar 10 '24 03:03 remybar

After some investigations, here is the solution: your struct A must implement the Destruct trait as follow:

#[derive(Serde, Copy, Drop, Introspect, Destruct)]
struct A<T> {
    a: T
}

#[derive(Serde, Copy, Drop, Introspect)]
struct B<T> {
    a: A<T>,
    b: u8
}

It also works for the example with the struct C but this struct C has also to implement the Destruct trait.

Tested with the spawn-and-move example and it compiles !

remybar avatar Mar 10 '24 08:03 remybar

#[derive(Introspect, Serde, Copy, Drop)] struct A<T>{ a: T, b: u64 }

#[derive(Introspect, Serde, Copy, Drop)] struct B<T>{ a: A<T>, b: u64 }

I thought derive Drop would also implement Destruct. Interesting solution.

zsluedem avatar Mar 13 '24 07:03 zsluedem