11// NOTE: ABI target cfgs are provided by the build script as `has_abi_<name>`.
22
3- macro_rules! cfg_all {
4- ( $meta: meta { $( $items: item) * } ) => {
5- $( #[ cfg( $meta) ] $items) *
6- } ;
7- }
8-
93macro_rules! impl_fn {
104 ( @recurse ( ) ( $( $nm: ident : $ty: ident) ,* ) ) => {
115 impl_fn!( @impl_all ( $( $nm : $ty) ,* ) ) ;
@@ -38,14 +32,14 @@ macro_rules! impl_fn {
3832 impl_fn!( @impl_core ( $( $nm : $ty) ,* ) , unsafe extern $abi_str fn ( $( $ty) ,* ) -> Ret , false , $abi_ident, $abi_str) ;
3933 } ;
4034
41- ( @impl_core ( $( $nm: ident : $ty: ident) ,* ) , $fn_type: ty, true , $abi_ident: ident, $call_conv: expr) => {
35+ ( @impl_core ( $( $nm: ident : $ty: ident) ,* ) , $fn_type: ty, $safety : tt , $abi_ident: ident, $call_conv: expr) => {
4236 #[ automatically_derived]
4337 impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: FnPtr for $fn_type {
4438 type Args = ( $( $ty, ) * ) ;
4539 type Output = Ret ;
4640
4741 const ARITY : :: core:: primitive:: usize = impl_fn!( @count ( $( $ty) * ) ) ;
48- const IS_SAFE : :: core:: primitive:: bool = true ;
42+ const IS_SAFE : :: core:: primitive:: bool = $safety ;
4943 const IS_EXTERN : :: core:: primitive:: bool = !matches!( $crate:: Abi :: $abi_ident, $crate:: Abi :: Rust ) ;
5044 const ABI : $crate:: Abi = $crate:: Abi :: $abi_ident;
5145
@@ -54,97 +48,68 @@ macro_rules! impl_fn {
5448 }
5549 unsafe fn from_ptr( ptr: $crate:: UntypedFnPtr ) -> Self {
5650 :: core:: assert!( !ptr. is_null( ) ) ;
57- unsafe { :: core:: mem:: transmute( ptr) }
58- }
59- }
60- #[ automatically_derived]
61- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: SafeFnPtr for $fn_type {
62- fn invoke( & self , impl_fn!( @call_args ( $( $nm) ,* ) ) : Self :: Args ) -> Self :: Output {
63- ( * self ) ( $( $nm) ,* )
51+ unsafe { :: core:: mem:: transmute:: <$crate:: UntypedFnPtr , Self >( ptr) }
6452 }
6553 }
54+ impl_fn!( @impl_safe_fn_type ( $( $nm : $ty) ,* ) , $fn_type, $safety) ;
6655
6756 // WithSafety
6857 #[ automatically_derived]
69- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ true } , $fn_type> for $fn_type { type F = $fn_type; }
58+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ true } > for $fn_type {
59+ type F = extern $call_conv fn ( $( $ty) ,* ) -> Ret ;
60+ }
7061 #[ automatically_derived]
71- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ false } , $fn_type> for $fn_type { type F = unsafe extern $call_conv fn ( $( $ty) ,* ) -> Ret ; }
72-
73- cfg_all!( feature = "nightly" {
74- // HasAbi
75- #[ automatically_derived]
76- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: HasAbi <{ $crate:: Abi :: $abi_ident} > for $fn_type { }
77-
78- // WithAbi
79- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Rust } , $fn_type> for $fn_type { type F = extern "Rust" fn ( $( $ty) ,* ) -> Ret ; }
80- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: C } , $fn_type> for $fn_type { type F = extern "C" fn ( $( $ty) ,* ) -> Ret ; }
81- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: System } , $fn_type> for $fn_type { type F = extern "system" fn ( $( $ty) ,* ) -> Ret ; }
82- #[ cfg( has_abi_cdecl) ]
83- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Cdecl } , $fn_type> for $fn_type { type F = extern "cdecl" fn ( $( $ty) ,* ) -> Ret ; }
84- #[ cfg( has_abi_stdcall) ]
85- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Stdcall } , $fn_type> for $fn_type { type F = extern "stdcall" fn ( $( $ty) ,* ) -> Ret ; }
86- #[ cfg( has_abi_fastcall) ]
87- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Fastcall } , $fn_type> for $fn_type { type F = extern "fastcall" fn ( $( $ty) ,* ) -> Ret ; }
88- #[ cfg( has_abi_win64) ]
89- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Win64 } , $fn_type> for $fn_type { type F = extern "win64" fn ( $( $ty) ,* ) -> Ret ; }
90- #[ cfg( has_abi_sysv64) ]
91- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Sysv64 } , $fn_type> for $fn_type { type F = extern "sysv64" fn ( $( $ty) ,* ) -> Ret ; }
92- #[ cfg( has_abi_aapcs) ]
93- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Aapcs } , $fn_type> for $fn_type { type F = extern "aapcs" fn ( $( $ty) ,* ) -> Ret ; }
94- } ) ;
95- } ;
62+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ false } > for $fn_type {
63+ type F = unsafe extern $call_conv fn ( $( $ty) ,* ) -> Ret ;
64+ }
9665
97- ( @impl_core ( $ ( $nm : ident : $ty : ident ) , * ) , $fn_type : ty , false , $abi_ident : ident , $call_conv : expr ) => {
66+ // HasAbi
9867 #[ automatically_derived]
99- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: FnPtr for $fn_type {
100- type Args = ( $( $ty, ) * ) ;
101- type Output = Ret ;
68+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: HasAbi <{ $crate:: abi:: key( $crate:: Abi :: $abi_ident) } > for $fn_type { }
10269
103- const ARITY : :: core:: primitive:: usize = impl_fn!( @count ( $( $ty) * ) ) ;
104- const IS_SAFE : :: core:: primitive:: bool = false ;
105- const IS_EXTERN : :: core:: primitive:: bool = !matches!( $crate:: Abi :: $abi_ident, $crate:: Abi :: Rust ) ;
106- const ABI : $crate:: Abi = $crate:: Abi :: $abi_ident;
107-
108- fn as_ptr( & self ) -> $crate:: UntypedFnPtr {
109- * self as $crate:: UntypedFnPtr
110- }
111- unsafe fn from_ptr( ptr: $crate:: UntypedFnPtr ) -> Self {
112- :: core:: assert!( !ptr. is_null( ) ) ;
113- unsafe { :: core:: mem:: transmute( ptr) }
114- }
70+ // WithAbi
71+ #[ automatically_derived]
72+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Rust ) } > for $fn_type {
73+ type F = impl_fn!( @make_unsafe extern "Rust" fn ( $( $ty) ,* ) -> Ret , $safety) ;
11574 }
11675 #[ automatically_derived]
117- impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: UnsafeFnPtr for $fn_type {
118- unsafe fn invoke( & self , impl_fn!( @call_args ( $( $nm) ,* ) ) : Self :: Args ) -> Self :: Output {
119- unsafe { ( * self ) ( $( $nm) ,* ) }
120- }
76+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: C ) } > for $fn_type {
77+ type F = impl_fn!( @make_unsafe extern "C" fn ( $( $ty) ,* ) -> Ret , $safety) ;
78+ }
79+ #[ automatically_derived]
80+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: System ) } > for $fn_type {
81+ type F = impl_fn!( @make_unsafe extern "system" fn ( $( $ty) ,* ) -> Ret , $safety) ;
82+ }
83+ #[ cfg( has_abi_cdecl) ]
84+ #[ automatically_derived]
85+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Cdecl ) } > for $fn_type {
86+ type F = impl_fn!( @make_unsafe extern "cdecl" fn ( $( $ty) ,* ) -> Ret , $safety) ;
87+ }
88+ #[ cfg( has_abi_stdcall) ]
89+ #[ automatically_derived]
90+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Stdcall ) } > for $fn_type {
91+ type F = impl_fn!( @make_unsafe extern "stdcall" fn ( $( $ty) ,* ) -> Ret , $safety) ;
92+ }
93+ #[ cfg( has_abi_fastcall) ]
94+ #[ automatically_derived]
95+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Fastcall ) } > for $fn_type {
96+ type F = impl_fn!( @make_unsafe extern "fastcall" fn ( $( $ty) ,* ) -> Ret , $safety) ;
97+ }
98+ #[ cfg( has_abi_win64) ]
99+ #[ automatically_derived]
100+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Win64 ) } > for $fn_type {
101+ type F = impl_fn!( @make_unsafe extern "win64" fn ( $( $ty) ,* ) -> Ret , $safety) ;
102+ }
103+ #[ cfg( has_abi_sysv64) ]
104+ #[ automatically_derived]
105+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Sysv64 ) } > for $fn_type {
106+ type F = impl_fn!( @make_unsafe extern "sysv64" fn ( $( $ty) ,* ) -> Ret , $safety) ;
107+ }
108+ #[ cfg( has_abi_aapcs) ]
109+ #[ automatically_derived]
110+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: abi:: key( $crate:: Abi :: Aapcs ) } > for $fn_type {
111+ type F = impl_fn!( @make_unsafe extern "aapcs" fn ( $( $ty) ,* ) -> Ret , $safety) ;
121112 }
122-
123- // WithSafety
124- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ true } , $fn_type> for $fn_type { type F = extern $call_conv fn ( $( $ty) ,* ) -> Ret ; }
125- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithSafety <{ false } , $fn_type> for $fn_type { type F = $fn_type; }
126-
127- cfg_all!( feature = "nightly" {
128- // HasAbi
129- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: HasAbi <{ $crate:: Abi :: $abi_ident} > for $fn_type { }
130-
131- // WithAbi
132- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Rust } , $fn_type> for $fn_type { type F = unsafe extern "Rust" fn ( $( $ty) ,* ) -> Ret ; }
133- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: C } , $fn_type> for $fn_type { type F = unsafe extern "C" fn ( $( $ty) ,* ) -> Ret ; }
134- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: System } , $fn_type> for $fn_type { type F = unsafe extern "system" fn ( $( $ty) ,* ) -> Ret ; }
135- #[ cfg( has_abi_cdecl) ]
136- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Cdecl } , $fn_type> for $fn_type { type F = unsafe extern "cdecl" fn ( $( $ty) ,* ) -> Ret ; }
137- #[ cfg( has_abi_stdcall) ]
138- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Stdcall } , $fn_type> for $fn_type { type F = unsafe extern "stdcall" fn ( $( $ty) ,* ) -> Ret ; }
139- #[ cfg( has_abi_fastcall) ]
140- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Fastcall } , $fn_type> for $fn_type { type F = unsafe extern "fastcall" fn ( $( $ty) ,* ) -> Ret ; }
141- #[ cfg( has_abi_win64) ]
142- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Win64 } , $fn_type> for $fn_type { type F = unsafe extern "win64" fn ( $( $ty) ,* ) -> Ret ; }
143- #[ cfg( has_abi_sysv64) ]
144- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Sysv64 } , $fn_type> for $fn_type { type F = unsafe extern "sysv64" fn ( $( $ty) ,* ) -> Ret ; }
145- #[ cfg( has_abi_aapcs) ]
146- #[ automatically_derived] impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: WithAbi <{ $crate:: Abi :: Aapcs } , $fn_type> for $fn_type { type F = unsafe extern "aapcs" fn ( $( $ty) ,* ) -> Ret ; }
147- } ) ;
148113 } ;
149114
150115 ( @count ( ) ) => {
@@ -154,6 +119,30 @@ macro_rules! impl_fn {
154119 1 + impl_fn!( @count ( $( $tl) * ) )
155120 } ;
156121
122+ ( @make_unsafe $fn_type: ty, true ) => {
123+ $fn_type
124+ } ;
125+ ( @make_unsafe extern $abi: literal fn ( $( $args: ty) ,* ) -> $ret: ty, false ) => {
126+ unsafe extern $abi fn ( $( $args) ,* ) -> $ret
127+ } ;
128+
129+ ( @impl_safe_fn_type ( $( $nm: ident : $ty: ident) ,* ) , $fn_type: ty, true ) => {
130+ #[ automatically_derived]
131+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: SafeFnPtr for $fn_type {
132+ fn invoke( & self , impl_fn!( @call_args ( $( $nm) ,* ) ) : Self :: Args ) -> Self :: Output {
133+ ( * self ) ( $( $nm) ,* )
134+ }
135+ }
136+ } ;
137+ ( @impl_safe_fn_type ( $( $nm: ident : $ty: ident) ,* ) , $fn_type: ty, false ) => {
138+ #[ automatically_derived]
139+ impl <Ret : ' static , $( $ty: ' static ) ,* > $crate:: UnsafeFnPtr for $fn_type {
140+ unsafe fn invoke( & self , impl_fn!( @call_args ( $( $nm) ,* ) ) : Self :: Args ) -> Self :: Output {
141+ unsafe { ( * self ) ( $( $nm) ,* ) }
142+ }
143+ }
144+ } ;
145+
157146 ( @call_args ( $single: ident) ) => {
158147 ( $single, )
159148 } ;
0 commit comments