How to create a value using a bound type using a regular struct constructor?

I am trying to create a macro that initializes a struct Tusing P::Childfrom struct Pwhere P: Parent<Child = T>.

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

This macro passes the props in the form of a card, which is passed to the constructor of this constructor. Expanded, it will 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);
}

When compiling, this has an 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 created a macro to initialize the structure in a similar way, but I cannot do this with related types. I think that the compiler for some reason does not support it. However, I want to create a macro with such an API.

How can I approach this problem?

Playground Link

+4
source share
2 answers

Same:

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

, , .

+6

, .

, Child: K K, , (::new ..), .

, , T , Child.

-1

Source: https://habr.com/ru/post/1695240/


All Articles