11use proc_macro2:: { Span , TokenStream } ;
2- use quote:: quote;
2+ use quote:: { quote, quote_spanned } ;
33use syn:: parse:: { Parse , ParseStream } ;
4- use syn:: punctuated:: Punctuated ;
5- use syn:: token:: Comma ;
6- use syn:: { Expr , Ident , Result , Token } ;
4+ use syn:: spanned:: Spanned ;
5+ use syn:: { Ident , Result , Token } ;
76
87#[ derive( Debug ) ]
98pub struct InitMacroInput {
109 name : syn:: Lit ,
11- funcs : syn:: ExprArray ,
1210 load : TokenStream ,
11+ maybe_warning : TokenStream ,
1312}
1413
1514impl Parse for InitMacroInput {
1615 fn parse ( input : ParseStream ) -> Result < Self > {
1716 let name = syn:: Lit :: parse ( input) ?;
18- let _comma = <syn:: Token ![ , ] >:: parse ( input) ?;
19- let funcs = syn:: ExprArray :: parse ( input) ?;
17+
18+ let maybe_warning = if input. peek ( syn:: token:: Comma ) && input. peek2 ( syn:: token:: Bracket ) {
19+ // peeked, must be there
20+ let _ = syn:: token:: Comma :: parse ( input) . unwrap ( ) ;
21+ if let Ok ( funcs) = syn:: ExprArray :: parse ( input) {
22+ quote_spanned ! ( funcs. span( ) =>
23+ #[ allow( dead_code) ]
24+ fn rustler_init( ) {
25+ #[ deprecated(
26+ since = "0.34.0" ,
27+ note = "Passing NIF functions explicitly is deprecated and this argument is ignored, please remove it"
28+ ) ]
29+ #[ allow( non_upper_case_globals) ]
30+ const explicit_nif_functions: ( ) = ( ) ;
31+ let _ = explicit_nif_functions;
32+ }
33+ )
34+ } else {
35+ quote ! ( )
36+ }
37+ } else {
38+ quote ! ( )
39+ } ;
40+
2041 let options = parse_expr_assigns ( input) ;
2142 let load = extract_option ( options, "load" ) ;
2243
23- Ok ( InitMacroInput { name, funcs, load } )
44+ Ok ( InitMacroInput {
45+ name,
46+ load,
47+ maybe_warning,
48+ } )
2449 }
2550}
2651
@@ -55,20 +80,22 @@ fn extract_option(args: Vec<syn::ExprAssign>, name: &str) -> TokenStream {
5580impl From < InitMacroInput > for proc_macro2:: TokenStream {
5681 fn from ( input : InitMacroInput ) -> Self {
5782 let name = input. name ;
58- let num_of_funcs = input. funcs . elems . len ( ) ;
59- let funcs = nif_funcs ( input. funcs . elems ) ;
6083 let load = input. load ;
84+ let maybe_warning = input. maybe_warning ;
6185
6286 let inner = quote ! {
6387 static mut NIF_ENTRY : Option <rustler:: codegen_runtime:: DEF_NIF_ENTRY > = None ;
64- use rustler:: Nif ;
88+ let nif_funcs: Box <[ _] > =
89+ rustler:: codegen_runtime:: inventory:: iter:: <rustler:: Nif >( )
90+ . map( rustler:: Nif :: get_def)
91+ . collect( ) ;
6592
6693 let entry = rustler:: codegen_runtime:: DEF_NIF_ENTRY {
6794 major: rustler:: codegen_runtime:: NIF_MAJOR_VERSION ,
6895 minor: rustler:: codegen_runtime:: NIF_MINOR_VERSION ,
6996 name: concat!( #name, "\0 " ) . as_ptr( ) as * const rustler:: codegen_runtime:: c_char,
70- num_of_funcs: #num_of_funcs as rustler:: codegen_runtime:: c_int,
71- funcs: [ #funcs ] . as_ptr( ) ,
97+ num_of_funcs: nif_funcs . len ( ) as rustler:: codegen_runtime:: c_int,
98+ funcs: nif_funcs . as_ptr( ) ,
7299 load: {
73100 extern "C" fn nif_load(
74101 env: rustler:: codegen_runtime:: NIF_ENV ,
@@ -91,12 +118,17 @@ impl From<InitMacroInput> for proc_macro2::TokenStream {
91118 } ;
92119
93120 unsafe {
121+ // Leak nif_funcs
122+ std:: mem:: forget( nif_funcs) ;
123+
94124 NIF_ENTRY = Some ( entry) ;
95125 NIF_ENTRY . as_ref( ) . unwrap( )
96126 }
97127 } ;
98128
99129 quote ! {
130+ #maybe_warning
131+
100132 #[ cfg( unix) ]
101133 #[ no_mangle]
102134 extern "C" fn nif_init( ) -> * const rustler:: codegen_runtime:: DEF_NIF_ENTRY {
@@ -115,17 +147,3 @@ impl From<InitMacroInput> for proc_macro2::TokenStream {
115147 }
116148 }
117149}
118-
119- fn nif_funcs ( funcs : Punctuated < Expr , Comma > ) -> TokenStream {
120- let mut tokens = TokenStream :: new ( ) ;
121-
122- for func in funcs. iter ( ) {
123- if let Expr :: Path ( _) = * func {
124- tokens. extend ( quote ! ( #func:: FUNC , ) ) ;
125- } else {
126- panic ! ( "Expected an expression, found: {}" , stringify!( func) ) ;
127- }
128- }
129-
130- tokens
131- }
0 commit comments