Skip to content

Commit b4c13c7

Browse files
Merge pull request #170 from getditto/libc-improvements
`libc` improvements
2 parents 140dd8f + 42522f3 commit b4c13c7

10 files changed

Lines changed: 110 additions & 29 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ path = "src/_lib.rs"
33

44
[package]
55
name = "safer-ffi"
6-
version = "0.1.1" # Keep in sync
6+
version = "0.1.2" # Keep in sync
77
authors = [
88
"Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>",
99
]
@@ -126,6 +126,9 @@ inventory-0-3-1.optional = true
126126
inventory-0-3-1.package = "inventory"
127127
inventory-0-3-1.version = "0.3.1"
128128

129+
libc.version = "0.2.66"
130+
libc.default-features = false
131+
129132
log.optional = true
130133
log.version = "0.4.8"
131134

@@ -161,11 +164,7 @@ version = "0.0.3"
161164

162165
[dependencies.safer_ffi-proc_macros]
163166
path = "src/proc_macro"
164-
version = "=0.1.1" # Keep in sync
165-
166-
[target.'cfg(not(target = "wasm32-unknown-unknown"))'.dependencies]
167-
libc.version = "0.2.66"
168-
libc.default-features = false
167+
version = "=0.1.2" # Keep in sync
169168

170169
[workspace]
171170
members = [

ffi_tests/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js_tests/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/_lib.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ cfg_alloc! {
269269
mod boxed;
270270
}
271271

272+
#[doc(inline)]
272273
pub use self::c_char_module::c_char;
273274
#[path = "c_char.rs"]
274275
mod c_char_module;
@@ -294,6 +295,9 @@ mod dyn_traits;
294295
#[doc(no_inline)]
295296
pub use dyn_traits::futures;
296297

298+
pub
299+
mod libc;
300+
297301
pub
298302
mod ptr;
299303

@@ -320,8 +324,8 @@ cfg_alloc! {
320324
pub mod vec;
321325
}
322326

323-
#[apply(hidden_export)]
324-
use layout::impls::c_int;
327+
#[doc(inline)]
328+
pub use layout::impls::c_int;
325329

326330
pub
327331
mod prelude {
@@ -446,16 +450,6 @@ macro_rules! __abort_with_msg__ { ($($tt:tt)*) => (
446450
}}
447451
)}
448452

449-
#[cfg(target_arch = "wasm32")]
450-
#[allow(dead_code)]
451-
mod libc {
452-
pub type c_int = i32;
453-
pub type size_t = u32;
454-
pub type uintptr_t = u32;
455-
}
456-
#[cfg(not(target_arch = "wasm32"))]
457-
use ::libc;
458-
459453
extern crate self as safer_ffi;
460454

461455
#[apply(hidden_export)]

src/c_char.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
#![cfg_attr(rustfmt, rustfmt::skip)]
22
use_prelude!();
33

4+
/// A `ReprC` _standalone_ type with the same layout and ABI as
5+
/// [`::libc::c_char`][crate::libc::c_char].
6+
///
7+
/// By _standalone_, the idea is that this is defined as a (`transparent`) _newtype_ `struct`,
8+
/// rather than as a _`type` alias_, which is error-prone and yields less-portable headers (since
9+
/// the header generation will resolve the type alias and emit, for instance, `int8_t`, ⚠️).
10+
///
11+
/// By using this type, you guarantee that the C `char` type be used in the headers.
412
#[repr(transparent)]
513
#[derive(
614
Debug,
@@ -16,8 +24,7 @@ struct c_char /* = */ (
1624
u8,
1725
);
1826

19-
/// Assert that `::libc::c_char` is either `uint8_t` or `int8_t`.
20-
#[cfg(not(any(target_arch = "wasm32", not(feature = "std"))))] // no libc on WASM nor no_std
27+
/// Assert that `crate::libc::c_char` is either `uint8_t` or `int8_t`.
2128
const _: () = {
2229
trait IsU8OrI8
2330
{}
@@ -33,7 +40,7 @@ const _: () = {
3340
fn is_u8_or_i8<T>() where
3441
T : IsU8OrI8,
3542
{}
36-
let _ = is_u8_or_i8::<::libc::c_char>;
43+
let _ = is_u8_or_i8::<crate::libc::c_char>;
3744
};
3845
};
3946

src/layout/impls.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,14 @@ unsafe
913913
}
914914
from_CType_impl_ReprC! { Bool }
915915

916+
/// A `ReprC` _standalone_ type with the same layout and ABI as
917+
/// [`::libc::c_int`][crate::libc::c_int].
918+
///
919+
/// By _standalone_, the idea is that this is defined as a (`transparent`) _newtype_ `struct`,
920+
/// rather than as a _`type` alias_, which is error-prone and yields less-portable headers (since
921+
/// the header generation will resolve the type alias and emit, for instance, `int32_t`, ⚠️).
922+
///
923+
/// By using this type, you guarantee that the C `int` type be used in the headers.
916924
#[repr(transparent)]
917925
#[derive(Clone, Copy, PartialEq, Eq)]
918926
pub

src/libc.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#![cfg_attr(rustfmt, rustfmt::skip)]
2+
//! On certain platforms, `::libc` has no definitions for pervasive types such as `size_t`.
3+
//!
4+
//! We polyfill them here, and reëxport them for downstream users to use at leisure
5+
//! (_e.g._, so that they don't have to do that themselves too!).
6+
//!
7+
//! ```rust
8+
//! # #[cfg(any())] macro_rules! ignore {
9+
#![doc = stringified_module_code!()]
10+
//! # }
11+
#![allow(warnings, clippy::all)]
12+
13+
use_libc_or_else! {
14+
pub use ::libc::{
15+
/// Note: your should probably be using [`crate::c_char`] instead.
16+
c_char else u8,
17+
/// Note: your should probably be using [`crate::c_int`] instead.
18+
c_int else ::core::ffi::c_int,
19+
///
20+
size_t else usize,
21+
///
22+
uintptr_t else usize,
23+
};
24+
}
25+
26+
macro_rules! use_libc_or_else_ {(
27+
pub use ::libc::{
28+
$(
29+
$(#$doc:tt)*
30+
$c_type:ident else $FallbackTy:ty
31+
),* $(,)?
32+
};
33+
) => (
34+
35+
$(
36+
#[doc = concat!("A _`type` alias_ to [`::libc::", stringify!($c_type), "`].")]
37+
///
38+
$(#$doc)*
39+
pub type $c_type = helper::$c_type;
40+
)*
41+
42+
mod helper {
43+
mod real_libc {
44+
pub use ::libc::*;
45+
$(
46+
pub const $c_type: () = ();
47+
)*
48+
}
49+
50+
pub use real_libc::{
51+
$(
52+
$c_type,
53+
)*
54+
};
55+
56+
pub use fallback::*;
57+
mod fallback {
58+
$(
59+
pub type $c_type = $FallbackTy;
60+
)*
61+
}
62+
}
63+
)} use use_libc_or_else_;
64+
65+
macro_rules! use_libc_or_else {(
66+
$($input:tt)*
67+
) => (
68+
macro_rules! stringified_module_code {() => (
69+
stringify!($($input)*)
70+
)}
71+
72+
use_libc_or_else_!($($input)*);
73+
)} use use_libc_or_else;

src/proc_macro/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ proc-macro = true
44

55
[package]
66
name = "safer_ffi-proc_macros"
7-
version = "0.1.1" # Keep in sync
7+
version = "0.1.2" # Keep in sync
88
authors = ["Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>"]
99
edition = "2021"
1010

src/utils/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ cfg_match! {
2727
pub(in crate) type size_t = u32;
2828
},
2929
_ => {
30-
pub(in crate) use ::libc::size_t;
30+
pub(in crate) use crate::libc::size_t;
3131
},
3232
}
3333

0 commit comments

Comments
 (0)