syn
syn copied to clipboard
parsing fields from `quote` fails with `"expected curly braces"`
Files to regenerate the error
base_crate/Cargo.toml
[package]
name = "add-fields-to-struct"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
proc-macros = { path = "./proc-macros" }
src/main.rs
fn main() {
let mystruct = MyStruct {
fieldaroo1: 37.,
fieldaroo2: 42.,
};
println!("{}", mystruct.summity_sumaroo());
}
#[proc_macros::do_the_macro]
pub struct MyStruct {
pub fieldaroo1: f64,
pub fieldaroo2: f64,
}
impl MyStruct {
fn summity_sumaroo(&self) -> f64 {
self.fieldaroo1 + self.fieldaroo2
}
}
base_crate/proc-macros/Cargo.toml
[package]
name = "proc-macros"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
proc-macro2 = "1.0.66"
syn = { version = "2.0.28", features = ["full"] }
proc-macro-error = "1.0.4"
quote = "1.0.18"
regex = "1.6.0"
[lib]
proc-macro = true
base_crate/proc-macros/src/lib.rs
pub(crate) use proc_macro::TokenStream;
pub(crate) use proc_macro2::TokenStream as TokenStream2;
pub(crate) use proc_macro_error::{abort, abort_call_site, emit_error, proc_macro_error};
pub(crate) use quote::{quote, ToTokens, TokenStreamExt}; // ToTokens is implicitly used as a trait
pub(crate) use regex::Regex;
pub(crate) use syn::{spanned::Spanned, DeriveInput, Field, FieldsNamed, Ident, Meta};
#[proc_macro_error]
#[proc_macro_attribute]
pub fn do_the_macro(_attr: TokenStream, item: TokenStream) -> TokenStream {
// make a copy so there is something to return as things are built out
let dummy_item = item.clone();
let syn_named = TokenStream2::from(quote! {
pub fieldaroo1: f64,
pub fieldaroo2: f64,
});
let mut ast = syn::parse_macro_input!(item as syn::ItemStruct);
if let syn::Fields::Named(FieldsNamed { named, .. }) = &mut ast.fields {
// prints `reference: pub fieldaroo1 : f64, pub fieldaroo2 : f64,`
println!("reference: {}", named.to_token_stream().to_string());
// prints `test: pub fieldaroo1 : f64, pub fieldaroo2_electric_boogaloo : f64,`
println!("test: {}", syn_named.to_token_stream().to_string());
assert_eq!(syn_named.to_string(), named.to_token_stream().to_string());
let parsed_named: TokenStream2 = syn::parse2(TokenStream2::from(named.to_token_stream()))
.map_err(|e| {
format!(
"[{}:{}] Parse 2 failed on named from macro input. {}",
file!(),
line!(),
e
)
})
.unwrap();
}
let syn_named: FieldsNamed = syn::parse2(syn_named)
.map_err(|e| format!("[{}:{}] `parse2` failed. {}", file!(), line!(), e))
.unwrap();
dummy_item
}
Output for cargo run
warning: unused imports: `abort_call_site`, `abort`, `emit_error`
--> proc-macros/src/lib.rs:3:35
|
3 | pub(crate) use proc_macro_error::{abort, abort_call_site, emit_error, proc_macro_error};
| ^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `TokenStreamExt`
--> proc-macros/src/lib.rs:4:41
|
4 | pub(crate) use quote::{quote, ToTokens, TokenStreamExt}; // ToTokens is implicitly used as a trait
| ^^^^^^^^^^^^^^
warning: unused import: `regex::Regex`
--> proc-macros/src/lib.rs:5:16
|
5 | pub(crate) use regex::Regex;
| ^^^^^^^^^^^^
warning: unused imports: `DeriveInput`, `Field`, `Ident`, `Meta`, `spanned::Spanned`
--> proc-macros/src/lib.rs:6:22
|
6 | pub(crate) use syn::{spanned::Spanned, DeriveInput, Field, FieldsNamed, Ident, Meta};
| ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^ ^^^^^ ^^^^
warning: unused variable: `parsed_named`
--> proc-macros/src/lib.rs:28:13
|
28 | let parsed_named: TokenStream2 = syn::parse2(TokenStream2::from(named.to_token_stream()))
| ^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_parsed_named`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `syn_named`
--> proc-macros/src/lib.rs:40:9
|
40 | let syn_named: FieldsNamed = syn::parse2(syn_named)
| ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_syn_named`
warning: `proc-macros` (lib) generated 6 warnings (run `cargo fix --lib -p proc-macros` to apply 6 suggestions)
Compiling add-fields-to-struct v0.1.0 (/Users/cbaker2/Documents/playground/rust/add-fields-to-struct)
reference: pub fieldaroo1 : f64, pub fieldaroo2 : f64,
test: pub fieldaroo1 : f64, pub fieldaroo2 : f64,
error: custom attribute panicked
--> src/main.rs:9:1
|
9 | #[proc_macros::do_the_macro]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: message: called `Result::unwrap()` on an `Err` value: "[proc-macros/src/lib.rs:41] `parse2` failed. expected curly braces"
error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
--> src/main.rs:2:20
|
2 | let mystruct = MyStruct {
| ^^^^^^^^ not found in this scope
error[E0412]: cannot find type `MyStruct` in this scope
--> src/main.rs:15:6
|
15 | impl MyStruct {
| ^^^^^^^^ not found in this scope
Some errors have detailed explanations: E0412, E0422.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `add-fields-to-struct` (bin "add-fields-to-struct") due to 3 previous errors
Expected outcome
This should be runnable code as best as I can tell