Skip to content

Commit d3c1e6f

Browse files
committed
Finish crate rewrite
1 parent 8d9ad40 commit d3c1e6f

10 files changed

Lines changed: 375 additions & 149 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type F = extern "C" fn(i32, i32) -> i32;
2424
assert_eq!(<F as FnPtr>::ARITY, 2);
2525
assert_eq!(<F as FnPtr>::IS_SAFE, true);
2626
assert_eq!(<F as FnPtr>::IS_EXTERN, true);
27-
assert_eq!(<F as FnPtr>::ABI, Abi::C { unwind: false });
27+
assert_eq!(<F as FnPtr>::abi, Abi::C { unwind: false });
2828
```
2929

3030
There are also some const helper functons to do so ergonomically.
@@ -33,7 +33,7 @@ There are also some const helper functons to do so ergonomically.
3333
const A: usize = fn_ptr::arity::<F>(); // 2
3434
const SAFE: bool = fn_ptr::is_safe::<F>(); // true
3535
const EXT: bool = fn_ptr::is_extern::<F>(); // true
36-
const ABI: Abi = fn_ptr::abi::<F>(); // Abi::C
36+
const abi: Abi = fn_ptr::abi::<F>(); // Abi::C
3737
```
3838

3939
### 2. Toggle Function Pointer Safety
@@ -60,7 +60,7 @@ let safe_add2: fn(i32, i32) -> i32 = unsafe { unsafe_add.as_safe() };
6060

6161
### 3. Changing ABIs
6262

63-
You can also change the ABI of a function pointer at the type level:
63+
You can also change the abi of a function pointer at the type level:
6464

6565
```rust
6666
use fn_ptr::{with_abi, Abi};
@@ -80,7 +80,7 @@ let rust_add: fn(i32, i32) -> i32 = |a, b| {a + b};
8080
let c_add: extern "C" fn(i32, i32) -> i32 = unsafe { rust_add.with_abi::<abi!("C")>() };
8181
```
8282

83-
Note that this does not change the underlying ABI and should be used with caution.
83+
Note that this does not change the underlying abi and should be used with caution.
8484

8585
## How It Works
8686

src/abi.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use crate::AbiValue;
22

3-
/// Type-level marker trait for function ABI.
3+
/// Type-level marker trait for function abi.
44
///
5-
/// Types implementing this trait represent a specific `extern "..."` ABI.
5+
/// Types implementing this trait represent a specific `extern "..."` abi.
66
///
77
/// See [`Abi`] for the runtime representation.
88
pub trait Abi {
9-
/// The exact ABI string used in `extern "..."`.
9+
/// The exact abi string used in `extern "..."`.
1010
const STR: &'static str;
1111

1212
/// The runtime [`Abi`] that represent this marker type.
@@ -22,7 +22,7 @@ macro_rules! define_abi_marker {
2222
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2323
#[doc = "Type-level marker for the `"]
2424
#[doc = $lit]
25-
#[doc = "` ABI."]
25+
#[doc = "` abi."]
2626
pub struct $name;
2727

2828
impl Abi for $name {
@@ -63,7 +63,7 @@ define_abi_marker!(SysV64Unwind, "sysv64-unwind");
6363
define_abi_marker!(Win64, "win64");
6464
define_abi_marker!(Win64Unwind, "win64-unwind");
6565

66-
/// Macro to convert an ABI string to the corrsponding [`Abi`] marker type.
66+
/// Macro to convert an abi string to the corresponding [`Abi`] marker type.
6767
#[macro_export]
6868
macro_rules! abi {
6969
// Common

src/abi_value.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,69 @@ use core::{
33
str::FromStr,
44
};
55

6-
/// The ABI or calling convention of a function pointer.
6+
/// The abi or calling convention of a function pointer.
77
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
88
// from https://github.com/rust-lang/rust/blob/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_abi/src/extern_abi.rs#L21
99
pub enum AbiValue {
1010
/* universal */
1111
/// This is the same as `extern fn foo()`; whatever the default your C compiler supports.
1212
C {
13-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
13+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
1414
unwind: bool,
1515
},
1616
/// Usually the same as [`extern "C"`](AbiValue::C), except on Win32, in which case it's
1717
/// [`"stdcall"`](AbiValue::Stdcall), or what you should use to link to the Windows API itself.
1818
System {
19-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
19+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
2020
unwind: bool,
2121
},
2222

23-
/// The default ABI when you write a normal `fn foo()` in any Rust code.
23+
/// The default abi when you write a normal `fn foo()` in any Rust code.
2424
Rust,
2525

2626
/* arm */
2727
/// The default for ARM.
2828
Aapcs {
29-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
29+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
3030
unwind: bool,
3131
},
3232

3333
/* x86 */
3434
/// The default for `x86_32` C code.
3535
Cdecl {
36-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
36+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
3737
unwind: bool,
3838
},
3939
/// The default for the Win32 API on `x86_32`.
4040
Stdcall {
41-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
41+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
4242
unwind: bool,
4343
},
44-
/// The `fastcall` ABI.
44+
/// The `fastcall` abi.
4545
Fastcall {
46-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
46+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
4747
unwind: bool,
4848
},
49-
/// The Windows C++ ABI.
49+
/// The Windows C++ abi.
5050
Thiscall {
51-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
51+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
5252
unwind: bool,
5353
},
54-
/// The `vectorcall` ABI.
54+
/// The `vectorcall` abi.
5555
Vectorcall {
56-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
56+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
5757
unwind: bool,
5858
},
5959

6060
/* x86_64 */
6161
/// The default for C code on non-Windows `x86_64`.
6262
SysV64 {
63-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
63+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
6464
unwind: bool,
6565
},
6666
/// The default for C code on `x86_64` Windows.
6767
Win64 {
68-
/// Whether unwinding across this ABI boundary is allowed (`*-unwind`).
68+
/// Whether unwinding across this abi boundary is allowed (`*-unwind`).
6969
unwind: bool,
7070
},
7171
}
@@ -89,12 +89,12 @@ impl AbiValue {
8989
}
9090
}
9191

92-
/// Canonicalize this ABI for the current target.
92+
/// Canonicalize this abi for the current target.
9393
///
94-
/// Maps aliases (e.g. `system`, `cdecl`) to the concrete ABI actually used on
94+
/// Maps aliases (e.g. `system`, `cdecl`) to the concrete abi actually used on
9595
/// the current OS/architecture, following Rust compiler rules.
9696
///
97-
/// Returns [`None`] if this ABI is not supported on the current target.
97+
/// Returns [`None`] if this abi is not supported on the current target.
9898
#[must_use]
9999
pub fn canonize(self, has_c_varargs: bool) -> Option<AbiValue> {
100100
// from https://github.com/rust-lang/rust/blob/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_target/src/spec/abi_map.rs#L79
@@ -165,7 +165,7 @@ macro_rules! abi_kind_impl {
165165
}
166166
) => {
167167
impl $t {
168-
/// Returns the string representation of this ABI.
168+
/// Returns the string representation of this abi.
169169
#[must_use]
170170
pub const fn to_str(&self) -> &'static str {
171171
match self {

src/base.rs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use core::{
55
};
66

77
use crate::{
8-
AsSafe, AsUnsafe, WithAbi, WithArgs, WithOutput, WithSafety, abi,
8+
WithAbi, WithAbiImpl, WithArgs, WithArgsImpl, WithOutput, WithOutputImpl, WithSafety,
9+
WithSafetyImpl, abi,
910
abi_value::AbiValue,
1011
safety::{self, Safe, Unsafe},
1112
tuple::Tuple,
@@ -19,6 +20,8 @@ ffi_opaque::opaque! {
1920
/// Type alias for a raw untyped function pointer.
2021
pub type UntypedFnPtr = *const OpaqueFn;
2122

23+
cfg_tt::cfg_tt! {}
24+
2225
cfg_tt::cfg_tt! {
2326
/// Marker trait for all function pointers.
2427
pub trait FnPtr:
@@ -37,8 +40,32 @@ pub trait FnPtr:
3740
+ UnwindSafe
3841
+ RefUnwindSafe
3942
+ Sized
40-
#[cfg(nightly_build)]
41-
(+ core::marker::FnPtr)
43+
+ WithOutputImpl
44+
+ WithArgsImpl
45+
+ WithSafetyImpl<safety::Safe>
46+
+ WithSafetyImpl<safety::Unsafe>
47+
+ WithAbiImpl<abi::Rust>
48+
+ WithAbiImpl<abi::C>
49+
+ WithAbiImpl<abi::CUnwind>
50+
+ WithAbiImpl<abi::System>
51+
+ WithAbiImpl<abi::SystemUnwind>
52+
#[cfg(nightly_build)](+ core::marker::FnPtr)
53+
#[cfg(has_abi_aapcs)](+ WithAbiImpl<abi::Aapcs>)
54+
#[cfg(has_abi_aapcs)](+ WithAbiImpl<abi::AapcsUnwind>)
55+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::Cdecl>)
56+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::CdeclUnwind>)
57+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::Stdcall>)
58+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::StdcallUnwind>)
59+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::Fastcall>)
60+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::FastcallUnwind>)
61+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::Thiscall>)
62+
#[cfg(has_abi_cdecl)](+ WithAbiImpl<abi::ThiscallUnwind>)
63+
#[cfg(has_abi_vectorcall)](+ WithAbiImpl<abi::Vectorcall>)
64+
#[cfg(has_abi_vectorcall)](+ WithAbiImpl<abi::VectorcallUnwind>)
65+
#[cfg(has_abi_sysv64)](+ WithAbiImpl<abi::SysV64>)
66+
#[cfg(has_abi_sysv64)](+ WithAbiImpl<abi::SysV64Unwind>)
67+
#[cfg(has_abi_win64)](+ WithAbiImpl<abi::Win64>)
68+
#[cfg(has_abi_win64)](+ WithAbiImpl<abi::Win64Unwind>)
4269
{
4370
/// The argument types as a tuple.
4471
type Args: Tuple;
@@ -61,7 +88,7 @@ pub trait FnPtr:
6188
/// Whether the function pointer uses an extern calling convention.
6289
const IS_EXTERN: bool;
6390

64-
/// The ABI associated with this function pointer.
91+
/// The abi associated with this function pointer.
6592
const ABI: AbiValue;
6693

6794
/// Returns the address of this function.
@@ -99,10 +126,7 @@ pub trait FnPtr:
99126

100127
/// Produces an unsafe version of this function pointer.
101128
#[must_use]
102-
fn as_unsafe(&self) -> <Self as AsUnsafe>::F
103-
where
104-
Self: AsUnsafe,
105-
{
129+
fn as_unsafe(&self) -> <Self as WithSafety<Unsafe>>::F {
106130
unsafe { FnPtr::from_ptr(self.as_ptr()) }
107131
}
108132

@@ -111,10 +135,7 @@ pub trait FnPtr:
111135
/// # Safety
112136
/// Caller must ensure the underlying function is actually safe to call.
113137
#[must_use]
114-
unsafe fn as_safe(&self) -> <Self as AsSafe>::F
115-
where
116-
Self: AsSafe,
117-
{
138+
unsafe fn as_safe(&self) -> <Self as WithSafety<Safe>>::F {
118139
self.cast()
119140
}
120141

@@ -130,10 +151,10 @@ pub trait FnPtr:
130151
self.cast()
131152
}
132153

133-
/// Produces a version of this function pointer with the given ABI.
154+
/// Produces a version of this function pointer with the given abi.
134155
///
135156
/// # Safety
136-
/// Caller must ensure that the resulting ABI transformation is sound.
157+
/// Caller must ensure that the resulting abi transformation is sound.
137158
#[must_use]
138159
unsafe fn with_abi<Abi: abi::Abi>(&self) -> <Self as WithAbi<Abi>>::F
139160
where
@@ -147,7 +168,7 @@ pub trait FnPtr:
147168
/// # Safety
148169
/// Caller must ensure that the resulting transformation is sound.
149170
#[must_use]
150-
unsafe fn with_ret<Output>(&self) -> <Self as WithOutput<Output>>::F
171+
unsafe fn with_output<Output>(&self) -> <Self as WithOutput<Output>>::F
151172
where
152173
Self: WithOutput<Output>,
153174
{
@@ -212,3 +233,22 @@ pub trait UnsafeFnPtr: FnPtr<Safety = Unsafe> {
212233
/// The return type and all parameter types have to be `'static`.
213234
pub trait StaticFnPtr: FnPtr + 'static {}
214235
impl<F: FnPtr + 'static> StaticFnPtr for F {}
236+
237+
#[cfg(test)]
238+
#[allow(unused)]
239+
mod test {
240+
use super::*;
241+
242+
fn h<F: FnPtr>(f: F) -> crate::with_abi!("system", F) {
243+
unsafe { f.cast() }
244+
}
245+
fn f<F: FnPtr>(f: F) -> crate::with_safety!(unsafe, F) {
246+
unsafe { f.cast() }
247+
}
248+
fn j<F: FnPtr>(f: F) -> crate::with_output!(i32, F) {
249+
unsafe { f.cast() }
250+
}
251+
fn k<F: FnPtr>(f: F) -> crate::with_args!((i32,), F) {
252+
unsafe { f.cast() }
253+
}
254+
}

src/build.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
use crate::{
2-
FnPtr, Tuple, WithAbi, WithArgs, WithOutput, WithSafety,
3-
abi::{self, Rust},
4-
safety::{self, Safe},
5-
};
1+
use crate::{FnPtr, Tuple, abi::Rust, safety::Safe};
62

73
/// Constructs a function-pointer type from its components.
84
///
95
/// Given
106
/// - a tuple of argument types (`Self`)
117
/// - a safety marker ([`Safety`](crate::safety::Safety))
12-
/// - an ABI ([`Abi`](crate::abi::Abi))
8+
/// - an abi ([`Abi`](crate::abi::Abi))
139
/// - an output type (`Output`)
1410
///
15-
/// The trait is implemented for tuples of argument types and produces the
16-
/// corresponding function-pointer type via the associated type [`F`](BuildFn::F).
11+
/// The trait is implemented for tuples, which get turned into the parameter types of [`F`](BuildFn::F).
1712
///
1813
/// # Examples
1914
///
@@ -28,6 +23,10 @@ pub trait BuildFn<Safety = Safe, Abi = Rust, Output = ()>: Tuple {
2823
type F: FnPtr<Args = Self, Output = Output, Safety = Safety, Abi = Abi>;
2924
}
3025

26+
/*
27+
These blanket impls could replace a large portion of impl.rs but would lead to
28+
additional bounds when using the traits.
29+
3130
impl<G: FnPtr, Args: BuildFn<G::Safety, G::Abi, G::Output>> WithArgs<Args> for G {
3231
type F = <Args as BuildFn<G::Safety, G::Abi, G::Output>>::F;
3332
}
@@ -52,3 +51,4 @@ where
5251
{
5352
type F = <G::Args as BuildFn<G::Safety, Abi, G::Output>>::F;
5453
}
54+
*/

0 commit comments

Comments
 (0)