safer_ffi/layout/_mod.rs
1#![cfg_attr(rustfmt, rustfmt::skip)]
2//! Trait abstractions describing the semantics of "being `#[repr(C)]`"
3
4use_prelude!();
5
6__cfg_headers__! {
7 use crate::headers::{
8 Definer,
9 languages::*,
10 };
11}
12
13pub(in crate)
14mod macros;
15
16#[doc(inline)]
17pub use crate::{from_CType_impl_ReprC, ReprC, CType};
18
19pub use crate::{
20 derive_ReprC,
21};
22
23type_level_enum! {
24 pub
25 enum OpaqueKind {
26 Concrete,
27 Opaque,
28 }
29}
30
31/// Safety (non-exhaustive list at the moment):
32/// - `::core::mem::zeroed::<Self>()` must be sound to use.
33pub
34unsafe
35trait CType
36:
37 Sized +
38 Copy +
39{
40 type OPAQUE_KIND : OpaqueKind::T;
41
42 fn zeroed() -> Self {
43 unsafe {
44 ::core::mem::zeroed()
45 }
46 }
47
48 __cfg_headers__! {
49 fn short_name ()
50 -> String
51 ;
52
53 #[allow(nonstandard_style)]
54 fn define_self__impl (
55 language: &'_ dyn HeaderLanguage,
56 definer: &'_ mut dyn Definer,
57 ) -> io::Result<()>
58 ;
59
60 fn define_self (
61 language: &'_ dyn HeaderLanguage,
62 definer: &'_ mut dyn Definer,
63 ) -> io::Result<()>
64 {
65 definer.define_once(
66 &Self::name(language),
67 &mut |definer| Self::define_self__impl(language, definer),
68 )
69 }
70
71 fn name (
72 _language: &'_ dyn HeaderLanguage,
73 ) -> String
74 {
75 format!("{}_t", Self::short_name())
76 }
77
78 fn name_wrapping_var (
79 language: &'_ dyn HeaderLanguage,
80 var_name: &'_ str,
81 ) -> String
82 {
83 let sep = if var_name.is_empty() { "" } else { " " };
84 format!("{}{sep}{var_name}", Self::name(language))
85 }
86
87 /// Optional marshaler attached to the type (_e.g._,
88 /// `[MarshalAs(UnmanagedType.FunctionPtr)]`)
89 fn csharp_marshaler ()
90 -> Option<String>
91 {
92 None
93 }
94 }
95}
96
97unsafe
98impl<T : LegacyCType> CType for T {
99 type OPAQUE_KIND = <T as LegacyCType>::OPAQUE_KIND;
100
101 __cfg_headers__! {
102 #[inline]
103 fn short_name ()
104 -> String
105 {
106 <Self as LegacyCType>::c_short_name().to_string()
107 }
108
109 #[inline]
110 fn define_self__impl (
111 _: &'_ dyn HeaderLanguage,
112 _: &'_ mut dyn Definer,
113 ) -> io::Result<()>
114 {
115 unimplemented!()
116 }
117
118 fn define_self (
119 language: &'_ dyn HeaderLanguage,
120 definer: &'_ mut dyn Definer,
121 ) -> io::Result<()>
122 {
123 match () {
124 | _case if language.is::<C>() => {
125 <Self as LegacyCType>::c_define_self(definer)
126 },
127 | _case if language.is::<CSharp>() => {
128 <Self as LegacyCType>::csharp_define_self(definer)
129 },
130 #[cfg(feature = "python-headers")]
131 | _case if language.is::<Python>() => {
132 <Self as LegacyCType>::c_define_self(definer)
133 },
134 | _ => unimplemented!(),
135 }
136 }
137
138 #[inline]
139 fn name (
140 language: &'_ dyn HeaderLanguage,
141 ) -> String
142 {
143 Self::name_wrapping_var(language, "")
144 }
145
146 #[inline]
147 fn name_wrapping_var (
148 language: &'_ dyn HeaderLanguage,
149 var_name: &'_ str,
150 ) -> String
151 {
152 match () {
153 | _case if language.is::<C>() => {
154 <Self as LegacyCType>::c_var(var_name).to_string()
155 },
156 | _case if language.is::<CSharp>() => {
157 let sep = if var_name.is_empty() { "" } else { " " };
158 format!("{}{sep}{var_name}", Self::csharp_ty())
159 },
160 #[cfg(feature = "python-headers")]
161 | _case if language.is::<Python>() => {
162 <Self as LegacyCType>::c_var(var_name).to_string()
163 },
164 | _ => unimplemented!(),
165 }
166 }
167
168 #[inline]
169 fn csharp_marshaler ()
170 -> Option<String>
171 {
172 <T as LegacyCType>::legacy_csharp_marshaler()
173 }
174 }
175}
176
177pub
178type CLayoutOf<ImplReprC> = <ImplReprC as ReprC>::CLayout;
179
180/// One of the two core traits of this crate (with [`ReprC`][`trait@ReprC`]).
181///
182/// `CType` is an `unsafe` trait that binds a Rust type to a C typedef.
183///
184/// To optimise compile-times, the C typedef part is gated behind the `headers`
185/// cargo feature, so when that feature is not enabled, the trait may "look"
186/// like a marker trait, but it isn't.
187///
188/// That's why **manually implementing this trait is strongly discouraged**,
189/// although not forbidden:
190///
191/// - If you trully want a manual implementation of `CType` (_e.g._, for an
192/// "opaque type" pattern, _i.e._, a forward declaration), then, to
193/// implement the trait so that it works no matter the status of
194/// the `safer_ffi/headers` feature, one must define the methods as if
195/// feature was present, but with a `#[::safer_ffi::cfg_headers]` gate slapped
196/// on _each_ method.
197///
198/// # Safety
199///
200/// The Rust type in an `extern "C"` function must have the same layout and ABI
201/// as the defined C type, and all the bit-patterns representing any instance
202/// of such C type must be valid and safe bit-patterns for the Rust type.
203///
204/// For the most common types, there are only two reasons to correctly be a
205/// `CType`:
206///
207/// - being a primitive type, such as an integer type or a (slim) pointer.
208///
209/// - This crates provides as many of these implementations as possible.
210///
211/// - and recursively, a non-zero-sized `#[repr(C)]` struct of `CType` fields.
212///
213/// - the [`CType!`] macro can be used to wrap a `#[repr(C)]` struct
214/// definition to _safely_ and automagically implement the trait
215/// when it is sound to do so.
216///
217/// Note that types such as Rust's [`bool`] are ruled out by this definition,
218/// since it has the ABI of a `u8 <-> uint8_t`, and yet there are many
219/// bit-patterns for the `uint8_t` type that do not make _valid_ `bool`s.
220///
221/// For such types, see the [`ReprC`][`trait@ReprC`] trait.
222pub
223unsafe trait LegacyCType
224:
225 Sized +
226 Copy +
227 CType +
228{
229 type OPAQUE_KIND : OpaqueKind::T;
230 __cfg_headers__! {
231 /// A short-name description of the type, mainly used to fill
232 /// "placeholders" such as when monomorphising generics structs or
233 /// arrays.
234 ///
235 /// This provides the implementation used by [`LegacyCType::c_short_name`]`()`.
236 ///
237 /// There are no bad implementations of this method, except,
238 /// of course, for the obligation to provide a valid identifier chunk,
239 /// _i.e._, the output must only contain alphanumeric digits and
240 /// underscores.
241 ///
242 /// For instance, given `T : CType` and `const N: usize > 0`, the type
243 /// `[T; N]` (inline fixed-size array of `N` consecutive elements of
244 /// type `T`) will be typedef-named as:
245 ///
246 /// ```rust,ignore
247 /// write!(fmt, "{}_{}_array", <T as CType>::c_short_name(), N)
248 /// ```
249 ///
250 /// Generally, typedefs with a trailing `_t` will see that `_t` trimmed
251 /// when used as a `short_name`.
252 ///
253 /// ## Implementation by [`CType!`]:
254 ///
255 /// A non generic struct such as:
256 ///
257 /// ```rust,ignore
258 /// CType! {
259 /// #[repr(C)]
260 /// struct Foo { /* fields */ }
261 /// }
262 /// ```
263 ///
264 /// will have `Foo` as its `short_name`.
265 ///
266 /// A generic struct such as:
267 ///
268 /// ```rust,ignore
269 /// CType! {
270 /// #[repr(C)]
271 /// struct Foo[T] where { T : CType } { /* fields */ }
272 /// }
273 /// ```
274 ///
275 /// will have `Foo_xxx` as its `short_name`, with `xxx` being `T`'s
276 /// `short_name`.
277 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
278 -> fmt::Result
279 ;
280 // {
281 // Self::short_name_fmt(&C, fmt)
282 // }
283
284 // fn short_name_fmt (
285 // language: &'_ dyn HeaderLanguage,
286 // fmt: &'_ mut fmt::Formatter<'_>,
287 // ) -> fmt::Result
288 // {
289 // match () {
290 // | _case if language.is::<C>() => Self::c_short_name_fmt(fmt),
291 // // | _case if language.is::<CSharp>() => Self::csharp_short_name_fmt(fmt),
292 // | _ => unimplemented!(),
293 // }
294 // }
295
296 /// Convenience function for _callers_ / users of types implementing
297 /// [`CType`][`trait@CType`].
298 ///
299 /// The `Display` logic is auto-derived from the implementation of
300 /// [`LegacyCType::c_short_name_fmt`]`()`.
301 #[inline]
302 fn c_short_name ()
303 -> short_name_impl_display::ImplDisplay<Self>
304 {
305 short_name_impl_display::ImplDisplay { _phantom: PhantomData }
306 }
307
308 /// Necessary one-time code for [`LegacyCType::c_var`]`()` to make sense.
309 ///
310 /// Some types, such as `char`, are part of the language, and can be
311 /// used directly by [`LegacyCType::c_var`]`()`.
312 /// In that case, there is nothing else to _define_, and all is fine.
313 ///
314 /// - That is the default implementation of this method: doing
315 /// nothing.
316 ///
317 /// But most often than not, a `typedef` or an `#include` is required.
318 ///
319 /// In that case, here is the place to put it, with the help of the
320 /// provided `Definer`.
321 ///
322 /// # Idempotent
323 ///
324 /// Given some `definer: &mut dyn Definer`, **the `c_define_self(definer)`
325 /// call must be idempotent _w.r.t._ code generated**. In other words,
326 /// two or more such calls must not generate any extra code _w.r.t_ the
327 /// first call.
328 ///
329 /// This is easy to achieve thanks to `definer`:
330 ///
331 /// ```rust,ignore
332 /// // This ensures the idempotency requirements are met.
333 /// definer.define_once(
334 /// // some unique `&str`, ideally the C name being defined:
335 /// "my_super_type_t",
336 /// // Actual code generation logic, writing to `definer.out()`
337 /// &mut |definer| {
338 /// // If the typdef recursively needs other types being defined,
339 /// // ensure it is the case by explicitly calling
340 /// // `c_define_self(definer)` on those types.
341 /// OtherType::c_define_self(definer)?;
342 /// write!(definer.out(), "typedef ... my_super_type_t;", ...)
343 /// },
344 /// )?
345 /// ```
346 ///
347 /// # Safety
348 ///
349 /// Given that the defined types may be used by [`LegacyCType::c_var_fmt`]`()`,
350 /// the same safety disclaimers apply.
351 ///
352 /// ## Examples
353 ///
354 /// #### `i32`
355 ///
356 /// The corresponding type for `i32` in C is `int32_t`, but such type
357 /// definition is not part of the language, it is brought by a library
358 /// instead: `<stdint.h>` (or `<inttypes.h>` since it includes it).
359 ///
360 /// ```rust,ignore
361 /// unsafe impl CType for i32 {
362 /// #[::safer_ffi::cfg_headers]
363 /// fn c_define_self (definer: &'_ mut dyn Definer)
364 /// -> io::Result<()>
365 /// {
366 /// definer.define_once("<stdint.h>", &mut |definer| {
367 /// write!(definer.out(), "\n#include <stdint.h>\n")
368 /// })
369 /// }
370 ///
371 /// // ...
372 /// }
373 /// ```
374 ///
375 /// #### `#[repr(C)] struct Foo { x: i32 }`
376 ///
377 /// ```rust,ignore
378 /// #[repr(C)]
379 /// struct Foo {
380 /// x: i32,
381 /// }
382 ///
383 /// unsafe impl CType for i32 {
384 /// #[::safer_ffi::cfg_headers]
385 /// fn c_define_self (definer: &'_ mut dyn Definer)
386 /// -> io::Result<()>
387 /// {
388 /// definer.define_once("Foo_t", &mut |definer| {
389 /// // ensure int32_t makes sense
390 /// <i32 as CType>::c_define_self(definer)?;
391 /// write!(definer.out(),
392 /// "typedef struct {{ {}; }} Foo_t;",
393 /// <i32 as CType>::c_var("x"),
394 /// )
395 /// })
396 /// }
397 ///
398 /// // ...
399 /// }
400 /// ```
401 fn c_define_self (definer: &'_ mut dyn Definer)
402 -> io::Result<()>
403 ;
404 // {
405 // Self::define_self(&C, definer)
406 // }
407
408 // #[inline]
409 // fn define_self__impl (
410 // language: &'_ dyn HeaderLanguage,
411 // definer: &'_ mut dyn Definer,
412 // ) -> io::Result<()>
413 // {
414 // let _ = (language, definer);
415 // Ok(())
416 // }
417
418 /// The core method of the trait: it provides the implementation to be
419 /// used by [`LegacyCType::c_var`], by bringing a `Formatter` in scope.
420 ///
421 /// This provides the implementation used by [`LegacyCType::c_var`]`()`.
422 ///
423 /// The implementations are thus much like any classic `Display` impl,
424 /// except that:
425 ///
426 /// - it must output valid C code representing the type corresponding
427 /// to the Rust type.
428 ///
429 /// - a `var_name` may be supplied, in which case the type must
430 /// use that as its "variable name" (C being how it is, the var
431 /// name may need to be inserted in the middle of the types, such as
432 /// with arrays and function pointers).
433 ///
434 /// # Safety
435 ///
436 /// Here is where the meat of the safety happens: associating a Rust
437 /// type to a non-corresponding C definition will cause Undefined
438 /// Behavior when a function using such type in its ABI is called.
439 ///
440 /// ## Examples
441 ///
442 /// #### `i32`
443 ///
444 /// ```rust,ignore
445 /// unsafe impl CType for i32 {
446 /// #[::safer_ffi::cfg_headers]
447 /// fn c_var_fmt (
448 /// fmt: &'_ mut fmt::Formatter<'_>,
449 /// var_name: &'_ str,
450 /// ) -> fmt::Result
451 /// {
452 /// write!(fmt, "int32_t {}", var_name)
453 /// }
454 ///
455 /// // ...
456 /// }
457 /// ```
458 ///
459 /// #### `Option<extern "C" fn (i32) -> u32>`
460 ///
461 /// ```rust,ignore
462 /// unsafe impl CType for Option<extern "C" fn (i32) -> u32> {
463 /// #[::safer_ffi::cfg_headers]
464 /// fn c_var_fmt (
465 /// fmt: &'_ mut fmt::Formatter<'_>,
466 /// var_name: &'_ str,
467 /// ) -> fmt::Result
468 /// {
469 /// write!(fmt, "uint32_t (*{})(int32_t)", var_name)
470 /// }
471 ///
472 /// // ...
473 /// }
474 /// ```
475 ///
476 /// #### `[i32; 42]`
477 ///
478 /// ```rust,ignore
479 /// unsafe impl CType for [i32; 42] {
480 /// #[::safer_ffi::cfg_headers]
481 /// fn c_var_fmt (
482 /// fmt: &'_ mut fmt::Formatter<'_>,
483 /// var_name: &'_ str,
484 /// ) -> fmt::Result
485 /// {
486 /// let typedef_name = format_args!("{}_t", Self::c_short_name());
487 /// write!(fmt, "{} {}", typedef_name, var_name)
488 /// }
489 ///
490 /// // Since `c_var_fmt()` requires a one-time typedef, overriding
491 /// // `c_define_self()` is necessary:
492 /// #[::safer_ffi::cfg_headers]
493 /// fn c_define_self (definer: &'_ mut dyn Definer)
494 /// -> fmt::Result
495 /// {
496 /// let typedef_name = &format!("{}_t", Self::c_short_name());
497 /// definer.define_once(typedef_name, &mut |definer| {
498 /// // ensure the array element type is defined
499 /// i32::c_define_self(definer)?;
500 /// write!(definer.out(),
501 /// "typedef struct {{ {0}; }} {1};\n",
502 /// i32::c_var("arr[42]"), // `int32_t arr[42]`
503 /// typedef_name,
504 /// )
505 /// })
506 /// }
507 ///
508 /// // etc.
509 /// }
510 /// ```
511 fn c_var_fmt (
512 fmt: &'_ mut fmt::Formatter<'_>,
513 var_name: &'_ str,
514 ) -> fmt::Result
515 ;
516
517 /// Convenience function for _callers_ / users of types implementing
518 /// [`LegacyCType`][`trait@LegacyCType`].
519 ///
520 /// The `Display` logic is auto-derived from the implementation of
521 /// [`LegacyCType::c_var_fmt`]`()`.
522 #[inline]
523 fn c_var (
524 var_name: &'_ str,
525 ) -> var_impl_display::ImplDisplay<'_, Self>
526 {
527 var_impl_display::ImplDisplay {
528 var_name,
529 _phantom: Default::default(),
530 }
531 }
532
533 __cfg_csharp__! {
534 /// Extra typedef code (_e.g._ `[LayoutKind.Sequential] struct ...`)
535 fn csharp_define_self (definer: &'_ mut dyn Definer)
536 -> io::Result<()>
537 ;
538 // {
539 // Self::define_self(
540 // &CSharp,
541 // definer,
542 // )
543 // }
544
545 /// Optional marshaler attached to the type (_e.g._,
546 /// `[MarshalAs(UnmanagedType.FunctionPtr)]`)
547 fn legacy_csharp_marshaler ()
548 -> Option<rust::String>
549 {
550 None
551 }
552
553 // TODO: Optimize out those unnecessary heap-allocations
554 /// Type name (_e.g._, `int`, `string`, `IntPtr`)
555 fn csharp_ty ()
556 -> rust::String
557 {
558 Self::c_var("").to_string()
559 }
560
561 /// Convenience function for formatting `{ty} {var}` in CSharp.
562 fn csharp_var (var_name: &'_ str)
563 -> rust::String
564 {
565 format!(
566 "{}{sep}{}",
567 Self::csharp_ty(), var_name,
568 sep = if var_name.is_empty() { "" } else { " " },
569 )
570 }
571 }
572 }
573}
574
575__cfg_headers__! {
576 mod var_impl_display {
577 use super::*;
578 use fmt::*;
579
580 #[allow(missing_debug_implementations)]
581 pub
582 struct ImplDisplay<'__, T : LegacyCType> {
583 pub(in super)
584 var_name: &'__ str,
585
586 pub(in super)
587 _phantom: ::core::marker::PhantomData<T>,
588 }
589
590 impl<T : LegacyCType> Display
591 for ImplDisplay<'_, T>
592 {
593 #[inline]
594 fn fmt (self: &'_ Self, fmt: &'_ mut Formatter<'_>)
595 -> Result
596 {
597 T::c_var_fmt(fmt, self.var_name)
598 }
599 }
600 }
601
602 mod short_name_impl_display {
603 use super::*;
604 use fmt::*;
605
606 #[allow(missing_debug_implementations)]
607 pub
608 struct ImplDisplay<T : LegacyCType> {
609 pub(in super)
610 _phantom: ::core::marker::PhantomData<T>,
611 }
612
613 impl<T : LegacyCType> Display
614 for ImplDisplay<T>
615 {
616 #[inline]
617 fn fmt (self: &'_ Self, fmt: &'_ mut Formatter<'_>)
618 -> Result
619 {
620 T::c_short_name_fmt(fmt)
621 }
622 }
623 }
624}
625
626/// The meat of the crate. _The_ trait.
627/// This trait describes that **a type has a defined / fixed `#[repr(C)]`
628/// layout**.
629///
630/// This is expressed at the type level by the `unsafe` (trait) type
631/// association of `ReprC::CLayout`, which must be a [`CType`][`trait@CType`].
632///
633/// Because of that property, the type may be used in the API of an
634/// `#[ffi_export]`-ed function, where ABI-wise it will be replaced by its
635/// equivalent [C layout][`ReprC::CLayout`].
636///
637/// Then, `#[ffi_export]` will transmute the `CType` parameters back to the
638/// provided `ReprC` types, using [`from_raw_unchecked`].
639///
640/// Although, from a pure point of view, no checks are performed at this step
641/// whatsoever, in practice, when `debug_assertions` are enabled, some "sanity
642/// checks" are performed on the input parameters: [`ReprC::is_valid`] is
643/// called in that case (as part of the implementation of [`from_raw`]).
644///
645/// - Although that may look innocent, it is actually pretty powerful tool:
646///
647/// **For instance, a non-null pointer coming from C can, this way, be
648/// automatically checked and unwrapped, and the same applies for
649/// enumerations having a finite number of valid bit-patterns.**
650///
651/// # Safety
652///
653/// It must be sound to transmute from a `ReprC::CLayout` instance when the
654/// bit pattern represents a _safe_ instance of `Self`.
655///
656/// # Implementing `ReprC`
657///
658/// It is generally recommended to avoid manually (and `unsafe`-ly)
659/// implementing the [`ReprC`] trait. Instead, the recommended and blessed way
660/// is to use the [`#[derive_ReprC]`](/safer_ffi/layout/attr.derive_ReprC.html)
661/// attribute on your `#[repr(C)] struct` (or your field-less
662/// `#[repr(<integer>)] enum`).
663///
664/// [`ReprC`]: `trait@ReprC`
665///
666/// ## Examples
667///
668/// #### Simple `struct`
669///
670/// ```rust,no_run
671/// # fn main () {}
672/// use ::safer_ffi::prelude::*;
673///
674/// #[derive_ReprC]
675/// #[repr(C)]
676/// struct Instant {
677/// seconds: u64,
678/// nanos: u32,
679/// }
680/// ```
681///
682/// - corresponding to the following C definition:
683///
684/// ```C
685/// typedef struct {
686/// uint64_t seconds;
687/// uint32_t nanos;
688/// } Instant_t;
689/// ```
690///
691/// #### Field-less `enum`
692///
693/// ```rust,no_run
694/// # fn main () {}
695/// use ::safer_ffi::prelude::*;
696///
697/// #[derive_ReprC]
698/// #[repr(u8)]
699/// enum Status {
700/// Ok = 0,
701/// Busy,
702/// NotInTheMood,
703/// OnStrike,
704/// OhNo,
705/// }
706/// ```
707///
708/// - corresponding to the following C definition:
709///
710/// ```C
711/// typedef uint8_t Status_t; enum {
712/// STATUS_OK = 0,
713/// STATUS_BUSY,
714/// STATUS_NOT_IN_THE_MOOD,
715/// STATUS_ON_STRIKE,
716/// STATUS_OH_NO,
717/// }
718/// ```
719///
720/// #### Generic `struct`
721///
722/// ```rust,no_run
723/// # fn main () {}
724/// use ::safer_ffi::prelude::*;
725///
726/// #[derive_ReprC]
727/// #[repr(C)]
728/// struct Point<Coordinate : ReprC> {
729/// x: Coordinate,
730/// y: Coordinate,
731/// }
732/// ```
733///
734/// Each monomorphization leads to its own C definition:
735///
736/// - **`Point<i32>`**
737///
738/// ```C
739/// typedef struct {
740/// int32_t x;
741/// int32_t y;
742/// } Point_int32_t;
743/// ```
744///
745/// - **`Point<f64>`**
746///
747/// ```C
748/// typedef struct {
749/// double x;
750/// double y;
751/// } Point_double_t;
752/// ```
753pub
754unsafe
755trait ReprC : Sized {
756 /// The `CType` having the same layout as `Self`.
757 type CLayout : CType;
758
759 /// Sanity checks that can be performed on an instance of the `CType`
760 /// layout.
761 ///
762 /// Such checks are performed when calling [`from_raw`], or equivalently
763 /// (⚠️ only with `debug_assertions` enabled ⚠️), [`from_raw_unchecked`].
764 ///
765 /// Implementation-wise, this function is only a "sanity check" step:
766 ///
767 /// - It is valid (although rather pointless) for this function to always
768 /// return `true`, even if the input may be `unsafe` to transmute to
769 /// `Self`, or even be an _invalid_ value of type `Self`.
770 ///
771 /// - In the other direction, it is not unsound, although it would be a
772 /// logic error, to always return `false`.
773 ///
774 /// - This is because it is impossible to have a function that for any
775 /// type is able to tell if a given bit pattern is a safe value of that
776 /// type.
777 ///
778 /// In practice, if this function returns `false`, then such result must be
779 /// trusted, _i.e._, transmuting such instance to the `Self` type will,
780 /// at the very least, break a _safety_ invariant, and it will even most
781 /// probably break a _validity_ invariant.
782 ///
783 /// On the other hand, if the function returns `true`, then the result is
784 /// inconclusive; there is no explicit reason to stop going on, but that
785 /// doesn't necessarily make it sound.
786 ///
787 /// # TL,DR
788 ///
789 /// > This function **may yield false positives** but no false negatives.
790 ///
791 /// ## Example: `Self = &'borrow i32`
792 ///
793 /// When `Self = &'borrow i32`, we know that the backing pointer is
794 /// necessarily non-null and well-aligned.
795 ///
796 /// This means that bit-patterns such as `0 as *const i32` or
797 /// `37 as *const i32` are "blatantly unsound" to transmute to a
798 /// `&'borrow i32`, and thus `<&'borrow i32 as ReprC>::is_valid` will
799 /// return `false` in such cases.
800 ///
801 /// But if given `4 as *const i32`, or if given `{ let p = &*Box::new(42)
802 /// as *const i32; p }`, then `is_valid` will return `true` in both cases,
803 /// since it doesn't know better.
804 ///
805 /// ## Example: `bool` or `#[repr(u8)] enum Foo { A, B }`
806 ///
807 /// In the case of `bool`, or in the case of a `#[repr(<integer>)]`
808 /// field-less enum, then the valid bit-patterns and the invalid
809 /// bit-patterns are all known and finite.
810 ///
811 /// In that case, `ReprC::is_valid` will return a `bool` that truly
812 /// represents the validity of the bit-pattern, in both directions
813 ///
814 /// - _i.e._, no false positives (_validity_-wise);
815 ///
816 /// Still, there may be _safety_ invariants involved with custom types,
817 /// so even then it is unclear.
818 fn is_valid (it: &'_ Self::CLayout)
819 -> bool
820 ;
821}
822
823#[doc(hidden)] /** For clarity;
824 this macro may be stabilized
825 if downstream users find it useful
826 **/
827#[macro_export]
828macro_rules! from_CType_impl_ReprC {(
829 $(@for[$($generics:tt)*])? $T:ty $(where $($bounds:tt)*)?
830) => (
831 unsafe
832 impl$(<$($generics)*>)? $crate::layout::ReprC
833 for $T
834 where
835 $($($bounds)*)?
836 {
837 type CLayout = Self;
838
839 #[inline]
840 fn is_valid (_: &'_ Self::CLayout)
841 -> bool
842 {
843 true
844 }
845 }
846)}
847
848#[inline]
849pub
850unsafe
851fn from_raw_unchecked<T : ReprC> (c_layout: T::CLayout)
852 -> T
853{
854 if let Some(it) = from_raw::<T>(c_layout) { it } else {
855 if cfg!(debug_assertions) || cfg!(test) {
856 panic!(
857 "Error: not a valid bit-pattern for the type `{}`",
858 // c_layout,
859 ::core::any::type_name::<T>(),
860 );
861 } else {
862 ::core::hint::unreachable_unchecked()
863 }
864 }
865}
866
867#[deny(unsafe_op_in_unsafe_fn)]
868#[inline]
869pub
870unsafe
871fn from_raw<T : ReprC> (c_layout: T::CLayout)
872 -> Option<T>
873{
874 if <T as ReprC>::is_valid(&c_layout).not() {
875 None
876 } else {
877 Some(unsafe {
878 const_assert! {
879 for [T]
880 [T : ReprC] => [T::CLayout : Copy]
881 }
882 crate::utils::transmute_unchecked(c_layout)
883 })
884 }
885}
886
887#[deny(unsafe_op_in_unsafe_fn)]
888#[inline]
889pub
890unsafe // May not be sound when input has uninit bytes that the output does not
891 // have.
892fn into_raw<T : ReprC> (it: T)
893 -> T::CLayout
894{
895 unsafe {
896 crate::utils::transmute_unchecked(
897 ::core::mem::ManuallyDrop::new(it)
898 )
899 }
900}
901
902pub use impls::Opaque;
903pub(in crate)
904mod impls;
905
906mod niche;
907
908#[apply(hidden_export)]
909use niche::HasNiche as __HasNiche__;
910
911#[apply(hidden_export)]
912trait Is { type EqTo : ?Sized; }
913impl<T : ?Sized> Is for T { type EqTo = Self; }
914
915/// Alias for `ReprC where Self::CLayout::OPAQUE_KIND = OpaqueKind::Concrete`
916pub
917trait ConcreteReprC
918where
919 Self : ReprC,
920{
921 type ConcreteCLayout
922 :
923 Is<EqTo = CLayoutOf<Self>> +
924 CType<OPAQUE_KIND = OpaqueKind::Concrete> +
925 ;
926}
927impl<T : ?Sized> ConcreteReprC for T
928where
929 Self : ReprC,
930 CLayoutOf<Self> : CType<OPAQUE_KIND = OpaqueKind::Concrete>,
931{
932 type ConcreteCLayout = CLayoutOf<Self>;
933}
934
935#[apply(hidden_export)]
936fn __assert_concrete__<T> ()
937where
938 T : ConcreteReprC,
939{}