libc/types.rs
1//! Platform-agnostic support types.
2
3#[cfg(feature = "extra_traits")]
4use core::hash::Hash;
5use core::mem::MaybeUninit;
6
7use crate::prelude::*;
8
9/// A transparent wrapper over `MaybeUninit<T>` to represent uninitialized padding
10/// while providing `Default`.
11// This is restricted to `Copy` types since that's a loose indicator that zeros is actually
12// a valid bitpattern. There is no technical reason this is required, though, so it could be
13// lifted in the future if it becomes a problem.
14#[allow(unused)]
15#[repr(transparent)]
16#[derive(Clone, Copy)]
17pub(crate) struct Padding<T: Copy>(MaybeUninit<T>);
18
19impl<T: Copy> Default for Padding<T> {
20 fn default() -> Self {
21 Self(MaybeUninit::zeroed())
22 }
23}
24
25impl<T: Copy> Padding<T> {
26 /// Const constructor for uninitialized padding in const contexts.
27 // FIXME: Change this into zeroed() and use MaybeUninit::zeroed()
28 // when we depend on rustc 1.75.0.
29 #[allow(unused)]
30 pub(crate) const fn uninit() -> Self {
31 // We can still safely use uninit here, since padding are is something
32 // that can are not meant to be read or written anyways.
33 Self(MaybeUninit::uninit())
34 }
35}
36
37impl<T: Copy> fmt::Debug for Padding<T> {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 // Taken frmo `MaybeUninit`'s debug implementation
40 // NB: there is no `.pad_fmt` so we can't use a simpler `format_args!("Padding<{..}>").
41 let full_name = core::any::type_name::<Self>();
42 let prefix_len = full_name.find("Padding").unwrap();
43 f.pad(&full_name[prefix_len..])
44 }
45}
46
47/// Do nothing when hashing to ignore the existence of padding fields.
48#[cfg(feature = "extra_traits")]
49impl<T: Copy> Hash for Padding<T> {
50 fn hash<H: hash::Hasher>(&self, _state: &mut H) {}
51}
52
53/// Padding fields are all equal, regardless of what is inside them, so they do not affect anything.
54#[cfg(feature = "extra_traits")]
55impl<T: Copy> PartialEq for Padding<T> {
56 fn eq(&self, _other: &Self) -> bool {
57 true
58 }
59}
60
61/// Mark that `Padding` implements `Eq` so that it can be used in types that implement it.
62#[cfg(feature = "extra_traits")]
63impl<T: Copy> Eq for Padding<T> {}
64
65/// The default repr type used for C style enums in Rust.
66#[cfg(target_env = "msvc")]
67#[allow(unused)]
68pub(crate) type CEnumRepr = c_int;
69#[cfg(not(target_env = "msvc"))]
70#[allow(unused)]
71pub(crate) type CEnumRepr = c_uint;