rustmetaprogrammingtraitsrust-compiler-plugin

How can I get original AST by trait identifier with syntax extensions?


I've gotten stuck, when I tried to implement traits programmatically using syntax extensions.

I wrote a minimal example here. I hope someone can help (or point me in the right direction).

// Just some methods collection I want to implement programmatically.
trait TraitToHack {
    fn implement_me(&self) -> int; // Say, I'd like to implement this method programmatically to return 42.
}

// I create dummy struct and wrap it with special attribute.
#[AttributeToHack(TraitToHack)]
struct StructToHack;

// I register syntax extension based on Decorator. Its signature is something like this:
// fn expand(cx: &mut ext::base::ExtCtxt, span: codemap::Span, mitem: &ast::MetaItem, item: &ast::Item, push: |P<ast::Item>|) { .. }
// This is where I got stuck :(    
fn main() {
    let hack = StructToHack;
    hack.implement_me(); // Must return 42.
}

The questions are:


Solution

  • You can't.

    Syntax extensions like macros and attributes are expanded prior to name resolution. This means that whilst you could get the identifier TraitToHack, you wouldn't be able to extract any information about the trait from it.

    The next best thing is to implement an attribute specifically for the trait, which has a hard-coded understanding of said trait (i.e. because the attribute is for TraitToHack, it knows it has to implement implement_me). This is more or less how deriving works: there's a separate expansion function for each supported trait.