11use proc_macro:: TokenStream ;
22use quote:: { quote, ToTokens } ;
33
4- use syn:: { parse_macro_input, parse_quote, FnArg , ItemFn , ReturnType , Type } ;
4+ use syn:: { parse_macro_input, parse_quote, spanned :: Spanned , FnArg , ItemFn , ReturnType , Type } ;
55
66fn handle_gmod ( item : TokenStream , export : Option < & str > ) -> TokenStream {
77 let mut returns_result: Option < & Box < Type > > = None ;
88
99 let mut ast = parse_macro_input ! ( item as ItemFn ) ;
1010
11- assert ! ( ast. sig. asyncness. is_none( ) , "Cannot be asynchronous" ) ;
12- assert ! ( ast. sig. constness. is_none( ) , "Cannot be const" ) ;
13- assert ! (
14- ast. sig. inputs. len( ) == 1 ,
15- "Must have one parameter, being the Lua state (rglua::lua::LuaState)"
16- ) ;
11+ if ast. sig . asyncness . is_some ( ) {
12+ return syn:: Error :: new ( ast. sig . span ( ) , "Cannot be async" ) . into_compile_error ( ) . into ( ) ;
13+ }
14+
15+ if ast. sig . constness . is_some ( ) {
16+ return syn:: Error :: new ( ast. sig . span ( ) , "Cannot be const" ) . into_compile_error ( ) . into ( ) ;
17+ }
18+
19+ if ast. sig . inputs . len ( ) != 1 {
20+ return syn:: Error :: new ( ast. sig . span ( ) , "Must have one parameter, being the Lua state (rglua::lua::LuaState)" ) . into_compile_error ( ) . into ( ) ;
21+ }
1722
1823 if let ReturnType :: Type ( _, ty) = & ast. sig . output {
1924 let mut ret = ty. to_token_stream ( ) . to_string ( ) ;
2025 if ret. starts_with ( "Result < i32" ) | ret. starts_with ( "std :: result :: Result < i32" ) {
2126 ret. retain ( |c| !c. is_whitespace ( ) ) ;
2227 returns_result = Some ( ty) ;
2328 } else {
24- assert ! (
25- ret. as_str( ) == "i32" ,
26- "Exported function must return i32 or Result<i32, E>"
27- ) ;
29+ if ret. as_str ( ) != "i32" {
30+ return syn:: Error :: new ( ast. sig . output . span ( ) , "Exported function must return i32 or Result<i32, E>" ) . into_compile_error ( ) . into ( ) ;
31+ }
2832 }
2933 } else {
30- panic ! ( "Exported function must return i32 or Result<i32, E>" ) ;
34+ return syn :: Error :: new ( ast . sig . output . span ( ) , "Exported function must return i32 or Result<i32, E>" ) . into_compile_error ( ) . into ( ) ;
3135 }
3236
3337 let lua_shared_param;
3438 let lua_shared_ty;
3539 // Make sure parameter is a LuaState
3640 match ast. sig . inputs . first ( ) . unwrap ( ) {
37- FnArg :: Receiver ( _) => panic ! ( "Parameter cannot be self" ) ,
41+ FnArg :: Receiver ( _) => return syn :: Error :: new ( ast . sig . inputs . span ( ) , "Parameter cannot be self" ) . into_compile_error ( ) . into ( ) ,
3842 FnArg :: Typed ( arg) => {
3943 // In the future this could check if it is *c_void as well.
4044 match arg. ty . to_token_stream ( ) . to_string ( ) . as_str ( ) {
4145 "LuaState" | "rglua :: lua :: LuaState" => ( ) ,
42- a => panic ! ( "Parameter must be rglua::lua::LuaState. Got {}" , a ) ,
46+ a => return syn :: Error :: new ( arg . ty . span ( ) , format ! ( "Parameter must be rglua::lua::LuaState. Got {a}" ) ) . to_compile_error ( ) . into ( ) ,
4347 }
4448
4549 lua_shared_ty = & arg. ty ;
@@ -49,9 +53,9 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
4953 lua_shared_param = & i. ident ;
5054 }
5155 syn:: Pat :: Wild ( _) => {
52- panic ! ( "Parameter must be named. Try _foo" ) ;
56+ return syn :: Error :: new ( arg . pat . span ( ) , "Parameter must be named. Try _foo" ) . to_compile_error ( ) . into ( ) ;
5357 }
54- _ => panic ! ( "Parameter must be in `` ident: ty`` format" ) ,
58+ _ => return syn :: Error :: new ( arg . pat . span ( ) , "Parameter must be in ' ident: ty' format" ) . to_compile_error ( ) . into ( ) ,
5559 }
5660 }
5761 }
@@ -60,7 +64,7 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
6064 if let Some ( abi) = & ast. sig . abi {
6165 match abi. name . as_ref ( ) . unwrap ( ) . value ( ) . as_str ( ) {
6266 "C" | "C-unwind" => ( ) ,
63- _ => panic ! ( "Only C ( or C-unwind) ABI is supported" ) ,
67+ _ => return syn :: Error :: new ( abi . span ( ) , "Only C or C-unwind are supported" ) . to_compile_error ( ) . into ( ) ,
6468 }
6569 } else {
6670 ast. sig . abi = Some ( parse_quote ! ( extern "C" ) )
@@ -115,7 +119,7 @@ fn handle_gmod(item: TokenStream, export: Option<&str>) -> TokenStream {
115119 for attr in & ast. attrs {
116120 if let Some ( id) = attr. path . get_ident ( ) {
117121 if id == "no_mangle" {
118- panic ! ( "Using no_mangle is unnecessary on exported functions" ) ;
122+ return syn :: Error :: new ( id . span ( ) , "Using no_mangle is unnecessary on exported functions" ) . into_compile_error ( ) . into ( ) ;
119123 }
120124 }
121125 }
0 commit comments