Skip to main content

rust_spec/
lib.rs

1//! Compile-time classification of Rust types according to Rust-specified type properties.
2//!
3//! # Classification Axes
4//!
5//! `RustSpec` describes a type across the following axes:
6//! - [`layout`]: representation stability.
7//! - [`size`]: statically sized, metadata-sized, or extern-type-like shape.
8//! - `Alignment`: whether ABI alignment is one or greater than one.
9//! - [`trap`](layout): whether the value representation has trap values.
10//! - [`niche`]: whether a type has a stable, unstable, or no niche value.
11//!
12//! ## Layout
13//!
14//! Describes total reachable (through pointer indirection) representation stability:
15//! - `Stable`: compiler-guaranteed representation.
16//! - `Unstable`: representation is not guaranteed.
17//!
18//! ## Size
19//!
20//! Describes compile-time size and pointer metadata shape:
21//! - [`size::Sized<Zero>`]: compile-time known zero-sized type.
22//! - [`size::Sized<Gt<Zero>>`]: compile-time known non-zero-sized type.
23//! - [`size::MetaSized<size::SliceLike>`]: dynamically sized slice-like type.
24//! - [`size::MetaSized<size::DynTraitLike>`]: dynamically sized trait-object-like type.
25//! - [`size::ExternTypeLike`]: dynamically sized extern-type-like type.
26//! - [`size::NulTerminated`]: unsized nul-terminated data.
27//!
28//! ## Alignment
29//!
30//! Whether ABI alignment is exactly one or greater than one.
31//!
32//! ## Trap
33//!
34//! Describes total reachable (through pointer indirection) value-representation validity:
35//! - [`layout::Robust`]: every bit pattern is valid.
36//! - [`layout::NonRobust`]: some bit patterns are trap/invalid values.
37//!
38//! ## Niche
39//!
40//! Describes whether and what kind of niche is available for the type:
41//! - [`niche::WithoutNiche`]: no niche is available.
42//! - [`niche::WithNiche<Stable>`]: compiler-guaranteed niche.
43//! - [`niche::WithNiche<Unstable>`]: niche exists but is not guaranteed.
44//!
45//! ## How to Use
46//!
47//! Derive `RustSpec` for your types, then use its associated marker families as bounds when implementing other traits:
48//!
49//! ```rust
50//! use disjoint_impls::disjoint_impls;
51//! use rust_spec::{
52//!     RustSpec, Stable, Unstable,
53//!     niche::{WithNiche, WithoutNiche}
54//! };
55//!
56//! #[derive(RustSpec)]
57//! struct Header {
58//!     id: u32,
59//!     flags: u16,
60//! }
61//!
62//! disjoint_impls! {
63//!     trait NullableEncoding {
64//!         const NEEDS_TAG: bool;
65//!     }
66//!
67//!     impl<T: RustSpec<Niche = WithoutNiche>> NullableEncoding for T {
68//!         const NEEDS_TAG: bool = true;
69//!     }
70//!
71//!     impl<T: RustSpec<Niche = WithNiche<Stable>>> NullableEncoding for T {
72//!         const NEEDS_TAG: bool = false;
73//!     }
74//!
75//!     impl<T: RustSpec<Niche = WithNiche<Unstable>>> NullableEncoding for T {
76//!         const NEEDS_TAG: bool = false;
77//!     }
78//! }
79//!
80//! const HEADER_OPTION_NEEDS_TAG: bool = Header::NEEDS_TAG;
81//! ```
82#![no_std]
83
84#[cfg(feature = "alloc")]
85extern crate alloc;
86extern crate self as rust_spec;
87
88#[cfg(feature = "alloc")]
89use alloc::boxed::Box;
90use core::ops::Add;
91
92use crate::{
93    niche::{WithNiche, WithoutNiche},
94    size::{MetadataKind, SizedKind},
95};
96use disjoint_impls::disjoint_impls;
97#[cfg(feature = "derive")]
98pub use rust_spec_derive::RustSpec;
99
100mod core_impls;
101
102/// Marker for a compiler-guaranteed representation or niche.
103pub enum Stable {}
104
105/// Marker for a representation or niche that is not compiler-guaranteed.
106pub enum Unstable {}
107
108/// Marker for a zero-sized type.
109pub enum Zero {}
110
111/// Marker for a statically sized type greater than the given threshold.
112pub struct Gt<T>(core::marker::PhantomData<T>);
113
114/// Marker for ABI alignment one.
115pub enum One {}
116
117/// Type-level maximum used to combine alignment categories.
118pub trait Max<Rhs> {
119    type Output;
120}
121
122impl<Rhs> Max<Rhs> for One {
123    type Output = Rhs;
124}
125impl<Rhs> Max<Rhs> for Gt<One> {
126    type Output = Gt<One>;
127}
128
129trait WithoutOrUnstableNiche {}
130
131impl WithoutOrUnstableNiche for WithoutNiche {}
132impl WithoutOrUnstableNiche for WithNiche<Stable> {}
133
134pub mod layout;
135#[doc(hidden)]
136pub mod mutability;
137pub mod niche;
138mod primitives;
139pub mod size;
140mod tuple;
141
142/// Opaque, lifetime-indexed field axes emitted by `RustSpec` derives for
143/// projections whose prerequisites are supplied by higher-ranked bounds.
144#[doc(hidden)]
145pub trait __HrtbAxes<const FIELD: usize> {
146    type Layout<'a>;
147    type Size<'a>;
148    type Alignment<'a>;
149    type Trap<'a>;
150    type Niche<'a>;
151    type Mutability<'a>;
152    type __IndirectTrap<'a>;
153}
154
155disjoint_impls! {
156    /// Joined Rust-spec classification of a type.
157    ///
158    /// This is the canonical surface for Rust-specified properties used by
159    /// conversion.
160    ///
161    /// # Safety
162    ///
163    /// Implementors must classify `Self` truthfully. In particular, [`Self::Size`]
164    /// carries the same safety requirements documented by the size marker types.
165    pub unsafe trait RustSpec {
166        /// Representation-stability classification.
167        type Layout;
168
169        /// Statically known, metadata-sized, or extern-type-like size classification.
170        type Size;
171
172        /// ABI alignment
173        type Alignment;
174
175        /// Trap-representation classification.
176        type Trap;
177
178        /// Niche availability classification.
179        type Niche;
180
181        /// Shared-access mutability classification.
182        #[doc(hidden)]
183        type Mutability;
184
185        /// Trap classification reachable through one or more supported pointer indirections.
186        #[doc(hidden)]
187        type __IndirectTrap;
188    }
189
190    unsafe impl<R: ?Sized> RustSpec for &R
191    where
192        R: RustSpec<Size: size::Thin>,
193    {
194        type Layout = R::Layout;
195        type Size = size::Sized<Gt<Zero>>;
196        type Alignment = <usize as RustSpec>::Alignment;
197        type Trap = layout::NonRobust;
198        type Niche = WithNiche<Stable>;
199        type Mutability = R::Mutability;
200        type __IndirectTrap = R::Trap;
201    }
202    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for &R
203    where
204        R: RustSpec<Size = size::MetaSized<U>>,
205    {
206        type Layout = Unstable;
207        type Size = size::Sized<Gt<Zero>>;
208        type Alignment = <usize as RustSpec>::Alignment;
209        type Trap = layout::NonRobust;
210        type Niche = WithNiche<Unstable>;
211        type Mutability = R::Mutability;
212        type __IndirectTrap = R::Trap;
213    }
214    unsafe impl<R: ?Sized> RustSpec for &R
215    where
216        R: RustSpec<Size = size::NulTerminated>,
217    {
218        type Layout = Unstable;
219        type Size = size::Sized<Gt<Zero>>;
220        type Alignment = <usize as RustSpec>::Alignment;
221        type Trap = layout::NonRobust;
222        type Niche = WithNiche<Unstable>;
223        type Mutability = R::Mutability;
224        type __IndirectTrap = R::Trap;
225    }
226
227    unsafe impl<R: ?Sized> RustSpec for &mut R
228    where
229        R: RustSpec<Size: size::Thin>,
230    {
231        type Layout = R::Layout;
232        type Size = size::Sized<Gt<Zero>>;
233        type Alignment = <usize as RustSpec>::Alignment;
234        type Trap = layout::NonRobust;
235        type Niche = WithNiche<Stable>;
236        type Mutability = R::Mutability;
237        type __IndirectTrap = R::Trap;
238    }
239    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for &mut R
240    where
241        R: RustSpec<Size = size::MetaSized<U>>,
242    {
243        type Layout = Unstable;
244        type Size = size::Sized<Gt<Zero>>;
245        type Alignment = <usize as RustSpec>::Alignment;
246        type Trap = layout::NonRobust;
247        type Niche = WithNiche<Unstable>;
248        type Mutability = R::Mutability;
249        type __IndirectTrap = R::Trap;
250    }
251    unsafe impl<R: ?Sized> RustSpec for &mut R
252    where
253        R: RustSpec<Size = size::NulTerminated>,
254    {
255        type Layout = Unstable;
256        type Size = size::Sized<Gt<Zero>>;
257        type Alignment = <usize as RustSpec>::Alignment;
258        type Trap = layout::NonRobust;
259        type Niche = WithNiche<Unstable>;
260        type Mutability = R::Mutability;
261        type __IndirectTrap = R::Trap;
262    }
263
264    #[cfg(feature = "alloc")]
265    unsafe impl<R, S: SizedKind> RustSpec for Box<R>
266    where
267        R: RustSpec<Size = size::Sized<S>>,
268    {
269        type Layout = R::Layout;
270        type Size = size::Sized<Gt<Zero>>;
271        type Alignment = <usize as RustSpec>::Alignment;
272        type Trap = layout::NonRobust;
273        type Niche = WithNiche<Stable>;
274        type Mutability = R::Mutability;
275        type __IndirectTrap = R::Trap;
276    }
277    #[cfg(feature = "alloc")]
278    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for Box<R>
279    where
280        R: RustSpec<Size = size::MetaSized<U>>,
281    {
282        type Layout = Unstable;
283        type Size = size::Sized<Gt<Zero>>;
284        type Alignment = <usize as RustSpec>::Alignment;
285        type Trap = layout::NonRobust;
286        type Niche = WithNiche<Unstable>;
287        type Mutability = mutability::Exclusive;
288        type __IndirectTrap = R::Trap;
289    }
290    #[cfg(feature = "alloc")]
291    unsafe impl<R: ?Sized> RustSpec for Box<R>
292    where
293        R: RustSpec<Size = size::NulTerminated>,
294    {
295        type Layout = Unstable;
296        type Size = size::Sized<Gt<Zero>>;
297        type Alignment = <usize as RustSpec>::Alignment;
298        type Trap = layout::NonRobust;
299        type Niche = WithNiche<Unstable>;
300        type Mutability = mutability::Exclusive;
301        type __IndirectTrap = R::Trap;
302    }
303
304    unsafe impl<R> RustSpec for Option<R>
305    where
306        R: RustSpec<Niche = WithoutNiche>,
307    {
308        type Layout = Unstable;
309        type Size = size::Sized<Gt<Zero>>;
310        type Alignment = R::Alignment;
311        type Trap = layout::NonRobust;
312        type Niche = WithNiche<Unstable>;
313        type Mutability = mutability::Exclusive;
314        type __IndirectTrap = R::__IndirectTrap;
315    }
316    unsafe impl<R> RustSpec for Option<R>
317    where
318        R: RustSpec<Niche = WithNiche<Unstable>>,
319    {
320        type Layout = Unstable;
321        // FIXME: This can be Robust but we have to track
322        // the number of available custom/unstable niches.
323        // The same thing happens for all other enums
324        type Size = size::Sized<Gt<Zero>>;
325        type Alignment = R::Alignment;
326        type Trap = layout::NonRobust;
327        type Niche = WithNiche<Unstable>;
328        type Mutability = mutability::Exclusive;
329        type __IndirectTrap = R::__IndirectTrap;
330    }
331    unsafe impl<R> RustSpec for Option<R>
332    where
333        R: RustSpec<Niche = WithNiche<Stable>>,
334    {
335        type Layout = R::Layout;
336        type Size = size::Sized<Gt<Zero>>;
337        type Alignment = R::Alignment;
338        type Trap = R::__IndirectTrap;
339        type Niche = WithoutNiche;
340        type Mutability = mutability::Exclusive;
341        type __IndirectTrap = R::__IndirectTrap;
342    }
343
344    unsafe impl<R, E, K: SizedKind> RustSpec for Result<R, E>
345    where
346        R: RustSpec<Size = size::Sized<K>>,
347        E: RustSpec<Size = size::Sized<K>>,
348        <R as RustSpec>::Niche: WithoutOrUnstableNiche,
349        <E as RustSpec>::Niche: WithoutOrUnstableNiche,
350        <R as RustSpec>::__IndirectTrap: Add<<E as RustSpec>::__IndirectTrap>,
351        <E as RustSpec>::Alignment: Sized,
352        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
353    {
354        type Layout = Unstable;
355        type Size = size::Sized<Gt<Zero>>;
356        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
357        type Trap = layout::NonRobust;
358        type Niche = WithNiche<Unstable>;
359        type Mutability = mutability::Exclusive;
360        type __IndirectTrap = <R::__IndirectTrap as Add<E::__IndirectTrap>>::Output;
361    }
362
363    // TODO: The next 3 impls are the same
364    unsafe impl<R, E> RustSpec for Result<R, E>
365    where
366        R: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithoutNiche>,
367        E: RustSpec<Size = size::Sized<Zero>>,
368        <E as RustSpec>::Alignment: Sized,
369        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
370    {
371        type Layout = Unstable;
372        type Size = size::Sized<Gt<Zero>>;
373        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
374        type Trap = layout::NonRobust;
375        type Niche = WithNiche<Unstable>;
376        type Mutability = mutability::Exclusive;
377        type __IndirectTrap = R::__IndirectTrap;
378    }
379    unsafe impl<R, E> RustSpec for Result<R, E>
380    where
381        R: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Unstable>>,
382        E: RustSpec<Size = size::Sized<Zero>>,
383        <E as RustSpec>::Alignment: Sized,
384        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
385    {
386        type Layout = Unstable;
387        type Size = size::Sized<Gt<Zero>>;
388        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
389        type Trap = layout::NonRobust;
390        type Niche = WithNiche<Unstable>;
391        type Mutability = mutability::Exclusive;
392        type __IndirectTrap = R::__IndirectTrap;
393    }
394    unsafe impl<R, E> RustSpec for Result<R, E>
395    where
396        R: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Stable>>,
397        E: RustSpec<Size = size::Sized<Zero>, Alignment = Gt<One>>,
398        <E as RustSpec>::Alignment: Sized,
399        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
400    {
401        type Layout = Unstable;
402        type Size = size::Sized<Gt<Zero>>;
403        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
404        type Trap = layout::NonRobust;
405        type Niche = WithNiche<Unstable>;
406        type Mutability = mutability::Exclusive;
407        type __IndirectTrap = R::__IndirectTrap;
408    }
409    unsafe impl<R, E> RustSpec for Result<R, E>
410    where
411        R: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Stable>>,
412        E: RustSpec<Size = size::Sized<Zero>, Alignment = One>,
413        <E as RustSpec>::Alignment: Sized,
414        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
415    {
416        type Layout = R::Layout;
417        type Size = size::Sized<Gt<Zero>>;
418        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
419        type Trap = R::__IndirectTrap;
420        type Niche = WithoutNiche;
421        type Mutability = mutability::Exclusive;
422        type __IndirectTrap = R::__IndirectTrap;
423    }
424
425    // TODO: The next 3 impls are the same
426    unsafe impl<R, E> RustSpec for Result<R, E>
427    where
428        R: RustSpec<Size = size::Sized<Zero>>,
429        E: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithoutNiche>,
430        <R as RustSpec>::Alignment: Sized,
431        <E as RustSpec>::Alignment: Sized,
432        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
433    {
434        type Layout = Unstable;
435        type Size = size::Sized<Gt<Zero>>;
436        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
437        type Trap = layout::NonRobust;
438        type Niche = WithNiche<Unstable>;
439        type Mutability = mutability::Exclusive;
440        type __IndirectTrap = E::__IndirectTrap;
441    }
442    unsafe impl<R, E> RustSpec for Result<R, E>
443    where
444        R: RustSpec<Size = size::Sized<Zero>, Niche: WithoutOrUnstableNiche>,
445        E: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Unstable>>,
446        <R as RustSpec>::Alignment: Sized,
447        <E as RustSpec>::Alignment: Sized,
448        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
449    {
450        type Layout = Unstable;
451        type Size = size::Sized<Gt<Zero>>;
452        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
453        type Trap = layout::NonRobust;
454        type Niche = WithNiche<Unstable>;
455        type Mutability = mutability::Exclusive;
456        type __IndirectTrap = E::__IndirectTrap;
457    }
458    unsafe impl<R, E> RustSpec for Result<R, E>
459    where
460        R: RustSpec<Size = size::Sized<Zero>, Alignment = Gt<One>>,
461        E: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Stable>>,
462        <R as RustSpec>::Alignment: Sized,
463        <E as RustSpec>::Alignment: Sized,
464        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
465    {
466        type Layout = Unstable;
467        type Size = size::Sized<Gt<Zero>>;
468        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
469        type Trap = layout::NonRobust;
470        type Niche = WithNiche<Unstable>;
471        type Mutability = mutability::Exclusive;
472        type __IndirectTrap = E::__IndirectTrap;
473    }
474    unsafe impl<R, E> RustSpec for Result<R, E>
475    where
476        R: RustSpec<Size = size::Sized<Zero>, Alignment = One>,
477        E: RustSpec<Size = size::Sized<Gt<Zero>>, Niche = WithNiche<Stable>>,
478        <R as RustSpec>::Alignment: Sized,
479        <E as RustSpec>::Alignment: Sized,
480        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
481    {
482        type Layout = E::Layout;
483        type Size = size::Sized<Gt<Zero>>;
484        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
485        type Trap = E::__IndirectTrap;
486        type Niche = WithoutNiche;
487        type Mutability = mutability::Exclusive;
488        type __IndirectTrap = E::__IndirectTrap;
489    }
490}
491
492#[cfg(test)]
493mod tests {
494    #[cfg(feature = "alloc")]
495    use alloc::vec::Vec;
496
497    use static_assertions::assert_impl_all;
498
499    use super::*;
500    use {
501        layout::{NonRobust, Robust},
502        mutability::Exclusive,
503        niche::{WithNiche, WithoutNiche},
504        size::{Gt, Sized as Co3Sized},
505    };
506
507    #[test]
508    fn indirect_trap_follows_supported_pointers_only() {
509        assert_impl_all!(&u8: RustSpec<__IndirectTrap = Robust>);
510        assert_impl_all!(&bool: RustSpec<__IndirectTrap = NonRobust>);
511        assert_impl_all!(&&u8: RustSpec<__IndirectTrap = NonRobust>);
512        assert_impl_all!(Option<&u8>: RustSpec<__IndirectTrap = Robust>);
513        assert_impl_all!(*const bool: RustSpec<__IndirectTrap = Robust>);
514    }
515
516    #[test]
517    fn transparent_type() {
518        assert_impl_all!(bool:
519            RustSpec<
520                Layout = Stable,
521                Size = Co3Sized<Gt<Zero>>,
522                Alignment = One,
523                Trap = NonRobust,
524                Niche = WithNiche<Unstable>,
525                Mutability = Exclusive,
526                __IndirectTrap = Robust,
527            >,
528        );
529        assert_impl_all!(&bool:
530            RustSpec<
531                Layout = Stable,
532                Size = Co3Sized<Gt<Zero>>,
533                Alignment = <usize as RustSpec>::Alignment,
534                Trap = NonRobust,
535                Niche = WithNiche<Stable>,
536                Mutability = Exclusive,
537                __IndirectTrap = NonRobust,
538            >,
539        );
540        assert_impl_all!(&mut bool:
541            RustSpec<
542                Layout = Stable,
543                Size = Co3Sized<Gt<Zero>>,
544                Alignment = <usize as RustSpec>::Alignment,
545                Trap = NonRobust,
546                Niche = WithNiche<Stable>,
547                Mutability = Exclusive,
548                __IndirectTrap = NonRobust,
549            >,
550        );
551        #[cfg(feature = "alloc")]
552        assert_impl_all!(Box<bool>:
553            RustSpec<
554                Layout = Stable,
555                Size = Co3Sized<Gt<Zero>>,
556                Alignment = <usize as RustSpec>::Alignment,
557                Trap = NonRobust,
558                Niche = WithNiche<Stable>,
559                Mutability = Exclusive,
560                __IndirectTrap = NonRobust,
561            >,
562        );
563        assert_impl_all!(&[bool]:
564            RustSpec<
565                Layout = Unstable,
566                Size = Co3Sized<Gt<Zero>>,
567                Alignment = <usize as RustSpec>::Alignment,
568                Trap = NonRobust,
569                Niche = WithNiche<Unstable>,
570                Mutability = Exclusive,
571                __IndirectTrap = NonRobust,
572            >,
573        );
574        #[cfg(feature = "alloc")]
575        assert_impl_all!(&mut [bool]:
576            RustSpec<
577                Layout = Unstable,
578                Size = Co3Sized<Gt<Zero>>,
579                Alignment = <usize as RustSpec>::Alignment,
580                Trap = NonRobust,
581                Niche = WithNiche<Unstable>,
582                Mutability = Exclusive,
583                __IndirectTrap = NonRobust,
584            >,
585        );
586        #[cfg(feature = "alloc")]
587        assert_impl_all!(Box<[bool]>:
588            RustSpec<
589                Layout = Unstable,
590                Size = Co3Sized<Gt<Zero>>,
591                Alignment = <usize as RustSpec>::Alignment,
592                Trap = NonRobust,
593                Niche = WithNiche<Unstable>,
594                Mutability = Exclusive,
595                __IndirectTrap = NonRobust,
596            >,
597        );
598        #[cfg(feature = "alloc")]
599        assert_impl_all!(Vec<bool>:
600            RustSpec<
601                Layout = Unstable,
602                Size = Co3Sized<Gt<Zero>>,
603                Alignment = <usize as RustSpec>::Alignment,
604                Trap = NonRobust,
605                Niche = WithNiche<Unstable>,
606                Mutability = Exclusive,
607                __IndirectTrap = NonRobust,
608            >,
609        );
610        assert_impl_all!([bool; 2]:
611            RustSpec<
612                Layout = Stable,
613                Size = Co3Sized<Gt<Zero>>,
614                Alignment = One,
615                Trap = NonRobust,
616                Niche = WithNiche<Unstable>,
617                Mutability = Exclusive,
618                __IndirectTrap = Robust,
619            >,
620        );
621        // FIXME:
622        //assert_impl_all!(Option<bool>:
623        //    RustSpec<
624        //        Layout = Unstable,
625        //        Size = Co3Sized<Gt<Zero>>,
626        //        Trap = NonRobust,
627        //        Niche = WithNiche<Unstable>,
628        //        Mutability = Exclusive,
629        //    >,
630        //);
631    }
632
633    #[test]
634    fn option_stable_niche_layout() {
635        use core::num::NonZeroU8;
636
637        assert_impl_all!(Option<NonZeroU8>:
638            RustSpec<
639                Layout = Stable,
640                Size = Co3Sized<Gt<Zero>>,
641                Alignment = One,
642                Trap = Robust,
643                Niche = WithoutNiche,
644                Mutability = Exclusive,
645                __IndirectTrap = Robust,
646            >,
647        );
648        assert_impl_all!(Option<&u8>:
649            RustSpec<
650                Layout = Stable,
651                Size = Co3Sized<Gt<Zero>>,
652                Alignment = <usize as RustSpec>::Alignment,
653                Trap = Robust,
654                Niche = WithoutNiche,
655                Mutability = Exclusive,
656                __IndirectTrap = Robust,
657            >,
658        );
659        assert_impl_all!(Option<&(u8, u8, u8)>:
660            RustSpec<
661                Layout = Unstable,
662                Size = Co3Sized<Gt<Zero>>,
663                Alignment = <usize as RustSpec>::Alignment,
664                Trap = Robust,
665                Niche = WithoutNiche,
666                Mutability = Exclusive,
667                __IndirectTrap = Robust,
668            >,
669        );
670        assert_impl_all!(Option<&NonZeroU8>:
671            RustSpec<
672                Layout = Stable,
673                Size = Co3Sized<Gt<Zero>>,
674                Alignment = <usize as RustSpec>::Alignment,
675                Trap = NonRobust,
676                Niche = WithoutNiche,
677                Mutability = Exclusive,
678                __IndirectTrap = NonRobust,
679            >,
680        );
681    }
682
683    #[test]
684    fn result_stable_niche_layout() {
685        use core::num::NonZeroU8;
686
687        assert_impl_all!(Result<NonZeroU8, ()>:
688            RustSpec<
689                Layout = Stable,
690                Size = Co3Sized<Gt<Zero>>,
691                Alignment = One,
692                Trap = Robust,
693                Niche = WithoutNiche,
694                Mutability = Exclusive,
695                __IndirectTrap = Robust,
696            >,
697        );
698        assert_impl_all!(Result<&u8, ()>:
699            RustSpec<
700                Layout = Stable,
701                Size = Co3Sized<Gt<Zero>>,
702                Alignment = <usize as RustSpec>::Alignment,
703                Trap = Robust,
704                Niche = WithoutNiche,
705                Mutability = Exclusive,
706                __IndirectTrap = Robust,
707            >,
708        );
709        assert_impl_all!(Result<&NonZeroU8, ()>:
710            RustSpec<
711                Layout = Stable,
712                Size = Co3Sized<Gt<Zero>>,
713                Alignment = <usize as RustSpec>::Alignment,
714                Trap = NonRobust,
715                Niche = WithoutNiche,
716                Mutability = Exclusive,
717                __IndirectTrap = NonRobust,
718            >,
719        );
720        assert_impl_all!(Result<(), NonZeroU8>:
721            RustSpec<
722                Layout = Stable,
723                Size = Co3Sized<Gt<Zero>>,
724                Alignment = One,
725                Trap = Robust,
726                Niche = WithoutNiche,
727                Mutability = Exclusive,
728                __IndirectTrap = Robust,
729            >,
730        );
731        assert_impl_all!(Result<&mut u8, ()>:
732            RustSpec<
733                Layout = Stable,
734                Size = Co3Sized<Gt<Zero>>,
735                Alignment = <usize as RustSpec>::Alignment,
736                Trap = Robust,
737                Niche = WithoutNiche,
738                Mutability = Exclusive,
739                __IndirectTrap = Robust,
740            >,
741        );
742    }
743
744    #[test]
745    fn robust_ref() {
746        assert_impl_all!(&&u8:
747            RustSpec<
748                Layout = Stable,
749                Size = Co3Sized<Gt<Zero>>,
750                Alignment = <usize as RustSpec>::Alignment,
751                Trap = NonRobust,
752                Niche = WithNiche<Stable>,
753                Mutability = Exclusive,
754                __IndirectTrap = NonRobust,
755            >,
756        );
757        assert_impl_all!(&mut &u8:
758            RustSpec<
759                Layout = Stable,
760                Size = Co3Sized<Gt<Zero>>,
761                Alignment = <usize as RustSpec>::Alignment,
762                Trap = NonRobust,
763                Niche = WithNiche<Stable>,
764                Mutability = Exclusive,
765                __IndirectTrap = NonRobust,
766            >,
767        );
768        #[cfg(feature = "alloc")]
769        assert_impl_all!(Box<&bool>:
770            RustSpec<
771                Layout = Stable,
772                Size = Co3Sized<Gt<Zero>>,
773                Alignment = <usize as RustSpec>::Alignment,
774                Trap = NonRobust,
775                Niche = WithNiche<Stable>,
776                Mutability = Exclusive,
777                __IndirectTrap = NonRobust,
778            >,
779        );
780        assert_impl_all!(&[&u8]:
781            RustSpec<
782                Layout = Unstable,
783                Size = Co3Sized<Gt<Zero>>,
784                Alignment = <usize as RustSpec>::Alignment,
785                Trap = NonRobust,
786                Niche = WithNiche<Unstable>,
787                Mutability = Exclusive,
788                __IndirectTrap = NonRobust,
789            >,
790        );
791        assert_impl_all!(&mut [&u8]:
792            RustSpec<
793                Layout = Unstable,
794                Size = Co3Sized<Gt<Zero>>,
795                Alignment = <usize as RustSpec>::Alignment,
796                Trap = NonRobust,
797                Niche = WithNiche<Unstable>,
798                Mutability = Exclusive,
799                __IndirectTrap = NonRobust,
800            >,
801        );
802        #[cfg(feature = "alloc")]
803        assert_impl_all!(Box<[&u8]>:
804            RustSpec<
805                Layout = Unstable,
806                Size = Co3Sized<Gt<Zero>>,
807                Alignment = <usize as RustSpec>::Alignment,
808                Trap = NonRobust,
809                Niche = WithNiche<Unstable>,
810                Mutability = Exclusive,
811                __IndirectTrap = NonRobust,
812            >,
813        );
814        #[cfg(feature = "alloc")]
815        assert_impl_all!(Vec<&u8>:
816            RustSpec<
817                Layout = Unstable,
818                Size = Co3Sized<Gt<Zero>>,
819                Alignment = <usize as RustSpec>::Alignment,
820                Trap = NonRobust,
821                Niche = WithNiche<Unstable>,
822                Mutability = Exclusive,
823                __IndirectTrap = NonRobust,
824            >,
825        );
826        assert_impl_all!([&u8; 2]:
827            RustSpec<
828                Layout = Stable,
829                Size = Co3Sized<Gt<Zero>>,
830                Alignment = <usize as RustSpec>::Alignment,
831                Trap = NonRobust,
832                Niche = WithNiche<Unstable>,
833                Mutability = Exclusive,
834                __IndirectTrap = Robust,
835            >,
836        );
837        assert_impl_all!(Option<&u8>:
838            RustSpec<
839                Layout = Stable,
840                Size = Co3Sized<Gt<Zero>>,
841                Alignment = <usize as RustSpec>::Alignment,
842                Trap = Robust,
843                Niche = WithoutNiche,
844                Mutability = Exclusive,
845                __IndirectTrap = Robust,
846            >,
847        );
848    }
849
850    #[test]
851    fn transparent_ref() {
852        assert_impl_all!(&&bool:
853            RustSpec<
854                Layout = Stable,
855                Size = Co3Sized<Gt<Zero>>,
856                Alignment = <usize as RustSpec>::Alignment,
857                Trap = NonRobust,
858                Niche = WithNiche<Stable>,
859                Mutability = Exclusive,
860                __IndirectTrap = NonRobust,
861            >,
862        );
863        assert_impl_all!(&mut &bool:
864            RustSpec<
865                Layout = Stable,
866                Size = Co3Sized<Gt<Zero>>,
867                Alignment = <usize as RustSpec>::Alignment,
868                Trap = NonRobust,
869                Niche = WithNiche<Stable>,
870                Mutability = Exclusive,
871                __IndirectTrap = NonRobust,
872            >,
873        );
874        #[cfg(feature = "alloc")]
875        assert_impl_all!(Box<&bool>:
876            RustSpec<
877                Layout = Stable,
878                Size = Co3Sized<Gt<Zero>>,
879                Alignment = <usize as RustSpec>::Alignment,
880                Trap = NonRobust,
881                Niche = WithNiche<Stable>,
882                Mutability = Exclusive,
883                __IndirectTrap = NonRobust,
884            >,
885        );
886        assert_impl_all!(&[&bool]:
887            RustSpec<
888                Layout = Unstable,
889                Size = Co3Sized<Gt<Zero>>,
890                Alignment = <usize as RustSpec>::Alignment,
891                Trap = NonRobust,
892                Niche = WithNiche<Unstable>,
893                Mutability = Exclusive,
894                __IndirectTrap = NonRobust,
895            >,
896        );
897        #[cfg(feature = "alloc")]
898        assert_impl_all!(&mut [&bool]:
899            RustSpec<
900                Layout = Unstable,
901                Size = Co3Sized<Gt<Zero>>,
902                Alignment = <usize as RustSpec>::Alignment,
903                Trap = NonRobust,
904                Niche = WithNiche<Unstable>,
905                Mutability = Exclusive,
906                __IndirectTrap = NonRobust,
907            >,
908        );
909        #[cfg(feature = "alloc")]
910        assert_impl_all!(Box<[&bool]>:
911            RustSpec<
912                Layout = Unstable,
913                Size = Co3Sized<Gt<Zero>>,
914                Alignment = <usize as RustSpec>::Alignment,
915                Trap = NonRobust,
916                Niche = WithNiche<Unstable>,
917                Mutability = Exclusive,
918                __IndirectTrap = NonRobust,
919            >,
920        );
921        #[cfg(feature = "alloc")]
922        assert_impl_all!(Vec<&bool>:
923            RustSpec<
924                Layout = Unstable,
925                Size = Co3Sized<Gt<Zero>>,
926                Alignment = <usize as RustSpec>::Alignment,
927                Trap = NonRobust,
928                Niche = WithNiche<Unstable>,
929                Mutability = Exclusive,
930                __IndirectTrap = NonRobust,
931            >,
932        );
933        assert_impl_all!([&bool; 2]:
934            RustSpec<
935                Layout = Stable,
936                Size = Co3Sized<Gt<Zero>>,
937                Alignment = <usize as RustSpec>::Alignment,
938                Trap = NonRobust,
939                Niche = WithNiche<Unstable>,
940                Mutability = Exclusive,
941                __IndirectTrap = NonRobust,
942            >,
943        );
944        assert_impl_all!(Option<&bool>:
945            RustSpec<
946                Layout = Stable,
947                Size = Co3Sized<Gt<Zero>>,
948                Alignment = <usize as RustSpec>::Alignment,
949                Trap = NonRobust,
950                Niche = WithoutNiche,
951                Mutability = Exclusive,
952                __IndirectTrap = NonRobust,
953            >,
954        );
955    }
956
957    #[test]
958    fn robust_ref_mut() {
959        assert_impl_all!(&&mut u8:
960            RustSpec<
961                Layout = Stable,
962                Size = Co3Sized<Gt<Zero>>,
963                Alignment = <usize as RustSpec>::Alignment,
964                Trap = NonRobust,
965                Niche = WithNiche<Stable>,
966                Mutability = Exclusive,
967                __IndirectTrap = NonRobust,
968            >,
969        );
970        assert_impl_all!(&mut &mut u8:
971            RustSpec<
972                Layout = Stable,
973                Size = Co3Sized<Gt<Zero>>,
974                Alignment = <usize as RustSpec>::Alignment,
975                Trap = NonRobust,
976                Niche = WithNiche<Stable>,
977                Mutability = Exclusive,
978                __IndirectTrap = NonRobust,
979            >,
980        );
981        #[cfg(feature = "alloc")]
982        assert_impl_all!(Box<&mut u8>:
983            RustSpec<
984                Layout = Stable,
985                Size = Co3Sized<Gt<Zero>>,
986                Alignment = <usize as RustSpec>::Alignment,
987                Trap = NonRobust,
988                Niche = WithNiche<Stable>,
989                Mutability = Exclusive,
990                __IndirectTrap = NonRobust,
991            >,
992        );
993        assert_impl_all!(&[&mut u8]:
994            RustSpec<
995                Layout = Unstable,
996                Size = Co3Sized<Gt<Zero>>,
997                Alignment = <usize as RustSpec>::Alignment,
998                Trap = NonRobust,
999                Niche = WithNiche<Unstable>,
1000                Mutability = Exclusive,
1001                __IndirectTrap = NonRobust,
1002            >,
1003        );
1004        assert_impl_all!(&mut [&mut u8]:
1005            RustSpec<
1006                Layout = Unstable,
1007                Size = Co3Sized<Gt<Zero>>,
1008                Alignment = <usize as RustSpec>::Alignment,
1009                Trap = NonRobust,
1010                Niche = WithNiche<Unstable>,
1011                Mutability = Exclusive,
1012                __IndirectTrap = NonRobust,
1013            >,
1014        );
1015        #[cfg(feature = "alloc")]
1016        assert_impl_all!(Box<[&mut u8]>:
1017            RustSpec<
1018                Layout = Unstable,
1019                Size = Co3Sized<Gt<Zero>>,
1020                Alignment = <usize as RustSpec>::Alignment,
1021                Trap = NonRobust,
1022                Niche = WithNiche<Unstable>,
1023                Mutability = Exclusive,
1024                __IndirectTrap = NonRobust,
1025            >,
1026        );
1027        #[cfg(feature = "alloc")]
1028        assert_impl_all!(Vec<&mut u8>:
1029            RustSpec<
1030                Layout = Unstable,
1031                Size = Co3Sized<Gt<Zero>>,
1032                Alignment = <usize as RustSpec>::Alignment,
1033                Trap = NonRobust,
1034                Niche = WithNiche<Unstable>,
1035                Mutability = Exclusive,
1036                __IndirectTrap = NonRobust,
1037            >,
1038        );
1039        assert_impl_all!([&mut u8; 2]:
1040            RustSpec<
1041                Layout = Stable,
1042                Size = Co3Sized<Gt<Zero>>,
1043                Alignment = <usize as RustSpec>::Alignment,
1044                Trap = NonRobust,
1045                Niche = WithNiche<Unstable>,
1046                Mutability = Exclusive,
1047                __IndirectTrap = Robust,
1048            >,
1049        );
1050        assert_impl_all!(Option<&mut u8>:
1051            RustSpec<
1052                Layout = Stable,
1053                Size = Co3Sized<Gt<Zero>>,
1054                Alignment = <usize as RustSpec>::Alignment,
1055                Trap = Robust,
1056                Niche = WithoutNiche,
1057                Mutability = Exclusive,
1058                __IndirectTrap = Robust,
1059            >,
1060        );
1061    }
1062
1063    #[test]
1064    fn transparent_ref_mut() {
1065        assert_impl_all!(&&mut bool:
1066            RustSpec<
1067                Layout = Stable,
1068                Size = Co3Sized<Gt<Zero>>,
1069                Alignment = <usize as RustSpec>::Alignment,
1070                Trap = NonRobust,
1071                Niche = WithNiche<Stable>,
1072                Mutability = Exclusive,
1073                __IndirectTrap = NonRobust,
1074            >,
1075        );
1076        assert_impl_all!(&mut &mut bool:
1077            RustSpec<
1078                Layout = Stable,
1079                Size = Co3Sized<Gt<Zero>>,
1080                Alignment = <usize as RustSpec>::Alignment,
1081                Trap = NonRobust,
1082                Niche = WithNiche<Stable>,
1083                Mutability = Exclusive,
1084                __IndirectTrap = NonRobust,
1085            >,
1086        );
1087        #[cfg(feature = "alloc")]
1088        assert_impl_all!(Box<&mut bool>:
1089            RustSpec<
1090                Layout = Stable,
1091                Size = Co3Sized<Gt<Zero>>,
1092                Alignment = <usize as RustSpec>::Alignment,
1093                Trap = NonRobust,
1094                Niche = WithNiche<Stable>,
1095                Mutability = Exclusive,
1096                __IndirectTrap = NonRobust,
1097            >,
1098        );
1099        assert_impl_all!(&[&mut bool]:
1100            RustSpec<
1101                Layout = Unstable,
1102                Size = Co3Sized<Gt<Zero>>,
1103                Alignment = <usize as RustSpec>::Alignment,
1104                Trap = NonRobust,
1105                Niche = WithNiche<Unstable>,
1106                Mutability = Exclusive,
1107                __IndirectTrap = NonRobust,
1108            >,
1109        );
1110        assert_impl_all!(&mut [&mut bool]:
1111            RustSpec<
1112                Layout = Unstable,
1113                Size = Co3Sized<Gt<Zero>>,
1114                Alignment = <usize as RustSpec>::Alignment,
1115                Trap = NonRobust,
1116                Niche = WithNiche<Unstable>,
1117                Mutability = Exclusive,
1118                __IndirectTrap = NonRobust,
1119            >,
1120        );
1121        #[cfg(feature = "alloc")]
1122        assert_impl_all!(Box<[&mut bool]>:
1123            RustSpec<
1124                Layout = Unstable,
1125                Size = Co3Sized<Gt<Zero>>,
1126                Alignment = <usize as RustSpec>::Alignment,
1127                Trap = NonRobust,
1128                Niche = WithNiche<Unstable>,
1129                Mutability = Exclusive,
1130                __IndirectTrap = NonRobust,
1131            >,
1132        );
1133        #[cfg(feature = "alloc")]
1134        assert_impl_all!(Vec<&mut bool>:
1135            RustSpec<
1136                Layout = Unstable,
1137                Size = Co3Sized<Gt<Zero>>,
1138                Alignment = <usize as RustSpec>::Alignment,
1139                Trap = NonRobust,
1140                Niche = WithNiche<Unstable>,
1141                Mutability = Exclusive,
1142                __IndirectTrap = NonRobust,
1143            >,
1144        );
1145        assert_impl_all!([&mut bool; 2]:
1146            RustSpec<
1147                Layout = Stable,
1148                Size = Co3Sized<Gt<Zero>>,
1149                Alignment = <usize as RustSpec>::Alignment,
1150                Trap = NonRobust,
1151                Niche = WithNiche<Unstable>,
1152                Mutability = Exclusive,
1153                __IndirectTrap = NonRobust,
1154            >,
1155        );
1156        assert_impl_all!(Option<&mut bool>:
1157            RustSpec<
1158                Layout = Stable,
1159                Size = Co3Sized<Gt<Zero>>,
1160                Alignment = <usize as RustSpec>::Alignment,
1161                Trap = NonRobust,
1162                Niche = WithoutNiche,
1163                Mutability = Exclusive,
1164                __IndirectTrap = NonRobust,
1165            >,
1166        );
1167    }
1168}