Skip to main content

rust_spec/
lib.rs

1//! **Compile-time classification of types** according to the Rust specification.
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//! - [`trap`](layout): whether the value has trap representations.
9//! - [`niche`]: whether a type has a stable, unstable, or no niche value.
10//! - [`mutability`]: whether type can be mutated through shared access.
11//! - [`drop`](mod@drop): whether dropping runs custom or compiler-generated code.
12//! - [`Opaque`]: whether the value representation may be inspected.
13//!
14//! ## Layout
15//!
16//! Describes total reachable (through pointer indirection) representation stability:
17//! - [`Stable`]: compiler-guaranteed representation.
18//! - [`Unstable`]: representation is not guaranteed.
19//!
20//! ## Size
21//!
22//! Describes compile-time size and pointer metadata shape:
23//! - [`Sized`](size::Sized)<[`Zero`]>: compile-time known zero-sized type.
24//! - [`Sized`](size::Sized)<[`Gt`]<[`Zero`]>>: compile-time known non-zero-sized type.
25//! - [`MetaSized`](size::MetaSized)<[`SliceLike`](size::SliceLike)>: dynamically sized slice-like type.
26//! - [`MetaSized`](size::MetaSized)<[`DynTraitLike`](size::DynTraitLike)>: dynamically sized trait-object-like type.
27//! - [`ExternTypeLike`](size::ExternTypeLike): dynamically sized extern-type-like type.
28//! - [`NulTerminated`](size::NulTerminated): unsized nul-terminated data.
29//!
30//! ## Trap
31//!
32//! Describes total reachable (through pointer indirection) value-representation validity:
33//! - [`Robust`](layout::Robust): every bit pattern (through indirection) is valid.
34//! - [`NonRobust`](layout::NonRobust): some bit patterns are trap/invalid values.
35//!
36//! This classification does not establish provenance, alignment, lifetimes, or aliasing requirements
37//! for pointers or references. For example, `Option<&u8>` is `Robust`, but a non-null representation
38//! must still be a valid reference before constructing the value.
39//!
40//! ## Niche
41//!
42//! Describes whether and what kind of niche is available for the type:
43//! - [`WithoutNiche`]: no niche is available.
44//! - [`WithNiche`]<[`Stable`]>: compiler-guaranteed niche.
45//! - [`WithNiche`]<[`Unstable`]>: niche exists but is not guaranteed.
46//!
47//! **Use `#[rust_spec(custom_niche)]` when deriving [`RustSpec`] to select `WithNiche<Unstable>`**.
48//!
49//! ## Drop
50//!
51//! Describes the type's behavior when dropped:
52//! - [`NoDrop`]: dropping the type runs no drop glue.
53//! - [`AutoDrop`](drop::AutoDrop): owned contents need automatic drop glue.
54//! - [`drop::CustomDrop`]<[`NoDrop`]>: the type implements [`Drop`] and its contents need no automatic drop glue.
55//! - [`drop::CustomDrop`]<[`AutoDrop`](drop::AutoDrop)>: the type implements [`Drop`] and its contents need automatic drop glue.
56//!
57//! **Use `#[rust_spec(custom_drop)]` when deriving [`RustSpec`] for a type that implements `Drop`**.
58//!
59//! ## Mutability
60//!
61//! Describes whether a type has parts that can be mutated through shared access:
62//! - [`Exclusive<WithoutInterior>`](mutability::Exclusive): mutation requires exclusive non-interleaving access.
63//! - [`WithInterior<Robust>`](mutability::WithInterior): only robust parts can be mutated through shared access.
64//! - [`WithInterior<NonRobust>`](mutability::WithInterior): non-robust parts can be mutated through shared access.
65//!
66//! ## Opacity
67//!
68//! - [`NonOpaque`]: the value representation is not opaque.
69//! - [`Opaque`]: the value must appear only behind an indirection.
70//!
71//! **Use `#[rust_spec(opaque)]` when deriving [`RustSpec`] to classify type as `Opaque`**.
72//!
73//! # How to Use
74//!
75//! Derive [`RustSpec`] for your types, then use its associated marker families as bounds when implementing other traits:
76//!
77//! ```rust
78//! # #[cfg(feature = "derive")]
79//! # {
80//! use disjoint_impls::disjoint_impls;
81//! use rust_spec::{RustSpec, Stable, Unstable, niche::{WithNiche, WithoutNiche}};
82//!
83//! #[derive(RustSpec)]
84//! struct Header {
85//!     id: u32,
86//!     flags: u16,
87//! }
88//!
89//! disjoint_impls! {
90//!     trait NullableEncoding {
91//!         const NEEDS_TAG: bool;
92//!     }
93//!
94//!     impl<T: RustSpec<Niche = WithoutNiche>> NullableEncoding for T {
95//!         const NEEDS_TAG: bool = true;
96//!     }
97//!
98//!     impl<T: RustSpec<Niche = WithNiche<Stable>>> NullableEncoding for T {
99//!         const NEEDS_TAG: bool = false;
100//!     }
101//!
102//!     impl<T: RustSpec<Niche = WithNiche<Unstable>>> NullableEncoding for T {
103//!         const NEEDS_TAG: bool = false;
104//!     }
105//! }
106//!
107//! const HEADER_OPTION_NEEDS_TAG: bool = Header::NEEDS_TAG;
108//! # }
109//! ```
110//!
111//! Check out [CO3](https://github.com/mversic/co3) to see how this crate allows for building higher zero-cost abstractions.
112#![no_std]
113
114#[cfg(feature = "alloc")]
115extern crate alloc;
116extern crate self as rust_spec;
117
118#[cfg(feature = "alloc")]
119use alloc::boxed::Box;
120use core::{convert::Infallible, ops::Add, ptr::NonNull};
121
122#[cfg(feature = "alloc")]
123use crate::drop::{CustomDrop, DropKind};
124use crate::{
125    drop::{NeedsDrop, NoDrop},
126    layout::NonRobust,
127    mutability::PointerMutability,
128    niche::{NullableRepresentation, WithNiche, WithoutNiche},
129    size::PointerLayout,
130};
131#[cfg(feature = "derive")]
132pub use rust_spec_derive::RustSpec;
133
134mod core_impls;
135pub mod drop;
136pub mod layout;
137pub mod mutability;
138pub mod niche;
139mod primitives;
140pub mod size;
141mod tuple;
142
143type Sum<A, B> = <A as Add<B>>::Output;
144
145/// The output of the type-level [`Max`] operation.
146#[doc(hidden)]
147pub type Maximum<A, B> = <A as Max<B>>::Output;
148
149/// Marker for a compiler-guaranteed representation or niche.
150pub enum Stable {}
151
152/// Marker for a representation or niche that is not compiler-guaranteed.
153pub enum Unstable {}
154
155/// The value is opaque and must be placed behind an indirection.
156pub enum Opaque {}
157
158/// The value representation is not opaque.
159pub enum NonOpaque {}
160
161/// Marker for a zero-sized type.
162pub enum Zero {}
163
164/// Marker for a statically sized type greater than the given threshold.
165pub struct Gt<T>(core::marker::PhantomData<T>, Infallible);
166
167/// Marker for alignment one.
168#[doc(hidden)]
169pub enum One {}
170
171/// Type-level maximum used to combine alignment categories.
172#[doc(hidden)]
173pub trait Max<Rhs> {
174    type Output;
175}
176
177impl<Rhs> Max<Rhs> for One {
178    type Output = Rhs;
179}
180impl<Rhs> Max<Rhs> for Gt<One> {
181    type Output = Gt<One>;
182}
183
184/// Joined Rust-spec classification of a type.
185///
186/// # Safety hazards when deriving `RustSpec`
187///
188/// Check [`rust_spec_derive::RustSpec`].
189///
190/// # Safety
191///
192/// Implementors must classify `Self` truthfully according to each axis's documentation.
193/// [`Opaque`] types must be used only through indirection and consumers should not read them.
194pub unsafe trait RustSpec {
195    /// Representation-stability classification; see [`layout`].
196    type Layout;
197
198    /// Statically known, metadata-sized, or extern-type-like size classification; see [`size`].
199    type Size;
200
201    /// __Alignment classification; see the [crate root](crate) for [`One`] and [`Gt`].
202    #[doc(hidden)]
203    type __Alignment;
204
205    /// Trap-representation classification, assuming pointer and reference validity
206    /// is established separately; see [`layout`].
207    type Trap;
208
209    /// Niche availability classification; see [`niche`].
210    type Niche;
211
212    /// Whether `Self` declares `Drop`, has inner drop glue, or has no drop glue; see [`drop`](mod@drop).
213    type Drop;
214
215    /// Shared-access mutability classification; see [`mutability`].
216    type Mutability;
217
218    /// Whether the value representation is opaque; see [`Opaque`].
219    type Opacity;
220
221    /// Trap classification reachable through one or more supported pointer indirections; see [`layout`].
222    #[doc(hidden)]
223    type __IndirectTrap;
224}
225
226unsafe impl<R: ?Sized> RustSpec for NonNull<R>
227where
228    R: RustSpec<Size: PointerLayout, Mutability: PointerMutability>,
229    <R::Size as PointerLayout>::Output: Add<R::Layout>,
230{
231    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
232    type Size = size::Sized<Gt<Zero>>;
233    type __Alignment = <usize as RustSpec>::__Alignment;
234    type Trap = NonRobust;
235    type Niche = WithNiche<<R::Size as PointerLayout>::Output>;
236    type Drop = NoDrop;
237    type Mutability = <R::Mutability as PointerMutability>::Output;
238    type Opacity = NonOpaque;
239    type __IndirectTrap = R::Trap;
240}
241
242unsafe impl<R> RustSpec for Option<R>
243where
244    R: RustSpec<Niche: NullableRepresentation, Drop: drop::DropKind>,
245    <R::Niche as NullableRepresentation>::Layout: Add<R::Layout>,
246    <R::Niche as NullableRepresentation>::Trap: Add<R::__IndirectTrap>,
247{
248    type Layout = Sum<<R::Niche as NullableRepresentation>::Layout, R::Layout>;
249    type Size = size::Sized<Gt<Zero>>;
250    type __Alignment = R::__Alignment;
251    type Trap = Sum<<R::Niche as NullableRepresentation>::Trap, R::__IndirectTrap>;
252    type Niche = <R::Niche as NullableRepresentation>::Niche;
253    type Drop = NeedsDrop<R::Drop>;
254    type Mutability = R::Mutability;
255    type Opacity = NonOpaque;
256    type __IndirectTrap = R::__IndirectTrap;
257}
258
259unsafe impl<R: ?Sized> RustSpec for &R
260where
261    R: RustSpec<Size: PointerLayout, Mutability: PointerMutability>,
262    <R::Size as PointerLayout>::Output: Add<R::Layout>,
263{
264    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
265    type Size = size::Sized<Gt<Zero>>;
266    type __Alignment = <usize as RustSpec>::__Alignment;
267    type Trap = layout::NonRobust;
268    type Niche = WithNiche<<R::Size as PointerLayout>::Output>;
269    type Drop = drop::NoDrop;
270    type Mutability = <R::Mutability as PointerMutability>::Output;
271    type Opacity = NonOpaque;
272    type __IndirectTrap = R::Trap;
273}
274
275unsafe impl<R: ?Sized> RustSpec for &mut R
276where
277    R: RustSpec<Size: PointerLayout, Mutability: PointerMutability>,
278    <R::Size as PointerLayout>::Output: Add<R::Layout>,
279{
280    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
281    type Size = size::Sized<Gt<Zero>>;
282    type __Alignment = <usize as RustSpec>::__Alignment;
283    type Trap = layout::NonRobust;
284    type Niche = WithNiche<<R::Size as PointerLayout>::Output>;
285    type Drop = drop::NoDrop;
286    type Mutability = <R::Mutability as PointerMutability>::Output;
287    type Opacity = NonOpaque;
288    type __IndirectTrap = R::Trap;
289}
290
291#[cfg(feature = "alloc")]
292unsafe impl<R: ?Sized> RustSpec for Box<R>
293where
294    R: RustSpec<Size: PointerLayout, Drop: DropKind, Mutability: PointerMutability>,
295    <R::Size as PointerLayout>::Output: Add<R::Layout>,
296{
297    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
298    type Size = size::Sized<Gt<Zero>>;
299    type __Alignment = <usize as RustSpec>::__Alignment;
300    type Trap = layout::NonRobust;
301    type Niche = WithNiche<<R::Size as PointerLayout>::Output>;
302    type Drop = CustomDrop<NeedsDrop<R::Drop>>;
303    type Mutability = <R::Mutability as PointerMutability>::Output;
304    type Opacity = NonOpaque;
305    type __IndirectTrap = R::Trap;
306}
307
308unsafe impl<R: ?Sized> RustSpec for *const R
309where
310    R: RustSpec<Size: PointerLayout, Mutability: PointerMutability>,
311    <R::Size as PointerLayout>::Output: Add<R::Layout>,
312{
313    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
314    type Size = size::Sized<crate::Gt<Zero>>;
315    type __Alignment = <usize as RustSpec>::__Alignment;
316    type Trap = R::Trap;
317    type Niche = WithoutNiche;
318    type Drop = NoDrop;
319    type Mutability = <R::Mutability as PointerMutability>::Output;
320    type Opacity = NonOpaque;
321    type __IndirectTrap = R::Trap;
322}
323
324unsafe impl<R: ?Sized> RustSpec for *mut R
325where
326    R: RustSpec<Size: PointerLayout, Mutability: PointerMutability>,
327    <R::Size as PointerLayout>::Output: Add<R::Layout>,
328{
329    type Layout = Sum<<R::Size as PointerLayout>::Output, R::Layout>;
330    type Size = size::Sized<crate::Gt<Zero>>;
331    type __Alignment = <usize as RustSpec>::__Alignment;
332    type Trap = R::Trap;
333    type Niche = WithoutNiche;
334    type Drop = NoDrop;
335    type Mutability = <R::Mutability as PointerMutability>::Output;
336    type Opacity = NonOpaque;
337    type __IndirectTrap = R::Trap;
338}
339
340#[cfg(test)]
341mod tests {
342    #[cfg(feature = "alloc")]
343    use alloc::vec::Vec;
344
345    use static_assertions::assert_impl_all;
346
347    use super::*;
348    use {
349        layout::{NonRobust, Robust},
350        mutability::{Exclusive, WithoutInterior},
351        niche::{WithNiche, WithoutNiche},
352        size::{Gt, Sized as RustSpecSized},
353    };
354
355    #[test]
356    fn indirect_trap_follows_supported_pointers_only() {
357        assert_impl_all!(&u8: RustSpec<__IndirectTrap = Robust>);
358        assert_impl_all!(&bool: RustSpec<__IndirectTrap = NonRobust>);
359        assert_impl_all!(&&u8: RustSpec<__IndirectTrap = NonRobust>);
360        assert_impl_all!(Option<&u8>: RustSpec<__IndirectTrap = Robust>);
361        assert_impl_all!(*const bool: RustSpec<__IndirectTrap = NonRobust>);
362    }
363
364    #[test]
365    fn transparent_type() {
366        assert_impl_all!(bool:
367            RustSpec<
368                Layout = Stable,
369                Size = RustSpecSized<Gt<Zero>>,
370                __Alignment = One,
371                Trap = NonRobust,
372                Niche = WithNiche<Unstable>,
373                Mutability = Exclusive<WithoutInterior>,
374                __IndirectTrap = Robust,
375            >,
376        );
377        assert_impl_all!(&bool:
378            RustSpec<
379                Layout = Stable,
380                Size = RustSpecSized<Gt<Zero>>,
381                __Alignment = <usize as RustSpec>::__Alignment,
382                Trap = NonRobust,
383                Niche = WithNiche<Stable>,
384                Mutability = Exclusive<WithoutInterior>,
385                __IndirectTrap = NonRobust,
386            >,
387        );
388        assert_impl_all!(&mut bool:
389            RustSpec<
390                Layout = Stable,
391                Size = RustSpecSized<Gt<Zero>>,
392                __Alignment = <usize as RustSpec>::__Alignment,
393                Trap = NonRobust,
394                Niche = WithNiche<Stable>,
395                Mutability = Exclusive<WithoutInterior>,
396                __IndirectTrap = NonRobust,
397            >,
398        );
399        #[cfg(feature = "alloc")]
400        assert_impl_all!(Box<bool>:
401            RustSpec<
402                Layout = Stable,
403                Size = RustSpecSized<Gt<Zero>>,
404                __Alignment = <usize as RustSpec>::__Alignment,
405                Trap = NonRobust,
406                Niche = WithNiche<Stable>,
407                Mutability = Exclusive<WithoutInterior>,
408                __IndirectTrap = NonRobust,
409            >,
410        );
411        assert_impl_all!(&[bool]:
412            RustSpec<
413                Layout = Unstable,
414                Size = RustSpecSized<Gt<Zero>>,
415                __Alignment = <usize as RustSpec>::__Alignment,
416                Trap = NonRobust,
417                Niche = WithNiche<Unstable>,
418                Mutability = Exclusive<WithoutInterior>,
419                __IndirectTrap = NonRobust,
420            >,
421        );
422        #[cfg(feature = "alloc")]
423        assert_impl_all!(&mut [bool]:
424            RustSpec<
425                Layout = Unstable,
426                Size = RustSpecSized<Gt<Zero>>,
427                __Alignment = <usize as RustSpec>::__Alignment,
428                Trap = NonRobust,
429                Niche = WithNiche<Unstable>,
430                Mutability = Exclusive<WithoutInterior>,
431                __IndirectTrap = NonRobust,
432            >,
433        );
434        #[cfg(feature = "alloc")]
435        assert_impl_all!(Box<[bool]>:
436            RustSpec<
437                Layout = Unstable,
438                Size = RustSpecSized<Gt<Zero>>,
439                __Alignment = <usize as RustSpec>::__Alignment,
440                Trap = NonRobust,
441                Niche = WithNiche<Unstable>,
442                Mutability = Exclusive<WithoutInterior>,
443                __IndirectTrap = NonRobust,
444            >,
445        );
446        #[cfg(feature = "alloc")]
447        assert_impl_all!(Vec<bool>:
448            RustSpec<
449                Layout = Unstable,
450                Size = RustSpecSized<Gt<Zero>>,
451                __Alignment = <usize as RustSpec>::__Alignment,
452                Trap = NonRobust,
453                Niche = WithNiche<Unstable>,
454                Mutability = Exclusive<WithoutInterior>,
455                __IndirectTrap = NonRobust,
456            >,
457        );
458        assert_impl_all!([bool; 2]:
459            RustSpec<
460                Layout = Stable,
461                Size = RustSpecSized<Gt<Zero>>,
462                __Alignment = One,
463                Trap = NonRobust,
464                Niche = WithNiche<Unstable>,
465                Mutability = Exclusive<WithoutInterior>,
466                __IndirectTrap = Robust,
467            >,
468        );
469        // FIXME:
470        //assert_impl_all!(Option<bool>:
471        //    RustSpec<
472        //        Layout = Unstable,
473        //        Size = RustSpecSized<Gt<Zero>>,
474        //        Trap = NonRobust,
475        //        Niche = WithNiche<Unstable>,
476        //        Mutability = Exclusive<WithoutInterior>,
477        //    >,
478        //);
479    }
480
481    #[test]
482    fn option_stable_niche_layout() {
483        use core::num::NonZeroU8;
484
485        assert_impl_all!(Option<NonZeroU8>:
486            RustSpec<
487                Layout = Stable,
488                Size = RustSpecSized<Gt<Zero>>,
489                __Alignment = One,
490                Trap = Robust,
491                Niche = WithoutNiche,
492                Mutability = Exclusive<WithoutInterior>,
493                __IndirectTrap = Robust,
494            >,
495        );
496        assert_impl_all!(Option<&u8>:
497            RustSpec<
498                Layout = Stable,
499                Size = RustSpecSized<Gt<Zero>>,
500                __Alignment = <usize as RustSpec>::__Alignment,
501                Trap = Robust,
502                Niche = WithoutNiche,
503                Mutability = Exclusive<WithoutInterior>,
504                __IndirectTrap = Robust,
505            >,
506        );
507        assert_impl_all!(Option<&(u8, u8, u8)>:
508            RustSpec<
509                Layout = Unstable,
510                Size = RustSpecSized<Gt<Zero>>,
511                __Alignment = <usize as RustSpec>::__Alignment,
512                Trap = Robust,
513                Niche = WithoutNiche,
514                Mutability = Exclusive<WithoutInterior>,
515                __IndirectTrap = Robust,
516            >,
517        );
518        assert_impl_all!(Option<&NonZeroU8>:
519            RustSpec<
520                Layout = Stable,
521                Size = RustSpecSized<Gt<Zero>>,
522                __Alignment = <usize as RustSpec>::__Alignment,
523                Trap = NonRobust,
524                Niche = WithoutNiche,
525                Mutability = Exclusive<WithoutInterior>,
526                __IndirectTrap = NonRobust,
527            >,
528        );
529    }
530
531    #[test]
532    fn result_stable_niche_layout() {
533        use core::num::NonZeroU8;
534
535        assert_impl_all!(Result<NonZeroU8, ()>:
536            RustSpec<
537                Layout = Stable,
538                Size = RustSpecSized<Gt<Zero>>,
539                __Alignment = One,
540                Trap = Robust,
541                Niche = WithoutNiche,
542                Mutability = Exclusive<WithoutInterior>,
543                __IndirectTrap = Robust,
544            >,
545        );
546        assert_impl_all!(Result<&u8, ()>:
547            RustSpec<
548                Layout = Stable,
549                Size = RustSpecSized<Gt<Zero>>,
550                __Alignment = <usize as RustSpec>::__Alignment,
551                Trap = Robust,
552                Niche = WithoutNiche,
553                Mutability = Exclusive<WithoutInterior>,
554                __IndirectTrap = Robust,
555            >,
556        );
557        assert_impl_all!(Result<&NonZeroU8, ()>:
558            RustSpec<
559                Layout = Stable,
560                Size = RustSpecSized<Gt<Zero>>,
561                __Alignment = <usize as RustSpec>::__Alignment,
562                Trap = NonRobust,
563                Niche = WithoutNiche,
564                Mutability = Exclusive<WithoutInterior>,
565                __IndirectTrap = NonRobust,
566            >,
567        );
568        assert_impl_all!(Result<(), NonZeroU8>:
569            RustSpec<
570                Layout = Stable,
571                Size = RustSpecSized<Gt<Zero>>,
572                __Alignment = One,
573                Trap = Robust,
574                Niche = WithoutNiche,
575                Mutability = Exclusive<WithoutInterior>,
576                __IndirectTrap = Robust,
577            >,
578        );
579        assert_impl_all!(Result<&mut u8, ()>:
580            RustSpec<
581                Layout = Stable,
582                Size = RustSpecSized<Gt<Zero>>,
583                __Alignment = <usize as RustSpec>::__Alignment,
584                Trap = Robust,
585                Niche = WithoutNiche,
586                Mutability = Exclusive<WithoutInterior>,
587                __IndirectTrap = Robust,
588            >,
589        );
590    }
591
592    #[test]
593    fn robust_ref() {
594        assert_impl_all!(&&u8:
595            RustSpec<
596                Layout = Stable,
597                Size = RustSpecSized<Gt<Zero>>,
598                __Alignment = <usize as RustSpec>::__Alignment,
599                Trap = NonRobust,
600                Niche = WithNiche<Stable>,
601                Mutability = Exclusive<WithoutInterior>,
602                __IndirectTrap = NonRobust,
603            >,
604        );
605        assert_impl_all!(&mut &u8:
606            RustSpec<
607                Layout = Stable,
608                Size = RustSpecSized<Gt<Zero>>,
609                __Alignment = <usize as RustSpec>::__Alignment,
610                Trap = NonRobust,
611                Niche = WithNiche<Stable>,
612                Mutability = Exclusive<WithoutInterior>,
613                __IndirectTrap = NonRobust,
614            >,
615        );
616        #[cfg(feature = "alloc")]
617        assert_impl_all!(Box<&bool>:
618            RustSpec<
619                Layout = Stable,
620                Size = RustSpecSized<Gt<Zero>>,
621                __Alignment = <usize as RustSpec>::__Alignment,
622                Trap = NonRobust,
623                Niche = WithNiche<Stable>,
624                Mutability = Exclusive<WithoutInterior>,
625                __IndirectTrap = NonRobust,
626            >,
627        );
628        assert_impl_all!(&[&u8]:
629            RustSpec<
630                Layout = Unstable,
631                Size = RustSpecSized<Gt<Zero>>,
632                __Alignment = <usize as RustSpec>::__Alignment,
633                Trap = NonRobust,
634                Niche = WithNiche<Unstable>,
635                Mutability = Exclusive<WithoutInterior>,
636                __IndirectTrap = NonRobust,
637            >,
638        );
639        assert_impl_all!(&mut [&u8]:
640            RustSpec<
641                Layout = Unstable,
642                Size = RustSpecSized<Gt<Zero>>,
643                __Alignment = <usize as RustSpec>::__Alignment,
644                Trap = NonRobust,
645                Niche = WithNiche<Unstable>,
646                Mutability = Exclusive<WithoutInterior>,
647                __IndirectTrap = NonRobust,
648            >,
649        );
650        #[cfg(feature = "alloc")]
651        assert_impl_all!(Box<[&u8]>:
652            RustSpec<
653                Layout = Unstable,
654                Size = RustSpecSized<Gt<Zero>>,
655                __Alignment = <usize as RustSpec>::__Alignment,
656                Trap = NonRobust,
657                Niche = WithNiche<Unstable>,
658                Mutability = Exclusive<WithoutInterior>,
659                __IndirectTrap = NonRobust,
660            >,
661        );
662        #[cfg(feature = "alloc")]
663        assert_impl_all!(Vec<&u8>:
664            RustSpec<
665                Layout = Unstable,
666                Size = RustSpecSized<Gt<Zero>>,
667                __Alignment = <usize as RustSpec>::__Alignment,
668                Trap = NonRobust,
669                Niche = WithNiche<Unstable>,
670                Mutability = Exclusive<WithoutInterior>,
671                __IndirectTrap = NonRobust,
672            >,
673        );
674        assert_impl_all!([&u8; 2]:
675            RustSpec<
676                Layout = Stable,
677                Size = RustSpecSized<Gt<Zero>>,
678                __Alignment = <usize as RustSpec>::__Alignment,
679                Trap = NonRobust,
680                Niche = WithNiche<Unstable>,
681                Mutability = Exclusive<WithoutInterior>,
682                __IndirectTrap = Robust,
683            >,
684        );
685        assert_impl_all!(Option<&u8>:
686            RustSpec<
687                Layout = Stable,
688                Size = RustSpecSized<Gt<Zero>>,
689                __Alignment = <usize as RustSpec>::__Alignment,
690                Trap = Robust,
691                Niche = WithoutNiche,
692                Mutability = Exclusive<WithoutInterior>,
693                __IndirectTrap = Robust,
694            >,
695        );
696    }
697
698    #[test]
699    fn transparent_ref() {
700        assert_impl_all!(&&bool:
701            RustSpec<
702                Layout = Stable,
703                Size = RustSpecSized<Gt<Zero>>,
704                __Alignment = <usize as RustSpec>::__Alignment,
705                Trap = NonRobust,
706                Niche = WithNiche<Stable>,
707                Mutability = Exclusive<WithoutInterior>,
708                __IndirectTrap = NonRobust,
709            >,
710        );
711        assert_impl_all!(&mut &bool:
712            RustSpec<
713                Layout = Stable,
714                Size = RustSpecSized<Gt<Zero>>,
715                __Alignment = <usize as RustSpec>::__Alignment,
716                Trap = NonRobust,
717                Niche = WithNiche<Stable>,
718                Mutability = Exclusive<WithoutInterior>,
719                __IndirectTrap = NonRobust,
720            >,
721        );
722        #[cfg(feature = "alloc")]
723        assert_impl_all!(Box<&bool>:
724            RustSpec<
725                Layout = Stable,
726                Size = RustSpecSized<Gt<Zero>>,
727                __Alignment = <usize as RustSpec>::__Alignment,
728                Trap = NonRobust,
729                Niche = WithNiche<Stable>,
730                Mutability = Exclusive<WithoutInterior>,
731                __IndirectTrap = NonRobust,
732            >,
733        );
734        assert_impl_all!(&[&bool]:
735            RustSpec<
736                Layout = Unstable,
737                Size = RustSpecSized<Gt<Zero>>,
738                __Alignment = <usize as RustSpec>::__Alignment,
739                Trap = NonRobust,
740                Niche = WithNiche<Unstable>,
741                Mutability = Exclusive<WithoutInterior>,
742                __IndirectTrap = NonRobust,
743            >,
744        );
745        #[cfg(feature = "alloc")]
746        assert_impl_all!(&mut [&bool]:
747            RustSpec<
748                Layout = Unstable,
749                Size = RustSpecSized<Gt<Zero>>,
750                __Alignment = <usize as RustSpec>::__Alignment,
751                Trap = NonRobust,
752                Niche = WithNiche<Unstable>,
753                Mutability = Exclusive<WithoutInterior>,
754                __IndirectTrap = NonRobust,
755            >,
756        );
757        #[cfg(feature = "alloc")]
758        assert_impl_all!(Box<[&bool]>:
759            RustSpec<
760                Layout = Unstable,
761                Size = RustSpecSized<Gt<Zero>>,
762                __Alignment = <usize as RustSpec>::__Alignment,
763                Trap = NonRobust,
764                Niche = WithNiche<Unstable>,
765                Mutability = Exclusive<WithoutInterior>,
766                __IndirectTrap = NonRobust,
767            >,
768        );
769        #[cfg(feature = "alloc")]
770        assert_impl_all!(Vec<&bool>:
771            RustSpec<
772                Layout = Unstable,
773                Size = RustSpecSized<Gt<Zero>>,
774                __Alignment = <usize as RustSpec>::__Alignment,
775                Trap = NonRobust,
776                Niche = WithNiche<Unstable>,
777                Mutability = Exclusive<WithoutInterior>,
778                __IndirectTrap = NonRobust,
779            >,
780        );
781        assert_impl_all!([&bool; 2]:
782            RustSpec<
783                Layout = Stable,
784                Size = RustSpecSized<Gt<Zero>>,
785                __Alignment = <usize as RustSpec>::__Alignment,
786                Trap = NonRobust,
787                Niche = WithNiche<Unstable>,
788                Mutability = Exclusive<WithoutInterior>,
789                __IndirectTrap = NonRobust,
790            >,
791        );
792        assert_impl_all!(Option<&bool>:
793            RustSpec<
794                Layout = Stable,
795                Size = RustSpecSized<Gt<Zero>>,
796                __Alignment = <usize as RustSpec>::__Alignment,
797                Trap = NonRobust,
798                Niche = WithoutNiche,
799                Mutability = Exclusive<WithoutInterior>,
800                __IndirectTrap = NonRobust,
801            >,
802        );
803    }
804
805    #[test]
806    fn robust_ref_mut() {
807        assert_impl_all!(&&mut u8:
808            RustSpec<
809                Layout = Stable,
810                Size = RustSpecSized<Gt<Zero>>,
811                __Alignment = <usize as RustSpec>::__Alignment,
812                Trap = NonRobust,
813                Niche = WithNiche<Stable>,
814                Mutability = Exclusive<WithoutInterior>,
815                __IndirectTrap = NonRobust,
816            >,
817        );
818        assert_impl_all!(&mut &mut u8:
819            RustSpec<
820                Layout = Stable,
821                Size = RustSpecSized<Gt<Zero>>,
822                __Alignment = <usize as RustSpec>::__Alignment,
823                Trap = NonRobust,
824                Niche = WithNiche<Stable>,
825                Mutability = Exclusive<WithoutInterior>,
826                __IndirectTrap = NonRobust,
827            >,
828        );
829        #[cfg(feature = "alloc")]
830        assert_impl_all!(Box<&mut u8>:
831            RustSpec<
832                Layout = Stable,
833                Size = RustSpecSized<Gt<Zero>>,
834                __Alignment = <usize as RustSpec>::__Alignment,
835                Trap = NonRobust,
836                Niche = WithNiche<Stable>,
837                Mutability = Exclusive<WithoutInterior>,
838                __IndirectTrap = NonRobust,
839            >,
840        );
841        assert_impl_all!(&[&mut u8]:
842            RustSpec<
843                Layout = Unstable,
844                Size = RustSpecSized<Gt<Zero>>,
845                __Alignment = <usize as RustSpec>::__Alignment,
846                Trap = NonRobust,
847                Niche = WithNiche<Unstable>,
848                Mutability = Exclusive<WithoutInterior>,
849                __IndirectTrap = NonRobust,
850            >,
851        );
852        assert_impl_all!(&mut [&mut u8]:
853            RustSpec<
854                Layout = Unstable,
855                Size = RustSpecSized<Gt<Zero>>,
856                __Alignment = <usize as RustSpec>::__Alignment,
857                Trap = NonRobust,
858                Niche = WithNiche<Unstable>,
859                Mutability = Exclusive<WithoutInterior>,
860                __IndirectTrap = NonRobust,
861            >,
862        );
863        #[cfg(feature = "alloc")]
864        assert_impl_all!(Box<[&mut u8]>:
865            RustSpec<
866                Layout = Unstable,
867                Size = RustSpecSized<Gt<Zero>>,
868                __Alignment = <usize as RustSpec>::__Alignment,
869                Trap = NonRobust,
870                Niche = WithNiche<Unstable>,
871                Mutability = Exclusive<WithoutInterior>,
872                __IndirectTrap = NonRobust,
873            >,
874        );
875        #[cfg(feature = "alloc")]
876        assert_impl_all!(Vec<&mut u8>:
877            RustSpec<
878                Layout = Unstable,
879                Size = RustSpecSized<Gt<Zero>>,
880                __Alignment = <usize as RustSpec>::__Alignment,
881                Trap = NonRobust,
882                Niche = WithNiche<Unstable>,
883                Mutability = Exclusive<WithoutInterior>,
884                __IndirectTrap = NonRobust,
885            >,
886        );
887        assert_impl_all!([&mut u8; 2]:
888            RustSpec<
889                Layout = Stable,
890                Size = RustSpecSized<Gt<Zero>>,
891                __Alignment = <usize as RustSpec>::__Alignment,
892                Trap = NonRobust,
893                Niche = WithNiche<Unstable>,
894                Mutability = Exclusive<WithoutInterior>,
895                __IndirectTrap = Robust,
896            >,
897        );
898        assert_impl_all!(Option<&mut u8>:
899            RustSpec<
900                Layout = Stable,
901                Size = RustSpecSized<Gt<Zero>>,
902                __Alignment = <usize as RustSpec>::__Alignment,
903                Trap = Robust,
904                Niche = WithoutNiche,
905                Mutability = Exclusive<WithoutInterior>,
906                __IndirectTrap = Robust,
907            >,
908        );
909    }
910
911    #[test]
912    fn transparent_ref_mut() {
913        assert_impl_all!(&&mut bool:
914            RustSpec<
915                Layout = Stable,
916                Size = RustSpecSized<Gt<Zero>>,
917                __Alignment = <usize as RustSpec>::__Alignment,
918                Trap = NonRobust,
919                Niche = WithNiche<Stable>,
920                Mutability = Exclusive<WithoutInterior>,
921                __IndirectTrap = NonRobust,
922            >,
923        );
924        assert_impl_all!(&mut &mut bool:
925            RustSpec<
926                Layout = Stable,
927                Size = RustSpecSized<Gt<Zero>>,
928                __Alignment = <usize as RustSpec>::__Alignment,
929                Trap = NonRobust,
930                Niche = WithNiche<Stable>,
931                Mutability = Exclusive<WithoutInterior>,
932                __IndirectTrap = NonRobust,
933            >,
934        );
935        #[cfg(feature = "alloc")]
936        assert_impl_all!(Box<&mut bool>:
937            RustSpec<
938                Layout = Stable,
939                Size = RustSpecSized<Gt<Zero>>,
940                __Alignment = <usize as RustSpec>::__Alignment,
941                Trap = NonRobust,
942                Niche = WithNiche<Stable>,
943                Mutability = Exclusive<WithoutInterior>,
944                __IndirectTrap = NonRobust,
945            >,
946        );
947        assert_impl_all!(&[&mut bool]:
948            RustSpec<
949                Layout = Unstable,
950                Size = RustSpecSized<Gt<Zero>>,
951                __Alignment = <usize as RustSpec>::__Alignment,
952                Trap = NonRobust,
953                Niche = WithNiche<Unstable>,
954                Mutability = Exclusive<WithoutInterior>,
955                __IndirectTrap = NonRobust,
956            >,
957        );
958        assert_impl_all!(&mut [&mut bool]:
959            RustSpec<
960                Layout = Unstable,
961                Size = RustSpecSized<Gt<Zero>>,
962                __Alignment = <usize as RustSpec>::__Alignment,
963                Trap = NonRobust,
964                Niche = WithNiche<Unstable>,
965                Mutability = Exclusive<WithoutInterior>,
966                __IndirectTrap = NonRobust,
967            >,
968        );
969        #[cfg(feature = "alloc")]
970        assert_impl_all!(Box<[&mut bool]>:
971            RustSpec<
972                Layout = Unstable,
973                Size = RustSpecSized<Gt<Zero>>,
974                __Alignment = <usize as RustSpec>::__Alignment,
975                Trap = NonRobust,
976                Niche = WithNiche<Unstable>,
977                Mutability = Exclusive<WithoutInterior>,
978                __IndirectTrap = NonRobust,
979            >,
980        );
981        #[cfg(feature = "alloc")]
982        assert_impl_all!(Vec<&mut bool>:
983            RustSpec<
984                Layout = Unstable,
985                Size = RustSpecSized<Gt<Zero>>,
986                __Alignment = <usize as RustSpec>::__Alignment,
987                Trap = NonRobust,
988                Niche = WithNiche<Unstable>,
989                Mutability = Exclusive<WithoutInterior>,
990                __IndirectTrap = NonRobust,
991            >,
992        );
993        assert_impl_all!([&mut bool; 2]:
994            RustSpec<
995                Layout = Stable,
996                Size = RustSpecSized<Gt<Zero>>,
997                __Alignment = <usize as RustSpec>::__Alignment,
998                Trap = NonRobust,
999                Niche = WithNiche<Unstable>,
1000                Mutability = Exclusive<WithoutInterior>,
1001                __IndirectTrap = NonRobust,
1002            >,
1003        );
1004        assert_impl_all!(Option<&mut bool>:
1005            RustSpec<
1006                Layout = Stable,
1007                Size = RustSpecSized<Gt<Zero>>,
1008                __Alignment = <usize as RustSpec>::__Alignment,
1009                Trap = NonRobust,
1010                Niche = WithoutNiche,
1011                Mutability = Exclusive<WithoutInterior>,
1012                __IndirectTrap = NonRobust,
1013            >,
1014        );
1015    }
1016}