I created a procedural macro ImplTraitMacro to implement a trait ImplTrait on a struct. The below works (the implementation of the ImplTraitMacro is at the end of this post).
I then created a macro_rules! to programatically set the field name of a struct, while still implementing a trait on the struct via a proc macro, as shown below.
error[E0425]: cannot find value `argument` in this scope
--> main/./main.rs:23:20
|
23 | declarative_macro!(field_name);
| ^^^^^^^^^^ not found in this scope
For more information about this error, try `rustc --explain E0425`.
Specifically, the derive proc macro is implemented like the below:
use syn::{parse_macro_input, DeriveInput, DataStruct, spanned::Spanned};
use quote::{quote, quote_spanned};
use proc_macro2::Span;
#[proc_macro_derive(ImplTraitMacro)]
pub fn implement_trait(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
// Boilerplate to obtain an arbitrary `Span`
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
let span = if let syn::Data::Struct(DataStruct {
fields: syn::Fields::Named(named),
..
}) = &input.data {
let fields: Vec<Span> = named.named.iter().map(|f| f.span()).collect();
fields[0]
} else {
panic!("Invalid input");
};
// Erroneous code
let multiply_by_2 = quote_spanned!{span=>
argument * 2
};
quote! {
impl impl_trait::ImplTrait for #name {
fn f(argument: u64) -> u64 {
#multiply_by_2
}
}
}.into()
}
It seems using a quote_spanned! whose tokens refer to an argument of a function (in this case called argument) causes the proc macro to be unable to find the argument variable when the proc macro is used inside a macro_rules!. This is fixed when either
quote! is used instead of quote_spanned!
When the quote_spanned! does not use a function argument as tokens (e.g. like the below)
let multiply_by_2 = quote_spanned!{span=>
123
};
quote! {
impl impl_trait::ImplTrait for #name {
fn f(argument: u64) -> u64 {
// Returning argument instead of `#multiply_by_2` also works
// argument
#multiply_by_2
}
}
}.into(
I'm using the following dependency versions
[dependencies]
syn = "2.0.18"
quote = "1.0.28"
proc-macro2 = "1.0.60"
The above code would constitute my minimal reproducible example. Let me know if you can reproduce this error, and why this would occur.
I created a procedural macro
ImplTraitMacro
to implement a traitImplTrait
on a struct. The below works (the implementation of theImplTraitMacro
is at the end of this post).I then created a
macro_rules!
to programatically set the field name of a struct, while still implementing a trait on the struct via a proc macro, as shown below.However, this encounters an error.
Specifically, the derive proc macro is implemented like the below:
It seems using a
quote_spanned!
whose tokens refer to an argument of a function (in this case calledargument
) causes the proc macro to be unable to find theargument
variable when the proc macro is used inside amacro_rules!
. This is fixed when eitherquote!
is used instead ofquote_spanned!
quote_spanned!
does not use a function argument as tokens (e.g. like the below)I'm using the following dependency versions
The above code would constitute my minimal reproducible example. Let me know if you can reproduce this error, and why this would occur.