dtolnay / proc-macro-workshop

Learn to write Rust procedural macros  [Rust Latam conference, Montevideo Uruguay, March 2019]
Apache License 2.0
4k stars 1.01k forks source link

Help with Cargo Expand? #50

Closed NateAGeek closed 1 year ago

NateAGeek commented 2 years ago

Hello,

Thank you for the wonderful workshop. It is helping me learn macros! One thing is that I am using the cargo expand command... and I'm not getting clean expansion...

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(Builder)]
pub fn derive(input: TokenStream) -> TokenStream {
    let ast = match ::syn::parse_macro_input::parse::<DeriveInput>(input) {
        ::syn::__private::Ok(data) => data,
        ::syn::__private::Err(err) => {
            return ::syn::__private::TokenStream::from(err.to_compile_error());
        }
    };
    let name = &ast.ident;
    let bname = syn::Ident::new(
        &{
            let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
                &["", "Builder"],
                &[::core::fmt::ArgumentV1::new_display(&name)],
            ));
            res
        },
        name.span(),
    );
    let fields = if let syn::Data::Struct(syn::DataStruct {
        fields: syn::Fields::Named(syn::FieldsNamed { ref named, .. }),
        ..
    }) = ast.data
    {
        named
    } else {
        ::core::panicking::panic("not implemented")
    };
    let bname_struct_fields = fields.iter().map(|field| {
        let field_name = &field.ident;
        let field_type = &field.ty;
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&field_name, &mut _s);
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&field_type, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            _s
        }
    });
    let builder = {
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "pub");
        ::quote::__private::push_ident(&mut _s, "struct");
        ::quote::ToTokens::to_tokens(&bname, &mut _s);
        ::quote::__private::push_group(&mut _s, ::quote::__private::Delimiter::Brace, {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::ThereIsNoIteratorInRepetition;
                #[allow(unused_mut)]
                let (mut bname_struct_fields, i) = bname_struct_fields.quote_into_iter();
                let has_iter = has_iter | i;
                let _: ::quote::__private::HasIterator = has_iter;
                while true {
                    let bname_struct_fields = match bname_struct_fields.next() {
                        Some(_x) => ::quote::__private::RepInterp(_x),
                        None => break,
                    };
                    ::quote::ToTokens::to_tokens(&bname_struct_fields, &mut _s);
                    ::quote::__private::push_comma(&mut _s);
                }
            };
            _s
        });
        ::quote::__private::push_ident(&mut _s, "impl");
        ::quote::ToTokens::to_tokens(&name, &mut _s);
        ::quote::__private::push_group(&mut _s, ::quote::__private::Delimiter::Brace, {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "builder");
            ::quote::__private::push_group(
                &mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new(),
            );
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&bname, &mut _s);
            ::quote::__private::push_group(&mut _s, ::quote::__private::Delimiter::Brace, {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "return");
                ::quote::ToTokens::to_tokens(&bname, &mut _s);
                ::quote::__private::push_group(&mut _s, ::quote::__private::Delimiter::Brace, {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "executable");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "args");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "env");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "current_dir");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
                _s
            });
            _s
        });
        _s
    };
    return builder.into();
}
const _: () = {
    extern crate proc_macro;
    #[rustc_proc_macro_decls]
    #[allow(deprecated)]
    static _DECLS: &[proc_macro::bridge::client::ProcMacro] =
        &[proc_macro::bridge::client::ProcMacro::custom_derive(
            "Builder",
            &[],
            derive,
        )];
};

I've seen other output, per tutorial by Jon Gjengset](https://www.youtube.com/watch?v=geovSK3wMB8), and it looks clearer and helpful. While the current expand is filled with " ::quote::__private::push_comma"... Not sure if it is just a setting? Any direction or help would be really appreciated!

Thank you!

NateAGeek commented 2 years ago

I ended up using VS Code Rust Analyzer to dump out the expansion. But still curious why this is happening. Might be something with rustfmt?

This is my rustfmt info rustfmt 1.4.38-nightly (a707f401 2022-04-29) I am also on Windows if that helps.

dtolnay commented 1 year ago

Sorry that no one was able to provide guidance here. If this is still an issue, you could try taking this question to any of the resources shown in https://www.rust-lang.org/community.