diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 51751bb2ac64f..63779472de106 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -98,8 +98,10 @@ jobs: run: | set -eux if [ "${{ matrix.toolchain }}" = "1.65.0" ]; then - # Remove `-Dwarnings` at the MSRV since lints may be different - export RUSTFLAGS="" + # Remove `-Dwarnings` at the MSRV since lints may be different, and allow + # `improper_ctypes` since pointers to ZSTs got the warning prior to 1.72. + # FIXME(msrv): remove this flag when possible. + export RUSTFLAGS="-Aimproper_ctypes" # Remove `ctest` which uses the 2024 edition perl -i -ne 'print unless /"ctest(-test)?",/ || /"libc-test",/' Cargo.toml fi diff --git a/ci/style.py b/ci/style.py index fcbee07dac17c..9a88ea5b18e16 100755 --- a/ci/style.py +++ b/ci/style.py @@ -9,7 +9,6 @@ from glob import iglob from pathlib import Path - FMT_DIRS = ["src", "ci"] IGNORE_FILES = [ # Too much special syntax that we don't want to format @@ -87,6 +86,9 @@ def fmt_one(fpath: Path, check_only: bool): # syntax. Replace it with a dummy name. text = re.sub(r"enum #anon\b", r"enum _fmt_anon", text) + # `extern_ty!` can be formatted as an extern block. + text = re.sub(r"extern_ty!", r'extern "extern-ty-macro"', text) + # If enum variants are annotated with `pub`, rustfmt erases the visibility. To get # around this we first match on all enums to extract their bodies, then look for `pub` # visibility indicators. If found, these get stashed in a comment on the preceding @@ -126,6 +128,7 @@ def enum_sub(m: re.Match) -> str: text = re.sub(r"cfg_tmp!\(\[(.*?)\]\)", r"#[cfg(\1)]", text, flags=re.DOTALL) text = re.sub(r"enum _fmt_anon", r"enum #anon", text) text = re.sub(r"/\* FMT-VIS (.*) END-FMT-VIS \*/\n\s*", r"\1 ", text) + text = re.sub(r'extern "extern-ty-macro"', r"extern_ty!", text) # And write the formatted file back fpath.write_text(text) diff --git a/src/fuchsia/mod.rs b/src/fuchsia/mod.rs index cb40463b5503f..02ad0e31a0fc1 100644 --- a/src/fuchsia/mod.rs +++ b/src/fuchsia/mod.rs @@ -79,9 +79,9 @@ pub type fsfilcnt_t = c_ulonglong; pub type rlim_t = c_ulonglong; extern_ty! { - pub enum timezone {} - pub enum DIR {} - pub enum fpos64_t {} // FIXME(fuchsia): fill this out with a struct + pub type timezone; + pub type DIR; + pub type fpos64_t; // FIXME(fuchsia): fill this out with a struct } // PUB_STRUCT @@ -3192,8 +3192,8 @@ fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar { extern "C" {} extern_ty! { - pub enum FILE {} - pub enum fpos_t {} // FIXME(fuchsia): fill this out with a struct + pub type FILE; + pub type fpos_t; // FIXME(fuchsia): fill this out with a struct } extern "C" { diff --git a/src/macros.rs b/src/macros.rs index 0149b1fd18466..2de4348bd29e6 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -246,9 +246,25 @@ macro_rules! s_no_extra_traits { macro_rules! extern_ty { ($( $(#[$attr:meta])* - pub enum $i:ident {} + pub type $i:ident; )*) => ($( $(#[$attr])* + /// This is an extern type ("opaque" or "incomplete" type in C). + /// + ///
+ /// This type's current representation allows inspecting some properties, such as via + /// size_of, and it is technically possible to construct the type within + /// MaybeUninit, However, this MUST NOT be relied upon + /// because a future version of libc may switch to a proper + /// extern type + /// representation when available. + ///
+ // ^ unfortunately warning blocks currently don't render markdown so we need to + // use raw HTML. + // + // Representation based on the Nomicon: + // . + // // FIXME(1.0): the type is uninhabited so these traits are unreachable and could be // removed. #[::core::prelude::v1::derive( @@ -256,7 +272,11 @@ macro_rules! extern_ty { ::core::marker::Copy, ::core::fmt::Debug, )] - pub enum $i { } + #[repr(C)] + pub struct $i { + _data: (), + _marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>, + } )*); } diff --git a/src/new/qurt/mod.rs b/src/new/qurt/mod.rs index 52d7ae04881e1..a9ad85e67a79a 100644 --- a/src/new/qurt/mod.rs +++ b/src/new/qurt/mod.rs @@ -60,7 +60,7 @@ pub type fd_set = c_ulong; // Standard C library types extern_ty! { - pub enum FILE {} + pub type FILE; } pub type fpos_t = c_long; pub type clock_t = c_long; diff --git a/src/solid/mod.rs b/src/solid/mod.rs index 0182f8150df67..4aec2bf90b65f 100644 --- a/src/solid/mod.rs +++ b/src/solid/mod.rs @@ -397,8 +397,8 @@ pub const SIGUSR2: c_int = 31; pub const SIGPWR: c_int = 32; extern_ty! { - pub enum FILE {} - pub enum fpos_t {} + pub type FILE; + pub type fpos_t; } extern "C" { diff --git a/src/unix/aix/powerpc64.rs b/src/unix/aix/powerpc64.rs index 0862cbf854d3c..cd439044d196f 100644 --- a/src/unix/aix/powerpc64.rs +++ b/src/unix/aix/powerpc64.rs @@ -3,7 +3,7 @@ use crate::prelude::*; // Define lock_data_instrumented as an empty enum extern_ty! { - pub enum lock_data_instrumented {} + pub type lock_data_instrumented; } s! { diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs index fceea8869cbfd..e8352e5806c47 100644 --- a/src/unix/bsd/apple/mod.rs +++ b/src/unix/bsd/apple/mod.rs @@ -176,7 +176,7 @@ pub type attrgroup_t = u32; pub type vol_capabilities_set_t = [u32; 4]; extern_ty! { - pub enum timezone {} + pub type timezone; } c_enum! { diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index 0283bd4afb4a9..481d910a16d35 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -49,7 +49,7 @@ pub type vm_map_entry_t = *mut vm_map_entry; pub type pmap = __c_anonymous_pmap; extern_ty! { - pub enum sem {} + pub type sem; } c_enum! { diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index 0c93d2edc2f4b..81f805ab1bbe1 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -60,7 +60,7 @@ cfg_if! { // link.h extern_ty! { - pub enum timezone {} + pub type timezone; } impl siginfo_t { diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs index e4d4e68ad1fb7..27db17736ea33 100644 --- a/src/unix/bsd/netbsdlike/mod.rs +++ b/src/unix/bsd/netbsdlike/mod.rs @@ -17,8 +17,8 @@ pub type sem_t = *mut sem; pub type key_t = c_long; extern_ty! { - pub enum timezone {} - pub enum sem {} + pub type timezone; + pub type sem; } s! { diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index 803cebab79df3..b1733db0948d2 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -45,7 +45,7 @@ c_enum! { } extern_ty! { - pub enum _cpuset {} + pub type _cpuset; } cfg_if! { diff --git a/src/unix/cygwin/mod.rs b/src/unix/cygwin/mod.rs index e190e18f4cd63..5968b37672c3a 100644 --- a/src/unix/cygwin/mod.rs +++ b/src/unix/cygwin/mod.rs @@ -29,7 +29,7 @@ pub type suseconds_t = c_long; pub type useconds_t = c_ulong; extern_ty! { - pub enum timezone {} + pub type timezone; } pub type sigset_t = c_ulong; @@ -71,7 +71,7 @@ pub type nfds_t = c_uint; pub type sem_t = *mut sem; extern_ty! { - pub enum sem {} + pub type sem; } pub type tcflag_t = c_uint; diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs index c5236ce3ee48e..15b943a63ee3c 100644 --- a/src/unix/haiku/mod.rs +++ b/src/unix/haiku/mod.rs @@ -81,7 +81,7 @@ pub type posix_spawnattr_t = *mut c_void; pub type posix_spawn_file_actions_t = *mut c_void; extern_ty! { - pub enum timezone {} + pub type timezone; } impl siginfo_t { diff --git a/src/unix/hurd/mod.rs b/src/unix/hurd/mod.rs index c96378f410ba8..84e3410264c02 100644 --- a/src/unix/hurd/mod.rs +++ b/src/unix/hurd/mod.rs @@ -226,8 +226,8 @@ pub type nl_item = c_int; pub type iconv_t = *mut c_void; extern_ty! { - pub enum fpos64_t {} // FIXME(hurd): fill this out with a struct - pub enum timezone {} + pub type fpos64_t; // FIXME(hurd): fill this out with a struct + pub type timezone; } // structs diff --git a/src/unix/linux_like/emscripten/mod.rs b/src/unix/linux_like/emscripten/mod.rs index 711ed8f8b4c37..e60cf7ea2cc9f 100644 --- a/src/unix/linux_like/emscripten/mod.rs +++ b/src/unix/linux_like/emscripten/mod.rs @@ -41,7 +41,7 @@ pub type statvfs64 = crate::statvfs; pub type dirent64 = crate::dirent; extern_ty! { - pub enum fpos64_t {} // FIXME(emscripten): fill this out with a struct + pub type fpos64_t; // FIXME(emscripten): fill this out with a struct } s! { diff --git a/src/unix/linux_like/linux_l4re_shared.rs b/src/unix/linux_like/linux_l4re_shared.rs index d91240a058583..cb277fe5ac770 100644 --- a/src/unix/linux_like/linux_l4re_shared.rs +++ b/src/unix/linux_like/linux_l4re_shared.rs @@ -35,7 +35,7 @@ pub type iconv_t = *mut c_void; cfg_if! { if #[cfg(not(target_env = "gnu"))] { extern_ty! { - pub enum fpos64_t {} // FIXME(linux): fill this out with a struct + pub type fpos64_t; // FIXME(linux): fill this out with a struct } } } diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs index 30bad55e032f8..7347c27fcad41 100644 --- a/src/unix/linux_like/mod.rs +++ b/src/unix/linux_like/mod.rs @@ -10,7 +10,7 @@ pub type key_t = c_int; pub type id_t = c_uint; extern_ty! { - pub enum timezone {} + pub type timezone; } s! { diff --git a/src/unix/mod.rs b/src/unix/mod.rs index 79c3ef8be2220..d342702c95758 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -38,7 +38,7 @@ cfg_if! { } extern_ty! { - pub enum DIR {} + pub type DIR; } #[cfg(not(target_os = "nuttx"))] @@ -602,13 +602,13 @@ cfg_if! { cfg_if! { if #[cfg(not(all(target_os = "linux", target_env = "gnu")))] { extern_ty! { - pub enum fpos_t {} // FIXME(unix): fill this out with a struct + pub type fpos_t; // FIXME(unix): fill this out with a struct } } } extern_ty! { - pub enum FILE {} + pub type FILE; } extern "C" { diff --git a/src/unix/nto/mod.rs b/src/unix/nto/mod.rs index 1df869445d41d..68f6af4f6881f 100644 --- a/src/unix/nto/mod.rs +++ b/src/unix/nto/mod.rs @@ -73,7 +73,7 @@ pub type sem_t = sync_t; pub type nl_item = c_int; extern_ty! { - pub enum timezone {} + pub type timezone; } s! { diff --git a/src/unix/redox/mod.rs b/src/unix/redox/mod.rs index 5fea6b3937fbf..fdc42c18856df 100644 --- a/src/unix/redox/mod.rs +++ b/src/unix/redox/mod.rs @@ -32,7 +32,7 @@ pub type uid_t = c_int; pub type gid_t = c_int; extern_ty! { - pub enum timezone {} + pub type timezone; } s! { diff --git a/src/unix/solarish/mod.rs b/src/unix/solarish/mod.rs index 963246732c437..fc60a724a1204 100644 --- a/src/unix/solarish/mod.rs +++ b/src/unix/solarish/mod.rs @@ -56,8 +56,8 @@ pub type posix_spawnattr_t = *mut c_void; pub type posix_spawn_file_actions_t = *mut c_void; extern_ty! { - pub enum timezone {} - pub enum ucred_t {} + pub type timezone; + pub type ucred_t; } s! { diff --git a/src/vxworks/mod.rs b/src/vxworks/mod.rs index 00428543d7aff..453fe1cdefb87 100644 --- a/src/vxworks/mod.rs +++ b/src/vxworks/mod.rs @@ -5,7 +5,7 @@ use core::ptr::null_mut; use crate::prelude::*; extern_ty! { - pub enum DIR {} + pub type DIR; } pub type intmax_t = i64; @@ -95,7 +95,7 @@ pub type sa_family_t = c_uchar; pub type mqd_t = c_int; extern_ty! { - pub enum _Vx_semaphore {} + pub type _Vx_semaphore; } impl siginfo_t { @@ -1435,8 +1435,8 @@ pub const TIOCGWINSZ: c_int = 0x1740087468; pub const TIOCSWINSZ: c_int = -0x7ff78b99; extern_ty! { - pub enum FILE {} - pub enum fpos_t {} // FIXME(vxworks): fill this out with a struct + pub type FILE; + pub type fpos_t; // FIXME(vxworks): fill this out with a struct } f! { diff --git a/src/wasi/mod.rs b/src/wasi/mod.rs index 9d08e612e6191..bd953934373cd 100644 --- a/src/wasi/mod.rs +++ b/src/wasi/mod.rs @@ -45,15 +45,11 @@ s_no_extra_traits! { } } -#[allow(missing_copy_implementations)] -#[derive(Debug)] -pub enum FILE {} -#[allow(missing_copy_implementations)] -#[derive(Debug)] -pub enum DIR {} -#[allow(missing_copy_implementations)] -#[derive(Debug)] -pub enum __locale_struct {} +extern_ty! { + pub type FILE; + pub type DIR; + pub type __locale_struct; +} s_paren! { // in wasi-libc clockid_t is const struct __clockid* (where __clockid is an opaque struct), diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 9bb3bcdaa9fe2..03fc95bf9c43b 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -31,7 +31,7 @@ pub type dev_t = u32; pub type ino_t = u16; extern_ty! { - pub enum timezone {} + pub type timezone; } pub type time64_t = i64; @@ -246,8 +246,8 @@ pub const L_tmpnam: c_uint = 260; pub const TMP_MAX: c_uint = 0x7fff_ffff; extern_ty! { - pub enum FILE {} - pub enum fpos_t {} // FIXME(windows): fill this out with a struct + pub type FILE; + pub type fpos_t; // FIXME(windows): fill this out with a struct } // Special handling for all print and scan type functions because of https://github.com/rust-lang/libc/issues/2860