null_fn/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use proc_macro::TokenStream;
4use proc_macro2::Ident;
5use quote::{quote, format_ident};
6use syn::{Generics, ItemFn, ItemStatic, Signature, Token, parse_macro_input, spanned::Spanned};
7
8#[proc_macro_attribute]
9#[doc = include_str!("../README.md")]
10pub fn null_fn(_: TokenStream, input: TokenStream) -> TokenStream {
11	let mut static_item = parse_macro_input!(input as ItemStatic);
12
13	let null_fn = ItemFn {
14		attrs: vec![],
15		vis: syn::parse_str("pub(super)").unwrap(),
16		block: syn::parse_str("{ panic!(\"This function has not been initialized yet\") }").unwrap(),
17		sig: Signature {
18			constness: None,
19			asyncness: None,
20			unsafety: Some(Token![unsafe](static_item.span())),
21			abi: None,
22			fn_token: Default::default(),
23			ident: Ident::new("null_fn", static_item.span()),
24			generics: Generics::default(),
25			paren_token: Default::default(),
26			inputs: Default::default(),
27			variadic: Default::default(),
28			output: syn::ReturnType::Default
29		},
30	};
31
32	static_item.expr = syn::parse_str(&format!("unsafe{{std::mem::transmute(__null_fn__{}::null_fn as *const ())}}", static_item.ident)).unwrap();
33
34	let mod_name = format_ident!("__null_fn__{}", static_item.ident);
35	quote!(
36		#[allow(non_snake_case)]
37		mod #mod_name {
38			#[allow(unused_variables)]
39			#null_fn
40		}
41		#static_item
42	).into()
43}