Fixing proc_macro example

  1. Sample code:
#![crate_type = "proc-macro"]
#![feature(extern_crate_item_prelude)]
extern crate proc_macro;
extern crate syn;

#[macro_use]
extern crate quote;
use proc_macro::TokenStream;
#[proc_macro_derive(TypeName)]



pub fn type_name(input: TokenStream) -> TokenStream {
    let ast = syn::parse(input).unwrap();
    impl_typename(&ast).into()
}

fn impl_typename(ast: &syn::DeriveInput) -> quote::Tokens {
    let name = &ast.ident;
    quote! {
      impl TypeName for #name {
        fn typename() -> String {
          stringify!(#name).to_string()
        }
      }
    }
}


  1. The above code is from a Rust book I am reading. I am not familiar with procedural macros, and am not sure if (1) I'm doing something wrong or (2) if the code is outdated. Either way, pointing out what's wrong with the code / how to fix it would be helpful.

  2. I am familiar with Rust macro-rules. I am also familiar with Lisp style macros, so the quote! looks like lisp 'quasi-quote' and the # looks like Lisp unquote.

TO be clear: I don't have any questions about the concept of macros -- i.e. AST -> AST transforms.

It's the "low level mechanics" of getting the macro to compile that I am confused about.

Try this

/* in Cargo.toml

[lib]
proc-macro = true

[dependencies]
syn = '0.15.26'
quote = '0.6.11'

 */

extern crate proc_macro;
extern crate syn;

#[macro_use]
extern crate quote;
use proc_macro::TokenStream;

#[proc_macro_derive(TypeName)]
pub fn type_name(input: TokenStream) -> TokenStream {
    let ast = syn::parse(input).unwrap();
    impl_typename(&ast).into()
}

fn impl_typename(ast: &syn::DeriveInput) -> impl Into<TokenStream> {
    let name = &ast.ident;
    quote! {
      impl TypeName for #name {
        fn typename() -> String {
          stringify!(#name).to_string()
        }
      }
    }
}

There seems to be some inconsistency between quote and syn, I don't know why.

1 Like

Adding the impl Into<...> fixed everything. Thanks!

The code in the book is outdated.

You can find up-to-date syn documentation here and quote documentation here.

1 Like