Creating impl items using rustc plugins


#1

Hello,

A library that I’m working on interfaces quite a bit with a C-style ABI standard which stores function pointers which basically act as methods, so they would be something like this:

#[my_plugin]
#[repr(C)]
struct Foo {
    some: Data,
    funct: extern "C" fn(self_: *mut Foo, bar: Bar),
   /** more functions, etc **/
}

and to save time (and cut down on typos), I am trying to make a plug-in that would expand the code above to something like this:

#[repr(C)]
struct Foo {
    some: Data,
    funct: extern "C" fn(self_: *mut Foo, bar: Bar),
    /** more functions, etc **/
}

impl Foo {
    fn funct(&mut self, bar: Bar) {
        /** boiler-plate, etc **/

        (self.funct)(self, bar)
    }

    /** more generated functions **/
}

I’ve already created a chunk of the plug-in, including getting the name of the function and the declaration information from the struct. As I understand I can add an item by passing an ImplItem(P<ImplItem>) to the &mut FnOnce<Annotatable> that is passed into my plug-in. However, I’m not sure how to create the ImplItem. There seems to be some things in syntax::ext::deriving::generic that will do this for traits (ex. from servo) , but I’ve found nothing for similar for impl. I also found the quote_*! macros, but I’m not sure how to use them here.

Any suggestions?


#2

The ExtCtxt implements AstBuilder, so you can use all the methods from there to build up an AST node. The deriving stuff is trait-specific and unnecessary here

Otherwise,

quote_item!(cx, impl $struct_name {
fn $funct(...) {
...
}
})

should work if $struct_name and $funct are local Ident variables holding the names of the function and struct.

Also, you want to pass an Item to the annotatable, specifically an ItemImpl. An ImplItem is for a single method, an ItemImpl is the entire impl.


#3

Docopt does this, and indeed, quote_item is the way to go. :slight_smile: https://github.com/docopt/docopt.rs/blob/master/docopt_macros/src/macro.rs#L70