hobofan / ambassador

Delegation of trait implementations via procedural macros
Apache License 2.0
251 stars 13 forks source link

Undocumented need for trait definition before struct/enum if inside same module file? #25

Closed jbuckmccready closed 3 months ago

jbuckmccready commented 3 years ago

Relates to https://github.com/hobofan/ambassador/issues/19, it seems the order of definitions matter if inside the same module file?

some_mod.rs

use ambassador::{delegatable_trait, Delegate};

#[derive(Delegate)]
#[delegate(Shout)]
pub enum Animal {
    Cat(Cat),
    Dog(Dog),
}

#[delegatable_trait]
pub trait Shout {
    fn shout(&self, input: &str) -> String;
}
pub struct Cat;
pub struct Dog;

impl Shout for Cat {
    fn shout(&self, input: &str) -> String {
        format!("{} - meow!", input)
    }
}

impl Shout for Dog {
    fn shout(&self, input: &str) -> String {
        format!("{} - wuff!", input)
    }
}

main.rs

mod some_mod;
use some_mod::*;
pub fn main() {
    let foo_animal = Animal::Cat(Cat);
    println!("{}", foo_animal.shout("BAR"));
}

The above minimal example fails to compile and I couldn't figure out how to get it to work using #[macro_use], I fixed it by placing the trait definition above the enum definition in some_mod.rs. So the following does compile:

some_mod.rs

use ambassador::{delegatable_trait, Delegate};

#[delegatable_trait]
pub trait Shout {
    fn shout(&self, input: &str) -> String;
}

#[derive(Delegate)]
#[delegate(Shout)]
pub enum Animal {
    Cat(Cat),
    Dog(Dog),
}

pub struct Cat;
pub struct Dog;

impl Shout for Cat {
    fn shout(&self, input: &str) -> String {
        format!("{} - meow!", input)
    }
}

impl Shout for Dog {
    fn shout(&self, input: &str) -> String {
        format!("{} - wuff!", input)
    }
}
dewert99 commented 3 months ago

Sorry this took so long, but this is fixed in version 0.4.0 by #60