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:
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.