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