1use crate::{
2 FnPtr, HasAbi, HasSafety,
3 marker::{self, Safe, Unsafe},
4};
5
6pub trait WithAbi<Abi>: FnPtr
8where
9 Abi: marker::Abi,
10{
11 type F: FnPtr<
13 Args = Self::Args,
14 Output = Self::Output,
15 ArityMarker = Self::ArityMarker,
16 SafetyMarker = Self::SafetyMarker,
17 AbiMarker = Abi,
18 > + HasAbi<Abi>;
19}
20
21pub trait WithSafety<Safety>: FnPtr
23where
24 Safety: marker::Safety,
25{
26 type F: FnPtr<
28 Args = Self::Args,
29 Output = Self::Output,
30 ArityMarker = Self::ArityMarker,
31 SafetyMarker = Safety,
32 AbiMarker = Self::AbiMarker,
33 > + HasSafety<Safety>;
34}
35
36pub trait AsSafe: WithSafety<Safe> {}
38impl<F: WithSafety<Safe>> AsSafe for F {}
39
40pub trait AsUnsafe: WithSafety<Unsafe> {}
42impl<F: WithSafety<Unsafe>> AsUnsafe for F {}
43
44cfg_tt::cfg_tt! {
45pub trait Convertible:
48 FnPtr
49 + WithAbi<marker::Rust>
50 + WithAbi<marker::C>
51 + WithAbi<marker::CUnwind>
52 + WithAbi<marker::System>
53 + WithAbi<marker::SystemUnwind>
54 + WithSafety<marker::Safe>
55 + WithSafety<marker::Unsafe>
56 + AsSafe
57 + AsUnsafe
58 #[cfg(has_abi_aapcs)](+ WithAbi<marker::Aapcs>)
59 #[cfg(has_abi_aapcs)](+ WithAbi<marker::AapcsUnwind>)
60 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Cdecl>)
61 #[cfg(has_abi_cdecl)](+ WithAbi<marker::CdeclUnwind>)
62 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Stdcall>)
63 #[cfg(has_abi_cdecl)](+ WithAbi<marker::StdcallUnwind>)
64 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Fastcall>)
65 #[cfg(has_abi_cdecl)](+ WithAbi<marker::FastcallUnwind>)
66 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Thiscall>)
67 #[cfg(has_abi_cdecl)](+ WithAbi<marker::ThiscallUnwind>)
68 #[cfg(has_abi_vectorcall)](+ WithAbi<marker::Vectorcall>)
69 #[cfg(has_abi_vectorcall)](+ WithAbi<marker::VectorcallUnwind>)
70 #[cfg(has_abi_sysv64)](+ WithAbi<marker::SysV64>)
71 #[cfg(has_abi_sysv64)](+ WithAbi<marker::SysV64Unwind>)
72 #[cfg(has_abi_win64)](+ WithAbi<marker::Win64>)
73 #[cfg(has_abi_win64)](+ WithAbi<marker::Win64Unwind>)
74{
75}
76impl<T> Convertible for T
77where
78 T: FnPtr
79 + WithAbi<marker::Rust>
80 + WithAbi<marker::C>
81 + WithAbi<marker::CUnwind>
82 + WithAbi<marker::System>
83 + WithAbi<marker::SystemUnwind>
84 + WithSafety<marker::Safe>
85 + WithSafety<marker::Unsafe>
86 + AsSafe
87 + AsUnsafe
88 #[cfg(has_abi_aapcs)](+ WithAbi<marker::Aapcs>)
89 #[cfg(has_abi_aapcs)](+ WithAbi<marker::AapcsUnwind>)
90 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Cdecl>)
91 #[cfg(has_abi_cdecl)](+ WithAbi<marker::CdeclUnwind>)
92 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Stdcall>)
93 #[cfg(has_abi_cdecl)](+ WithAbi<marker::StdcallUnwind>)
94 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Fastcall>)
95 #[cfg(has_abi_cdecl)](+ WithAbi<marker::FastcallUnwind>)
96 #[cfg(has_abi_cdecl)](+ WithAbi<marker::Thiscall>)
97 #[cfg(has_abi_cdecl)](+ WithAbi<marker::ThiscallUnwind>)
98 #[cfg(has_abi_vectorcall)](+ WithAbi<marker::Vectorcall>)
99 #[cfg(has_abi_vectorcall)](+ WithAbi<marker::VectorcallUnwind>)
100 #[cfg(has_abi_sysv64)](+ WithAbi<marker::SysV64>)
101 #[cfg(has_abi_sysv64)](+ WithAbi<marker::SysV64Unwind>)
102 #[cfg(has_abi_win64)](+ WithAbi<marker::Win64>)
103 #[cfg(has_abi_win64)](+ WithAbi<marker::Win64Unwind>)
104{}
105}
106
107#[macro_export]
125macro_rules! with_abi {
126 ( $abi:path, $ty:ty ) => {
127 <$ty as $crate::WithAbi<$abi>>::F
128 };
129
130 ( $lit:tt, $ty:ty ) => {
131 <$ty as $crate::WithAbi<$crate::abi!($lit)>>::F
132 };
133}
134
135#[macro_export]
154macro_rules! with_safety {
155 ( safe, $ty:ty ) => {
156 $crate::with_safety!(@inner $crate::marker::Safe, $ty)
157 };
158 ( unsafe, $ty:ty ) => {
159 $crate::with_safety!(@inner $crate::marker::Unsafe, $ty)
160 };
161 ( $safety:path, $ty:ty ) => {
162 $crate::with_safety!(@inner $safety, $ty)
163 };
164 ( $safety:tt, $ty:ty ) => {
165 $crate::with_safety!(@inner $crate::safety!($safety), $ty)
166 };
167
168 ( @inner $safety:ty, $ty:ty ) => {
169 <$ty as $crate::WithSafety<$safety>>::F
170 };
171}
172
173#[macro_export]
185macro_rules! make_safe {
186 ( $ty:ty ) => {
187 <$ty as $crate::WithSafety<$crate::marker::Safe>>::F
188 };
189}
190
191#[macro_export]
203macro_rules! make_unsafe {
204 ( $ty:ty ) => {
205 <$ty as $crate::WithSafety<$crate::marker::Unsafe>>::F
206 };
207}