pepsighan
pepsighan

Reputation: 908

How to create a value with an associated type using a normal struct constructor?

I am trying to create a macro which initializes a struct T using P::Child from struct P where P: Parent<Child = T>.

macro_rules! init {
    ($t:tt, { $( $k:ident =>  $v:expr ),* }) => {
        <$t as Parent>::Child {
            $( $k: $v ),*
        }
    };
}

This macro passes the props as a map which is passed onto the struct's given constructor. Expanded, it would look like this:

#[derive(Debug)]
struct Apple {
    a: i32
}

trait Parent {
    type Child;
}

struct Mango;

impl Parent for Mango {
    type Child = Apple;
}

fn main() {
    let a = <Mango as Parent>::Child {
        a: 4
    };
    println!("{:?}", a);
}

Compiling this has the error:

error: expected one of `.`, `::`, `;`, `?`, or an operator, found `{`
  --> src/main.rs:25:38
   |
25 |     let a = <Mango as Parent>::Child {
   |                                      ^ expected one of `.`, `::`, `;`, `?`, or an operator here

I have created a macro to initialize a struct in a similar way but I am not able to do it with associated types. I think the compiler does not support it for some reason. Even so, I want to create a macro with such an API.

How could I approach this problem?

Link to Playground

Upvotes: 4

Views: 362

Answers (2)

tafia
tafia

Reputation: 1562

I don't think it is possible to initialize an associated type.

What you could do is perhaps have the Child: K with K being a trait having some known constructor (::new etc ...), Then call that constructor instead.

Alternatively you can probably initialize a T directly instead of Child.

Upvotes: -1

DK.
DK.

Reputation: 59005

Like so:

macro_rules! init {
    ($t:ty, { $( $k:ident =>  $v:expr ),* }) => {
        {
            type T = <$t as Parent>::Child;
            T {
                $( $k: $v ),*
            }
        }
    };
}

My assumption would be that this is a limitation of the parser, not of the compiler's type analysis.

Upvotes: 6

Related Questions