diff --git a/Cargo.lock b/Cargo.lock index 46bbe62..b560524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,7 +135,7 @@ dependencies = [ [[package]] name = "gmod" -version = "12.0.0" +version = "12.0.1" dependencies = [ "cfg_table 1.0.0", "cstr", @@ -144,7 +144,7 @@ dependencies = [ "fn_abi", "fn_has_this", "fn_type_alias", - "gmod-macros 2.0.0", + "gmod-macros 2.0.1", "gmserverplugin", "lazy_static", "libloading", @@ -165,7 +165,7 @@ dependencies = [ [[package]] name = "gmod-macros" -version = "2.0.0" +version = "2.0.1" dependencies = [ "proc-macro2", "quote", diff --git a/gmod-macros/Cargo.toml b/gmod-macros/Cargo.toml index dfedc2a..bf066e9 100644 --- a/gmod-macros/Cargo.toml +++ b/gmod-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gmod-macros" -version = "2.0.0" +version = "2.0.1" authors = ["William Venner "] edition = "2021" license = "MIT" diff --git a/gmod-macros/src/lib.rs b/gmod-macros/src/lib.rs index 33c24d7..89572a2 100644 --- a/gmod-macros/src/lib.rs +++ b/gmod-macros/src/lib.rs @@ -8,6 +8,16 @@ use proc_macro::TokenStream; use quote::ToTokens; use syn::ItemFn; +macro_rules! wrap_compile_error { + ($input:ident, $code:expr) => {{ + let orig_tokens = $input.clone(); + match (|| -> Result { $code })() { + Ok(tokens) => tokens, + Err(_) => return orig_tokens + } + }}; +} + fn check_lua_function(input: &mut ItemFn) { assert!(input.sig.asyncness.is_none(), "Cannot be async"); assert!(input.sig.constness.is_none(), "Cannot be const"); @@ -24,66 +34,72 @@ fn genericify_return(item_fn: &mut ItemFn) { #[proc_macro_attribute] pub fn gmod13_open(_attr: TokenStream, tokens: TokenStream) -> TokenStream { - let mut input = parse_macro_input!(tokens as ItemFn); + wrap_compile_error!(tokens, { + let mut input = syn::parse::(tokens)?; - let lua_ident = format_ident!("{}", match &input.sig.inputs[0] { - syn::FnArg::Typed(arg) => arg.pat.to_token_stream().to_string(), - _ => unreachable!(), - }); + let lua_ident = format_ident!("{}", match &input.sig.inputs[0] { + syn::FnArg::Typed(arg) => arg.pat.to_token_stream().to_string(), + _ => unreachable!(), + }); - // Capture the Lua state - input.block.stmts.insert(0, syn::parse2(quote!(::gmod::lua::__set_state__internal(#lua_ident);)).unwrap()); + // Capture the Lua state + input.block.stmts.insert(0, syn::parse2(quote!(::gmod::lua::__set_state__internal(#lua_ident);)).unwrap()); - // Load lua_shared - input.block.stmts.insert(0, syn::parse2(quote!(#[allow(unused_unsafe)] unsafe { ::gmod::lua::load() })).unwrap()); + // Load lua_shared + input.block.stmts.insert(0, syn::parse2(quote!(#[allow(unused_unsafe)] unsafe { ::gmod::lua::load() })).unwrap()); - // Make sure it's valid - check_lua_function(&mut input); + // Make sure it's valid + check_lua_function(&mut input); - // No mangling - input.attrs.push(parse_quote!(#[no_mangle])); + // No mangling + input.attrs.push(parse_quote!(#[no_mangle])); - // Make the return type nice and dynamic - genericify_return(&mut input); + // Make the return type nice and dynamic + genericify_return(&mut input); - input.into_token_stream().into() + Ok(input.into_token_stream().into()) + }) } #[proc_macro_attribute] pub fn gmod13_close(_attr: TokenStream, tokens: TokenStream) -> TokenStream { - let mut input = parse_macro_input!(tokens as ItemFn); + wrap_compile_error!(tokens, { + let mut input = syn::parse::(tokens)?; - // Make sure it's valid - check_lua_function(&mut input); + // Make sure it's valid + check_lua_function(&mut input); - // No mangling - input.attrs.push(parse_quote!(#[no_mangle])); + // No mangling + input.attrs.push(parse_quote!(#[no_mangle])); - // Shutdown gmcl thread if it's running - #[cfg(feature = "gmcl")] { - let stmts = std::mem::take(&mut input.block.stmts); - input.block.stmts = vec![syn::parse2(quote!({ - let ret = (|| {#(#stmts);*})(); - ::gmod::gmcl::restore_stdout(); - ret - })).unwrap()]; - } + // Shutdown gmcl thread if it's running + #[cfg(feature = "gmcl")] { + let stmts = std::mem::take(&mut input.block.stmts); + input.block.stmts = vec![syn::parse2(quote!({ + let ret = (|| {#(#stmts);*})(); + ::gmod::gmcl::restore_stdout(); + ret + })).unwrap()]; + } - // Make the return type nice and dynamic - genericify_return(&mut input); + // Make the return type nice and dynamic + genericify_return(&mut input); - input.into_token_stream().into() + Ok(input.into_token_stream().into()) + }) } #[proc_macro_attribute] pub fn lua_function(_attr: TokenStream, tokens: TokenStream) -> TokenStream { - let mut input = parse_macro_input!(tokens as ItemFn); + wrap_compile_error!(tokens, { + let mut input = syn::parse::(tokens)?; - // Make sure it's valid - check_lua_function(&mut input); + // Make sure it's valid + check_lua_function(&mut input); - // Make the return type nice and dynamic - genericify_return(&mut input); + // Make the return type nice and dynamic + genericify_return(&mut input); - input.into_token_stream().into() + Ok(input.into_token_stream().into()) + }) } \ No newline at end of file diff --git a/gmod/Cargo.toml b/gmod/Cargo.toml index 56f9409..4f890f6 100644 --- a/gmod/Cargo.toml +++ b/gmod/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gmod" -version = "12.0.0" +version = "12.0.1" authors = ["William Venner "] edition = "2021" license = "MIT" @@ -16,7 +16,7 @@ server-plugin = ["gmserverplugin"] gmcl = ["gmod-macros/gmcl"] [dependencies] -gmod-macros = { version = "2.0.0", path = "../gmod-macros" } +gmod-macros = { version = "2.0.1", path = "../gmod-macros" } gmserverplugin = { version = "1", optional = true } libloading = "0"