Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

derived traits are not found by get_trait_impl #6143

Closed
Thunkar opened this issue Sep 24, 2024 · 0 comments · Fixed by #6326
Closed

derived traits are not found by get_trait_impl #6143

Thunkar opened this issue Sep 24, 2024 · 0 comments · Fixed by #6326
Labels
bug Something isn't working

Comments

@Thunkar
Copy link
Contributor

Thunkar commented Sep 24, 2024

Aim

Given:

mod traits; // Serialize, Deserialize and associated derive_via fns
mod meta; // Where "storage" macro lives

mod find_serialize {
    use std::meta::derive;
    use crate::traits::{Serialize, Deserialize};
    use crate::meta::storage;

    #[derive(Serialize, Deserialize, Eq)]
    struct State {
        token0: Field,
        token1: Field,
        liquidity_token: Field,
        reserve0: u64,
        reserve1: u64,
    }

    impl State {
        fn create() -> State {
            State { token0: 0, token1: 1, liquidity_token: 2, reserve0: 3, reserve1: 4 }
        }
    }

    #[storage]
    struct Storage {
        state: State,
    }

    fn main() {
        let state = State::create();
        let serialized = state.serialize();
        let deserialized = State::deserialize(serialized);

        assert(state == deserialized);
    }
}

If I have a storage annotation like this:

use std::meta::typ::fresh_type_variable;

pub comptime fn storage(s: StructDefinition) -> Quoted {
    println("STORAGE");
    let (field_name, stored_type) = s.fields()[0];

    let any = fresh_type_variable();
    let maybe_serialize_impl = stored_type.get_trait_impl(quote { crate::traits::Serialize<$any> }.as_trait_constraint());
    assert(
        maybe_serialize_impl.is_some(), f"Attempted to fetch serialization length, but {stored_type} does not implement the Serialize trait"
    );
    let serialize_impl = maybe_serialize_impl.unwrap();
    let size = serialize_impl.trait_generic_args()[0].as_constant().unwrap();
    // Hoping for 5
    println(f"SERIALIZED_SIZE {size}");
    let name = s.name();
    quote {
        impl $name {
            fn init() -> Self {
                Self {
                    $field_name: $stored_type::create()
                }
            }
        }
    }
}

It should be possible to find the derived Serialize implementation

Expected Behavior

The above should compile

Bug

Fails with

error: Attempted to fetch serialization length, but State does not implement the Serialize trait
┌─ src/meta/mod.nr:10:9

10 │ maybe_serialize_impl.is_some(), f"Attempted to fetch serialization length, but {stored_type} does not implement the Serialize trait"
│ ------------------------------ Assertion failed

= Call stack:
1. src/main.nr:24:7

To Reproduce

Use the above example

Workaround

None

Workaround Description

No response

Additional Context

I've checked is not an order issue, since the derive annotation runs before storage. Also using .implements and then checking the any variable to be bound to the length doesn't work either, fails with the same error.

Project Impact

None

Blocker Context

No response

Nargo Version

No response

NoirJS Version

No response

Proving Backend Tooling & Version

No response

Would you like to submit a PR for this Issue?

None

Support Needs

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: ✅ Done
1 participant