In fact pretty crazy things already seem to work:
#![feature(decl_macro)]
fn main() {
foo::Foo.poke();
}
mod foo {
super::def_struct!( Foo );
}
macro def_struct( $name:ident ) {
struct Foo;
impl Foo { fn msg( &self ) -> &str { "yo!" } }
pub struct $name;
add_poke!( $name, Foo.msg() );
}
use m::add_poke;
mod m {
pub fn show( msg : &str ) {
println!( "{}", msg );
}
pub macro add_poke( $t:ty, $msg:expr ) {
impl super::Pokeable for $t {
fn poke( &self ) {
show( $msg );
}
}
}
}
trait Pokeable {
fn poke( &self );
}
Notice the struct $name in def_struct (where $name is Foo) injects a definition into the caller, while the struct Foo in the same macro is invisible and does not conflict with it, yet the latter can be used in an expr passed to another macro that implements a trait for the first struct. Holy cow, and this works right now.
The same hygienic magic (I presume) that’s keeping Foo from conflicting with Foo can also have some unfortunate results though, such as when I tried to access a field of a struct created by a macro:
5 | foo::X.child.poke();
| ^^^^^ did you mean `child`?
I also noticed that m::show has to be public currently. I can imagine why, but I hope that requirement will go away eventually.