safer_ffi/layout/_mod.rs
1//! Trait abstractions describing the semantics of "being `#[repr(C)]`"
2
3use_prelude!();
4
5pub(crate) mod macros;
6
7#[doc(inline)]
8pub use crate::CType;
9#[doc(inline)]
10pub use crate::ReprC;
11pub use crate::derive_ReprC;
12#[doc(inline)]
13pub use crate::from_CType_impl_ReprC;
14
15type_level_enum! {
16 pub
17 enum OpaqueKind {
18 Concrete,
19 Opaque,
20 }
21}
22
23/// One of the two core traits of this crate (with [`ReprC`][`trait@ReprC`]).
24///
25/// `CType` is an `unsafe` trait that binds a Rust type to a C typedef.
26///
27/// To optimise compile-times, the C typedef part is gated behind the `headers`
28/// cargo feature, so when that feature is not enabled, the trait may "look"
29/// like a marker trait, but it isn't.
30///
31/// That's why **manually implementing this trait is strongly discouraged**,
32/// although not forbidden:
33///
34/// - If you trully want a manual implementation of `CType` (_e.g._, for an "opaque type" pattern,
35/// _i.e._, a forward declaration), then, to implement the trait so that it works no matter the
36/// status of the `safer_ffi/headers` feature, one must define the methods as if feature was
37/// present, but with a `#[::safer_ffi::cfg_headers]` gate slapped on _each_ method.
38///
39/// # Safety
40///
41/// The Rust type in an `extern "C"` function must have the same layout and ABI
42/// as the defined C type, and all the bit-patterns representing any instance
43/// of such C type must be valid and safe bit-patterns for the Rust type.
44///
45/// For the most common types, there are only two reasons to correctly be a
46/// `CType`:
47///
48/// - being a primitive type, such as an integer type or a (slim) pointer.
49///
50/// - This crates provides as many of these implementations as possible.
51///
52/// - and recursively, a non-zero-sized `#[repr(C)]` struct of `CType` fields.
53///
54/// - the [`CType!`] macro can be used to wrap a `#[repr(C)]` struct definition to _safely_
55/// and automagically implement the trait when it is sound to do so.
56///
57/// Note that types such as Rust's [`bool`] are ruled out by this definition,
58/// since it has the ABI of a `u8 <-> uint8_t`, and yet there are many
59/// bit-patterns for the `uint8_t` type that do not make _valid_ `bool`s.
60///
61/// For such types, see the [`ReprC`][`trait@ReprC`] trait.
62///
63/// Safety (non-exhaustive list at the moment):
64/// - `::core::mem::zeroed::<Self>()` must be sound to use.
65pub unsafe trait CType: Sized + Copy {
66 type OPAQUE_KIND: OpaqueKind::T;
67
68 fn zeroed() -> Self {
69 unsafe { ::core::mem::zeroed() }
70 }
71
72 #[apply(__cfg_headers__!)]
73 /// Necessary one-time code for [`CType::name()`] to make sense.
74 ///
75 /// Some types, such as `char`, are part of the language, and can be
76 /// used directly by [`CType::name()`].
77 /// In that case, there is nothing else to _define_, and all is fine.
78 ///
79 /// - That is the default implementation of this method: doing nothing.
80 ///
81 /// But most often than not, a `typedef` or an `#include` is required.
82 ///
83 /// In that case, here is the place to put it, with the help of the
84 /// provided `Definer`.
85 ///
86 /// # Idempotency?
87 ///
88 /// Given some `definer: &mut dyn Definer`, **the `define_self__impl(definer)`
89 /// call is not to be called more than once, thanks to the convenience
90 /// method [`Self::define_self()`], which is the one to guarantee idempotency**
91 /// (thanks to the [`Definer`]'s [`.define_once()`][`Definer::define_once()`] helper).
92 ///
93 /// # Safety
94 ///
95 /// Given that the defined types may be used by [`CType::name_wrapping_var()`],
96 /// and [`CType::name()`], the same safety disclaimers apply.
97 ///
98 /// ## Examples
99 ///
100 /// ### `#[repr(C)] struct Foo { x: i32 }`
101 ///
102 /// ```rust
103 /// use ::safer_ffi::headers::Definer;
104 /// use ::safer_ffi::headers::languages::HeaderLanguage;
105 /// use ::safer_ffi::layout::CType;
106 /// use ::safer_ffi::layout::OpaqueKind;
107 /// use ::std::io;
108 /// use ::std::marker::PhantomData;
109 ///
110 /// #[derive(Clone, Copy)]
111 /// #[repr(C)]
112 /// struct Foo {
113 /// x: i32,
114 /// }
115 ///
116 /// unsafe impl CType for Foo {
117 /// #[::safer_ffi::cfg_headers]
118 /// fn define_self__impl(
119 /// language: &'_ dyn HeaderLanguage,
120 /// definer: &'_ mut dyn Definer,
121 /// ) -> io::Result<()> {
122 /// // ensure int32_t makes sense
123 /// <i32 as CType>::define_self(language, definer)?;
124 /// language.declare_struct(
125 /// language,
126 /// definer,
127 /// // no docs.
128 /// &[],
129 /// &PhantomData::<Self>,
130 /// &[::safer_ffi::headers::languages::StructField {
131 /// docs: &[],
132 /// name: "x",
133 /// ty: &PhantomData::<i32>,
134 /// }],
135 /// )?;
136 /// Ok(())
137 /// }
138 ///
139 /// #[::safer_ffi::cfg_headers]
140 /// fn short_name() -> String {
141 /// "Foo".into()
142 /// }
143 ///
144 /// type OPAQUE_KIND = OpaqueKind::Concrete;
145 ///
146 /// // ...
147 /// }
148 /// ```
149 #[allow(nonstandard_style)]
150 fn define_self__impl(
151 language: &'_ dyn HeaderLanguage,
152 definer: &'_ mut dyn Definer,
153 ) -> io::Result<()>;
154
155 #[apply(__cfg_headers__!)]
156 fn define_self(
157 language: &'_ dyn HeaderLanguage,
158 definer: &'_ mut dyn Definer,
159 ) -> io::Result<()> {
160 definer.define_once(
161 &F(|out| Self::render(out, language)).to_string(),
162 &mut |definer| Self::define_self__impl(language, definer),
163 )
164 }
165
166 #[apply(__cfg_headers__!)]
167 /// A short-name description of the type, mainly used to fill
168 /// "placeholders" such as when monomorphising generics structs or
169 /// arrays.
170 ///
171 /// This provides the implementation used by [`CType::short_name`]`()`.
172 ///
173 /// There are no bad implementations of this method, except,
174 /// of course, for the obligation to provide a valid identifier chunk,
175 /// _i.e._, the output must only contain alphanumeric digits and
176 /// underscores.
177 ///
178 /// For instance, given `T : CType` and `const N: usize > 0`, the type
179 /// `[T; N]` (inline fixed-size array of `N` consecutive elements of
180 /// type `T`) will be typedef-named as:
181 ///
182 /// ```rust,ignore
183 /// write!(fmt, "{}_{}_array", <T as CType>::short_name(), N)
184 /// ```
185 ///
186 /// Generally, typedefs with a trailing `_t` will see that `_t` trimmed
187 /// when used as a `short_name`.
188 ///
189 /// ## Implementation by [`CType!`]:
190 ///
191 /// A non generic struct such as:
192 ///
193 /// ```rust,ignore
194 /// CType! {
195 /// #[repr(C)]
196 /// struct Foo { /* fields */ }
197 /// }
198 /// ```
199 ///
200 /// will have `Foo` as its `short_name`.
201 ///
202 /// A generic struct such as:
203 ///
204 /// ```rust,ignore
205 /// CType! {
206 /// #[repr(C)]
207 /// struct Foo[T] where { T : CType } { /* fields */ }
208 /// }
209 /// ```
210 ///
211 /// will have `Foo_xxx` as its `short_name`, with `xxx` being `T`'s
212 /// `short_name`.
213 fn short_name() -> String;
214
215 /// Display itself as header code which refers to this C type.
216 ///
217 /// This can be:
218 ///
219 /// - either through some direct syntactical construct derived off some other stuff, e.g., in
220 /// C, `{} const*` for the `*const T` case,
221 ///
222 /// - or simply by given a simple/single identifier name from a helper type alias or type
223 /// definition having occurred in `define_self` (common case).
224 ///
225 /// In this case, the name is probably going to be equal to `Self::short_name() + "_t"`.
226 ///
227 /// **The default implementation does this.**
228 #[apply(__cfg_headers__!)]
229 fn render(
230 out: &'_ mut dyn io::Write,
231 _language: &'_ dyn HeaderLanguage,
232 ) -> io::Result<()> {
233 write!(out, "{}_t", Self::short_name())
234 }
235
236 /// Convenience directly-`String`-outputting version of [`Self::render()`].
237 #[apply(__cfg_headers__!)]
238 fn name(language: &dyn HeaderLanguage) -> String {
239 F(|out| Self::render(out, language)).to_string()
240 }
241
242 /// Same as [`Self::render()`], but for "appending the varname/fn-name after it, with
243 /// whitespace.
244 ///
245 /// This, on its own would be a silly thing for which to dedicate a whole function.
246 ///
247 /// However, C being how it is, in the non-simple/single-typename ident cases for
248 /// `Self::render()`, mainly and most notably, in the array and `fn` pointer cases, the
249 /// varname/fn-name does not just go after the whole type.
250 ///
251 /// Instead, **it has to be interspersed in the middle of the type**.
252 ///
253 /// For instance, in the `fn(c_int) -> u8` case, it would have to be:
254 ///
255 /// > `uint8_t (*{var_name})(int)`.
256 ///
257 /// So such cases need to override the default implementation here, do the right thing, and then
258 /// override the other simpler non-`wrapping_var` versions thereof, to delegate to this function
259 /// with `var_name = ""`.
260 ///
261 /// > ⚠️ **NOTE**: when overriding this default impl, remember to `Self::render()` as
262 /// `Self::render_wrapping_var(…, "")`.
263 ///
264 /// ---
265 ///
266 /// Default implementation is to simply emit `{self.render()}{sep}{var_name}`, in pseudo-code
267 /// parlance.
268 #[apply(__cfg_headers__!)]
269 fn render_wrapping_var(
270 out: &'_ mut dyn io::Write,
271 language: &'_ dyn HeaderLanguage,
272 // Either a `&&str`, or a `&fmt::Arguments<'_>`, for instance.
273 var_name: Option<&dyn ::core::fmt::Display>,
274 ) -> io::Result<()> {
275 write!(
276 out,
277 "{}{sep}{var_name}",
278 F(|out| Self::render(out, language)),
279 sep = var_name.sep(),
280 var_name = var_name.or_empty(),
281 )?;
282 Ok(())
283 }
284
285 #[apply(__cfg_headers__!)]
286 /// The core method of the trait: it provides the code to emit in the target
287 /// [`HeaderLanguage`] in order to refer to the corresponding C type.
288 ///
289 /// The implementations are thus much like any classic `.to_string()` impl,
290 /// except that:
291 ///
292 /// - it must output valid C code representing the type corresponding to the Rust type.
293 ///
294 /// - a `var_name` may be supplied, in which case the type must use that as its "variable
295 /// name" (C being how it is, the var name may need to be inserted in the middle of the
296 /// types, such as with arrays and function pointers).
297 ///
298 /// # Safety
299 ///
300 /// Here is where the meat of the safety happens: associating a Rust
301 /// type to a non-corresponding C definition will cause Undefined
302 /// Behavior when a function using such type in its ABI is called.
303 ///
304 /// ## Examples
305 ///
306 /// #### `i32`
307 ///
308 /// ```rust ,ignore
309 /// # #[repr(transparent)] struct i32(::core::primitive::i32);
310 ///
311 /// use ::safer_ffi::{headers::languages::HeaderLanguage, layout::CType};
312 ///
313 /// unsafe impl CType for i32 {
314 /// #[::safer_ffi::cfg_headers]
315 /// fn name_wrapping_var (
316 /// header_language: &dyn HeaderLanguage,
317 /// var_name: Option<&dyn ::core::fmt::Display>,
318 /// ) -> String
319 /// {
320 /// // Usually this kind of logic for primitive types is
321 /// // provided by the `HeaderLanguage` itself, rather than hard-coded by the type…
322 /// assert_eq!(header_language.language_name(), "C");
323 ///
324 /// let sep = if var_name { " " } else { "" };
325 /// format!("int32_t{sep}{var_name}")
326 /// }
327 ///
328 /// // ...
329 /// }
330 /// ```
331 fn name_wrapping_var(
332 language: &'_ dyn HeaderLanguage,
333 var_name: Option<&dyn ::core::fmt::Display>,
334 ) -> String {
335 F(|out| Self::render_wrapping_var(out, language, var_name)).to_string()
336 }
337
338 #[apply(__cfg_headers__!)]
339 /// Optional language-specific metadata attached to the type (_e.g._,
340 /// some `[MarshalAs(UnmanagedType.FunctionPtr)]` annotation for C#).
341 ///
342 /// To be done using:
343 ///
344 /// <code>\&[provide_with]\(|req| req.give_if_requested::\<[CSharpMarshaler]\>(…))</code>
345 ///
346 /// [CSharpMarshaler]: `crate::headers::languages::CSharpMarshaler`
347 fn metadata() -> &'static dyn Provider {
348 &None
349 }
350}
351
352/// The meat of the crate. _The_ trait.
353///
354/// This trait describes that **a type has a defined / fixed `#[repr(C)]`
355/// layout**.
356///
357/// This is expressed at the type level by the `unsafe` (trait) type
358/// association of `ReprC::CLayout`, which must be a [`CType`][`trait@CType`].
359///
360/// Because of that property, the type may be used in the API of an
361/// `#[ffi_export]`-ed function, where ABI-wise it will be replaced by its
362/// equivalent [C layout][`ReprC::CLayout`].
363///
364/// Then, `#[ffi_export]` will transmute the `CType` parameters back to the
365/// provided `ReprC` types, using [`from_raw_unchecked`].
366///
367/// Although, from a pure point of view, no checks are performed at this step
368/// whatsoever, in practice, when `debug_assertions` are enabled, some "sanity
369/// checks" are performed on the input parameters: [`ReprC::is_valid`] is
370/// called in that case (as part of the implementation of [`from_raw`]).
371///
372/// - Although that may look innocent, it is actually pretty powerful tool:
373///
374/// **For instance, a non-null pointer coming from C can, this way, be
375/// automatically checked and unwrapped, and the same applies for
376/// enumerations having a finite number of valid bit-patterns.**
377///
378/// # Safety
379///
380/// It must be sound to transmute from a `ReprC::CLayout` instance when the
381/// bit pattern represents a _safe_ instance of `Self`.
382///
383/// # Implementing `ReprC`
384///
385/// It is generally recommended to avoid manually (and `unsafe`-ly)
386/// implementing the [`ReprC`] trait. Instead, the recommended and blessed way
387/// is to use the [`#[derive_ReprC]`](/safer_ffi/layout/attr.derive_ReprC.html)
388/// attribute on your `#[repr(C)] struct` (or your field-less
389/// `#[repr(<integer>)] enum`).
390///
391/// [`ReprC`]: `trait@ReprC`
392///
393/// ## Examples
394///
395/// #### Simple `struct`
396///
397/// ```rust,no_run
398/// # fn main () {}
399/// use ::safer_ffi::prelude::*;
400///
401/// #[derive_ReprC]
402/// #[repr(C)]
403/// struct Instant {
404/// seconds: u64,
405/// nanos: u32,
406/// }
407/// ```
408///
409/// - corresponding to the following C definition:
410///
411/// ```C
412/// typedef struct {
413/// uint64_t seconds;
414/// uint32_t nanos;
415/// } Instant_t;
416/// ```
417///
418/// #### Field-less `enum`
419///
420/// ```rust,no_run
421/// # fn main () {}
422/// use ::safer_ffi::prelude::*;
423///
424/// #[derive_ReprC]
425/// #[repr(u8)]
426/// enum Status {
427/// Ok = 0,
428/// Busy,
429/// NotInTheMood,
430/// OnStrike,
431/// OhNo,
432/// }
433/// ```
434///
435/// - corresponding to the following C definition:
436///
437/// ```C
438/// typedef uint8_t Status_t; enum {
439/// STATUS_OK = 0,
440/// STATUS_BUSY,
441/// STATUS_NOT_IN_THE_MOOD,
442/// STATUS_ON_STRIKE,
443/// STATUS_OH_NO,
444/// }
445/// ```
446///
447/// #### Generic `struct`
448///
449/// ```rust,no_run
450/// # fn main () {}
451/// use ::safer_ffi::prelude::*;
452///
453/// #[derive_ReprC]
454/// #[repr(C)]
455/// struct Point<Coordinate: ReprC> {
456/// x: Coordinate,
457/// y: Coordinate,
458/// }
459/// ```
460///
461/// Each monomorphization leads to its own C definition:
462///
463/// - **`Point<i32>`**
464///
465/// ```C
466/// typedef struct {
467/// int32_t x;
468/// int32_t y;
469/// } Point_int32_t;
470/// ```
471///
472/// - **`Point<f64>`**
473///
474/// ```C
475/// typedef struct {
476/// double x;
477/// double y;
478/// } Point_double_t;
479/// ```
480pub unsafe trait ReprC: Sized {
481 /// The `CType` having the same layout as `Self`.
482 type CLayout: CType;
483
484 /// Sanity checks that can be performed on an instance of the `CType`
485 /// layout.
486 ///
487 /// Such checks are performed when calling [`from_raw`], or equivalently
488 /// (⚠️ only with `debug_assertions` enabled ⚠️), [`from_raw_unchecked`].
489 ///
490 /// Implementation-wise, this function is only a "sanity check" step:
491 ///
492 /// - It is valid (although rather pointless) for this function to always return `true`, even
493 /// if the input may be `unsafe` to transmute to `Self`, or even be an _invalid_ value of
494 /// type `Self`.
495 ///
496 /// - In the other direction, it is not unsound, although it would be a logic error, to always
497 /// return `false`.
498 ///
499 /// - This is because it is impossible to have a function that for any type is able to tell if
500 /// a given bit pattern is a safe value of that type.
501 ///
502 /// In practice, if this function returns `false`, then such result must be
503 /// trusted, _i.e._, transmuting such instance to the `Self` type will,
504 /// at the very least, break a _safety_ invariant, and it will even most
505 /// probably break a _validity_ invariant.
506 ///
507 /// On the other hand, if the function returns `true`, then the result is
508 /// inconclusive; there is no explicit reason to stop going on, but that
509 /// doesn't necessarily make it sound.
510 ///
511 /// # TL,DR
512 ///
513 /// > This function **may yield false positives** but no false negatives.
514 ///
515 /// ## Example: `Self = &'borrow i32`
516 ///
517 /// When `Self = &'borrow i32`, we know that the backing pointer is
518 /// necessarily non-null and well-aligned.
519 ///
520 /// This means that bit-patterns such as `0 as *const i32` or
521 /// `37 as *const i32` are "blatantly unsound" to transmute to a
522 /// `&'borrow i32`, and thus `<&'borrow i32 as ReprC>::is_valid` will
523 /// return `false` in such cases.
524 ///
525 /// But if given `4 as *const i32`, or if given `{ let p = &*Box::new(42)
526 /// as *const i32; p }`, then `is_valid` will return `true` in both cases,
527 /// since it doesn't know better.
528 ///
529 /// ## Example: `bool` or `#[repr(u8)] enum Foo { A, B }`
530 ///
531 /// In the case of `bool`, or in the case of a `#[repr(<integer>)]`
532 /// field-less enum, then the valid bit-patterns and the invalid
533 /// bit-patterns are all known and finite.
534 ///
535 /// In that case, `ReprC::is_valid` will return a `bool` that truly
536 /// represents the validity of the bit-pattern, in both directions
537 ///
538 /// - _i.e._, no false positives (_validity_-wise);
539 ///
540 /// Still, there may be _safety_ invariants involved with custom types,
541 /// so even then it is unclear.
542 fn is_valid(it: &'_ Self::CLayout) -> bool;
543}
544
545pub type CLayoutOf<ImplReprC> = <ImplReprC as ReprC>::CLayout;
546
547#[doc(hidden)] /** For clarity;
548 this macro may be stabilized
549 if downstream users find it useful
550 **/
551#[macro_export]
552#[cfg_attr(rustfmt, rustfmt::skip)]
553macro_rules! from_CType_impl_ReprC {(
554 $(@for[$($generics:tt)*])? $T:ty $(where $($bounds:tt)*)?
555) => (
556 unsafe
557 impl$(<$($generics)*>)? $crate::layout::ReprC
558 for $T
559 where
560 $($($bounds)*)?
561 {
562 type CLayout = Self;
563
564 #[inline]
565 fn is_valid (_: &'_ Self::CLayout)
566 -> bool
567 {
568 true
569 }
570 }
571)}
572
573#[inline]
574pub unsafe fn from_raw_unchecked<T: ReprC>(c_layout: T::CLayout) -> T {
575 if let Some(it) = unsafe { from_raw::<T>(c_layout) } {
576 it
577 } else {
578 if cfg!(debug_assertions) || cfg!(test) {
579 panic!(
580 "Error: not a valid bit-pattern for the type `{}`",
581 // c_layout,
582 ::core::any::type_name::<T>(),
583 );
584 } else {
585 unsafe { ::core::hint::unreachable_unchecked() }
586 }
587 }
588}
589
590#[deny(unsafe_op_in_unsafe_fn)]
591#[inline]
592pub unsafe fn from_raw<T: ReprC>(c_layout: T::CLayout) -> Option<T> {
593 if <T as ReprC>::is_valid(&c_layout).not() {
594 None
595 } else {
596 Some(unsafe {
597 const_assert! {
598 for [T]
599 [T : ReprC] => [T::CLayout : Copy]
600 }
601 crate::utils::transmute_unchecked(c_layout)
602 })
603 }
604}
605
606#[deny(unsafe_op_in_unsafe_fn)]
607#[inline]
608pub unsafe fn into_raw<T: ReprC>(it: T) -> T::CLayout {
609 unsafe { crate::utils::transmute_unchecked(::core::mem::ManuallyDrop::new(it)) }
610}
611
612pub use impls::Opaque;
613pub(crate) mod impls;
614
615mod niche;
616
617#[apply(hidden_export)]
618use niche::HasNiche as __HasNiche__;
619
620#[apply(hidden_export)]
621trait Is {
622 type EqTo: ?Sized;
623}
624impl<T: ?Sized> Is for T {
625 type EqTo = Self;
626}
627
628/// Alias for `ReprC where Self::CLayout::OPAQUE_KIND = OpaqueKind::Concrete`
629pub trait ConcreteReprC
630where
631 Self: ReprC,
632{
633 type ConcreteCLayout: Is<EqTo = CLayoutOf<Self>> + CType<OPAQUE_KIND = OpaqueKind::Concrete>;
634}
635impl<T: ?Sized> ConcreteReprC for T
636where
637 Self: ReprC,
638 CLayoutOf<Self>: CType<OPAQUE_KIND = OpaqueKind::Concrete>,
639{
640 type ConcreteCLayout = CLayoutOf<Self>;
641}
642
643#[apply(hidden_export)]
644fn __assert_concrete__<T>()
645where
646 T: ConcreteReprC,
647{
648}