Writing proc-macro without match statements everywhere

⚓ rust    📅 2025-07-16    👤 surdeus    👁️ 1      

surdeus

I have a lot of proc-macro code where only certain types of arguments are expected (no lifetimes, no references, generic arguments can only be of type Option, etc.).

Currently my code looks like a match statement after a match statement after a match statement.

Is there any way to make it more readable/more pleasant to write?

I want my code to read something like: convert this syn::Type to syn::TypePath. If it isn't then fail, then gracefully fail.

In particular, I want to avoid this code:

if ty_args.args.len() != 1 {
    panic!("Unsupported type: Unexpected path type: {ty:?}")
}

let ty_arg = &ty_args.args[0];
let syn::GenericArgument::Type(ty_arg) = ty_arg else {
    panic!("Unsupported type: Unexpected path type: {ty:?}")
};

let syn::Type::Path(ty_path_arg) = ty_arg else {
    panic!("Unsupported type: Unexpected path type: {ty:?}")
};

The only way to do that that I found is with the help of syn::parse_quote:

let args = &ty_args.args;
let ty_path_arg: syn::TypePath = syn::parse_quote! { #args };

But then the error is very cryptic, and I can only find where it happened with RUSTFLAGS="-Zproc-macro-backtrace"

6 posts - 2 participants

Read full topic

🏷️ rust_feed