This uses proc_macro_error2::set_dummy to correctly return the derive input stream and a shim implementation (if possible) when encountering an error, as opposed to the previous implementation which would generate the shim but never return the token stream, leading to the derive input getting consumed by the macro and causing unnecessary errors.
TFKGE6LRNSG2N5Z3LIITYG7WH2VOLWQO7AESTWRWV52BFHESU26AC OWXLFLRMQDTXWN5QQQLJNAATWFWXIN2S4UQA2LC2A6AWX4UWM6LQC CESJ4CTO26X4GBZBPXRXLOJT3JQJOGFN5EJSNAAZELNQRZF7QSYAC 73C6NOJ7W7ZCQ2THEZ4HXNZF3734VIPHI5VKQ2CCPLOA4L3JFIIQC 7JPOCQEISAIOD7LV4JYBE6NNUWUKKNE73MEPQYTIZ7PP44ZAD2RAC LU6IFZFGPIKF3CBWZWITWVBSCYWF7Q4UXJDXVRWZ4XV7PKE5RSTQC QJC4IQITOQP65AFLA5CMH2EXHB6B3SOLW2XBV72U5ZQU2KOR2EIAC NEBSVXIASWSJO2CVU3VWRONIWJJDLL3VDS6WNKQBWQBRUUI7RSYAC 6XEMHUGSNX5YSWZYM7PZUTTUMFODMGO74QLHGEXQ5LAC7LPS7JNQC RUCC2HKZZTUHN3G6IWS4NK3VYGXAI6PORJH2YZKPRAYSDWH63ESQC EKXWNEPK4FTYKT2RJL2L7HTM64VQGDD3DYD6NZIDGMMV6ITHUVZAC RA3H7PWCI7WHONXB32IWYECQ3VKPKEXXYAJDIOHWNAGHDO7L5ZLQC O77KA6C4UJGZXVGPEA7WCRQH6XYQJPWETSPDXI3VOKOSRQND7JEQC // Emit the relevant error messagemacro_impl::error::emit(error, &attribute_stream, &derive_input_stream);
// Using the `proc_macro_error2` crate to generate errors ignores// the token stream returned from this function, so use the `set_dummy` function// to make sure a macro error is as self-contained as possible:// - Derive input streams are not consumed, so structs/enums don't "disappear" when macro returns error// - Generate a shim trait implementation when possible so that editor completions still work as expectedproc_macro_error2::set_dummy(match syn::parse2::<syn::DeriveInput>(derive_input_stream.clone()) {// Generate a minimal `Localize` implementation so the error is self-containedOk(derive_input) => {let ident = derive_input.ident;let (impl_generics, type_generics, where_clause) =derive_input.generics.split_for_impl();
// Generate a minimal `Localize` implementation so the error is self-containedmatch syn::parse2::<syn::DeriveInput>(derive_input_stream.clone()) {Ok(derive_input) => {let ident = derive_input.ident;quote! {#derive_input_stream
quote! {#derive_input_stream
impl ::l10n_embed::Localize for #ident {fn localize(&self,context: &::l10n_embed::Context,buffer: &mut String,) {unimplemented!("Encountered error in derive macro")
impl #impl_generics ::l10n_embed::Localize for #ident #type_generics #where_clause {fn localize(&self,context: &::l10n_embed::Context,buffer: &mut String,) {unimplemented!("Encountered error in derive macro")}
}// Unable to fail gracefully if the ident is unknown, so just return the original inputErr(_) => derive_input_stream,}
// Unable to implement Localize if the ident is unknown, so just return the original inputErr(_) => derive_input_stream.clone(),},);// Emit the relevant error messagemacro_impl::error::emit(error, &attribute_stream, &derive_input_stream);// `proc_macro_error2` will output the relevant token stream, but the function still needs to return somethingquote!()