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//! - `alignment`: whether alignment is one or greater than one.
9//! - [`trap`](layout): whether the value has trap representations.
10//! - [`niche`]: whether a type has a stable, unstable, or no niche value.
11//! - [`mutability`]: whether type can be mutated through shared access.
12//! - [`drop`](mod@drop): whether dropping runs custom or compiler-generated code.
13//! - [`Opaque`]: whether the value representation may be inspected.
14//!
15//! ## Layout
16//!
17//! Describes total reachable (through pointer indirection) representation stability:
18//! - [`Stable`]: compiler-guaranteed representation.
19//! - [`Unstable`]: representation is not guaranteed.
20//!
21//! ## Size
22//!
23//! Describes compile-time size and pointer metadata shape:
24//! - [`Sized`](size::Sized)<[`Zero`]>: compile-time known zero-sized type.
25//! - [`Sized`](size::Sized)<[`Gt`]<[`Zero`]>>: compile-time known non-zero-sized type.
26//! - [`MetaSized`](size::MetaSized)<[`SliceLike`](size::SliceLike)>: dynamically sized slice-like type.
27//! - [`MetaSized`](size::MetaSized)<[`DynTraitLike`](size::DynTraitLike)>: dynamically sized trait-object-like type.
28//! - [`ExternTypeLike`](size::ExternTypeLike): dynamically sized extern-type-like type.
29//! - [`NulTerminated`](size::NulTerminated): unsized nul-terminated data.
30//!
31//! ## Alignment
32//!
33//! - [`One`] means alignment is exactly one;
34//! - [`Gt`]<[`One`]> means it is greater than one.
35//!
36//! ## Trap
37//!
38//! Describes total reachable (through pointer indirection) value-representation validity:
39//! - [`Robust`](layout::Robust): every bit pattern (through indirection) is valid.
40//! - [`NonRobust`](layout::NonRobust): some bit patterns are trap/invalid values.
41//!
42//! This classification does not establish provenance, alignment, lifetimes, or aliasing requirements
43//! for pointers or references. For example, `Option<&u8>` is `Robust`, but a non-null representation
44//! must still be a valid reference before constructing the value.
45//!
46//! ## Niche
47//!
48//! Describes whether and what kind of niche is available for the type:
49//! - [`WithoutNiche`]: no niche is available.
50//! - [`WithNiche`]<[`Stable`]>: compiler-guaranteed niche.
51//! - [`WithNiche`]<[`Unstable`]>: niche exists but is not guaranteed.
52//!
53//! **Use `#[rust_spec(custom_niche)]` when deriving [`RustSpec`] to select `WithNiche<Unstable>`**.
54//!
55//! ## Drop
56//!
57//! Describes the type's behavior when dropped:
58//! - [`NoDrop`]: dropping the type runs no drop glue.
59//! - [`AutoDrop`](drop::AutoDrop): owned contents need automatic drop glue.
60//! - [`drop::CustomDrop`]<[`NoDrop`]>: the type implements [`Drop`] and its contents need no automatic drop glue.
61//! - [`drop::CustomDrop`]<[`AutoDrop`](drop::AutoDrop)>: the type implements [`Drop`] and its contents need automatic drop glue.
62//!
63//! **Use `#[rust_spec(custom_drop)]` when deriving [`RustSpec`] for a type that implements `Drop`**.
64//!
65//! ## Mutability
66//!
67//! Describes whether a type has parts that can be mutated through shared access:
68//! - [`Exclusive`](mutability::Exclusive): mutation requires exclusive non-interleaving access.
69//! - [`WithInterior`](mutability::WithInterior): a part can be mutated through shared access.
70//!
71//! ## Opacity
72//!
73//! - [`NonOpaque`]: the value representation is not opaque.
74//! - [`Opaque`]: the value must appear only behind an indirection.
75//!
76//! **Use `#[rust_spec(opaque)]` when deriving [`RustSpec`] to classify type as `Opaque`**.
77//!
78//! # How to Use
79//!
80//! Derive [`RustSpec`] for your types, then use its associated marker families as bounds when implementing other traits:
81//!
82//! ```rust
83//! # #[cfg(feature = "derive")]
84//! # {
85//! use disjoint_impls::disjoint_impls;
86//! use rust_spec::{RustSpec, Stable, Unstable, niche::{WithNiche, WithoutNiche}};
87//!
88//! #[derive(RustSpec)]
89//! struct Header {
90//!     id: u32,
91//!     flags: u16,
92//! }
93//!
94//! disjoint_impls! {
95//!     trait NullableEncoding {
96//!         const NEEDS_TAG: bool;
97//!     }
98//!
99//!     impl<T: RustSpec<Niche = WithoutNiche>> NullableEncoding for T {
100//!         const NEEDS_TAG: bool = true;
101//!     }
102//!
103//!     impl<T: RustSpec<Niche = WithNiche<Stable>>> NullableEncoding for T {
104//!         const NEEDS_TAG: bool = false;
105//!     }
106//!
107//!     impl<T: RustSpec<Niche = WithNiche<Unstable>>> NullableEncoding for T {
108//!         const NEEDS_TAG: bool = false;
109//!     }
110//! }
111//!
112//! const HEADER_OPTION_NEEDS_TAG: bool = Header::NEEDS_TAG;
113//! # }
114//! ```
115//!
116//! Check out [CO3](https://github.com/mversic/co3) to see how this crate allows for building higher zero-cost abstractions.
117#![no_std]
118
119#[cfg(feature = "alloc")]
120extern crate alloc;
121extern crate self as rust_spec;
122
123#[cfg(feature = "alloc")]
124use alloc::boxed::Box;
125use core::{ops::Add, ptr::NonNull};
126
127#[cfg(feature = "alloc")]
128use crate::drop::{CustomDrop, DropKind};
129use crate::{
130    drop::NoDrop,
131    layout::NonRobust,
132    niche::{WithNiche, WithoutNiche},
133    size::{MetadataKind, SizedKind},
134};
135use disjoint_impls::disjoint_impls;
136#[cfg(feature = "derive")]
137pub use rust_spec_derive::RustSpec;
138
139mod core_impls;
140pub mod drop;
141pub mod layout;
142pub mod mutability;
143pub mod niche;
144
145mod primitives;
146pub mod size;
147
148mod tuple;
149
150/// Marker for a compiler-guaranteed representation or niche.
151pub enum Stable {}
152
153/// Marker for a representation or niche that is not compiler-guaranteed.
154pub enum Unstable {}
155
156/// The value is opaque and must be placed behind an indirection.
157pub enum Opaque {}
158
159/// The value representation is not opaque.
160pub enum NonOpaque {}
161
162/// Marker for a zero-sized type.
163pub enum Zero {}
164
165/// Marker for a statically sized type greater than the given threshold.
166pub struct Gt<T>(core::marker::PhantomData<T>);
167
168/// Marker for alignment one.
169pub enum One {}
170
171/// Type-level maximum used to combine alignment categories.
172pub trait Max<Rhs> {
173    type Output;
174}
175
176impl<Rhs> Max<Rhs> for One {
177    type Output = Rhs;
178}
179impl<Rhs> Max<Rhs> for Gt<One> {
180    type Output = Gt<One>;
181}
182
183trait WithoutOrUnstableNiche {}
184
185impl WithoutOrUnstableNiche for WithoutNiche {}
186impl WithoutOrUnstableNiche for WithNiche<Unstable> {}
187
188disjoint_impls! {
189    /// Joined Rust-spec classification of a type.
190    ///
191    /// # Safety hazards when deriving `RustSpec`
192    ///
193    /// Check [`rust_spec_derive::RustSpec`].
194    ///
195    /// # Safety
196    ///
197    /// Implementors must classify `Self` truthfully according to each axis's documentation.
198    /// [`Opaque`] types must be used only through indirection and consumers should not read them.
199    pub unsafe trait RustSpec {
200        /// Representation-stability classification; see [`layout`].
201        type Layout;
202
203        /// Statically known, metadata-sized, or extern-type-like size classification; see [`size`].
204        type Size;
205
206        /// Alignment classification; see the [crate root](crate) for [`One`] and [`Gt`].
207        type Alignment;
208
209        /// Trap-representation classification, assuming pointer and reference validity
210        /// is established separately; see [`layout`].
211        type Trap;
212
213        /// Niche availability classification; see [`niche`].
214        type Niche;
215
216        /// Whether `Self` declares `Drop`, has inner drop glue, or has no drop glue; see [`drop`](mod@drop).
217        type Drop;
218
219        /// Shared-access mutability classification; see [`mutability`].
220        type Mutability;
221
222        /// Whether the value representation is opaque; see [`Opaque`].
223        type Opacity;
224
225        /// Trap classification reachable through one or more supported pointer indirections; see [`layout`].
226        #[doc(hidden)]
227        type __IndirectTrap;
228    }
229
230    unsafe impl<R: ?Sized> RustSpec for &R
231    where
232        R: RustSpec<Size: size::Thin>,
233    {
234        type Layout = R::Layout;
235        type Size = size::Sized<Gt<Zero>>;
236        type Alignment = <usize as RustSpec>::Alignment;
237        type Trap = layout::NonRobust;
238        type Niche = WithNiche<Stable>;
239        type Drop = drop::NoDrop;
240        type Mutability = mutability::Exclusive;
241        type Opacity = NonOpaque;
242        type __IndirectTrap = R::Trap;
243    }
244    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for &R
245    where
246        R: RustSpec<Size = size::MetaSized<U>>,
247    {
248        type Layout = Unstable;
249        type Size = size::Sized<Gt<Zero>>;
250        type Alignment = <usize as RustSpec>::Alignment;
251        type Trap = layout::NonRobust;
252        type Niche = WithNiche<Unstable>;
253        type Drop = drop::NoDrop;
254        type Mutability = mutability::Exclusive;
255        type Opacity = NonOpaque;
256        type __IndirectTrap = R::Trap;
257    }
258    unsafe impl<R: ?Sized> RustSpec for &R
259    where
260        R: RustSpec<Size = size::NulTerminated>,
261    {
262        type Layout = R::Layout;
263        type Size = size::Sized<Gt<Zero>>;
264        type Alignment = <usize as RustSpec>::Alignment;
265        type Trap = layout::NonRobust;
266        type Niche = WithNiche<Unstable>;
267        type Drop = drop::NoDrop;
268        type Mutability = mutability::Exclusive;
269        type Opacity = NonOpaque;
270        type __IndirectTrap = R::Trap;
271    }
272
273    unsafe impl<R: ?Sized> RustSpec for &mut R
274    where
275        R: RustSpec<Size: size::Thin>,
276    {
277        type Layout = R::Layout;
278        type Size = size::Sized<Gt<Zero>>;
279        type Alignment = <usize as RustSpec>::Alignment;
280        type Trap = layout::NonRobust;
281        type Niche = WithNiche<Stable>;
282        type Drop = drop::NoDrop;
283        type Mutability = mutability::Exclusive;
284        type Opacity = NonOpaque;
285        type __IndirectTrap = R::Trap;
286    }
287    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for &mut R
288    where
289        R: RustSpec<Size = size::MetaSized<U>>,
290    {
291        type Layout = Unstable;
292        type Size = size::Sized<Gt<Zero>>;
293        type Alignment = <usize as RustSpec>::Alignment;
294        type Trap = layout::NonRobust;
295        type Niche = WithNiche<Unstable>;
296        type Drop = drop::NoDrop;
297        type Mutability = mutability::Exclusive;
298        type Opacity = NonOpaque;
299        type __IndirectTrap = R::Trap;
300    }
301    unsafe impl<R: ?Sized> RustSpec for &mut R
302    where
303        R: RustSpec<Size = size::NulTerminated>,
304    {
305        type Layout = R::Layout;
306        type Size = size::Sized<Gt<Zero>>;
307        type Alignment = <usize as RustSpec>::Alignment;
308        type Trap = layout::NonRobust;
309        type Niche = WithNiche<Unstable>;
310        type Drop = drop::NoDrop;
311        type Mutability = mutability::Exclusive;
312        type Opacity = NonOpaque;
313        type __IndirectTrap = R::Trap;
314    }
315
316    #[cfg(feature = "alloc")]
317    unsafe impl<R, S: SizedKind> RustSpec for Box<R>
318    where
319        R: RustSpec<Size = size::Sized<S>, Drop: Sized>,
320        NoDrop: Add<<R as RustSpec>::Drop, Output: DropKind + Sized>,
321    {
322        type Layout = R::Layout;
323        type Size = size::Sized<Gt<Zero>>;
324        type Alignment = <usize as RustSpec>::Alignment;
325        type Trap = layout::NonRobust;
326        type Niche = WithNiche<Stable>;
327        type Drop = CustomDrop<<NoDrop as Add<R::Drop>>::Output>;
328        type Mutability = mutability::Exclusive;
329        type Opacity = NonOpaque;
330        type __IndirectTrap = R::Trap;
331    }
332    #[cfg(feature = "alloc")]
333    unsafe impl<R: ?Sized, U: MetadataKind> RustSpec for Box<R>
334    where
335        R: RustSpec<Size = size::MetaSized<U>, Drop: Sized>,
336        NoDrop: Add<<R as RustSpec>::Drop, Output: DropKind + Sized>,
337    {
338        type Layout = Unstable;
339        type Size = size::Sized<Gt<Zero>>;
340        type Alignment = <usize as RustSpec>::Alignment;
341        type Trap = layout::NonRobust;
342        type Niche = WithNiche<Unstable>;
343        type Drop = CustomDrop<<NoDrop as Add<R::Drop>>::Output>;
344        type Mutability = mutability::Exclusive;
345        type Opacity = NonOpaque;
346        type __IndirectTrap = R::Trap;
347    }
348    #[cfg(feature = "alloc")]
349    unsafe impl<R: ?Sized> RustSpec for Box<R>
350    where
351        R: RustSpec<Size = size::NulTerminated, Drop: Sized>,
352        NoDrop: Add<<R as RustSpec>::Drop, Output: DropKind + Sized>,
353    {
354        type Layout = R::Layout;
355        type Size = size::Sized<Gt<Zero>>;
356        type Alignment = <usize as RustSpec>::Alignment;
357        type Trap = layout::NonRobust;
358        type Niche = WithNiche<Unstable>;
359        type Drop = CustomDrop<<NoDrop as Add<R::Drop>>::Output>;
360        type Mutability = mutability::Exclusive;
361        type Opacity = NonOpaque;
362        type __IndirectTrap = R::Trap;
363    }
364
365    unsafe impl<R> RustSpec for Option<R>
366    where
367        R: RustSpec<Niche = WithoutNiche, Drop: Sized>,
368        NoDrop: Add<<R as RustSpec>::Drop>,
369    {
370        type Layout = Unstable;
371        type Size = size::Sized<Gt<Zero>>;
372        type Alignment = R::Alignment;
373        type Trap = layout::NonRobust;
374        type Niche = WithNiche<Unstable>;
375        type Drop = <NoDrop as Add<R::Drop>>::Output;
376        type Mutability = R::Mutability;
377        type Opacity = NonOpaque;
378        type __IndirectTrap = R::__IndirectTrap;
379    }
380    unsafe impl<R> RustSpec for Option<R>
381    where
382        R: RustSpec<Niche = WithNiche<Unstable>, Drop: Sized>,
383        NoDrop: Add<<R as RustSpec>::Drop>,
384    {
385        type Layout = Unstable;
386        // FIXME: This can be Robust but we have to track
387        // the number of available custom/unstable niches.
388        // The same thing happens for all other enums
389        type Size = size::Sized<Gt<Zero>>;
390        type Alignment = R::Alignment;
391        type Trap = layout::NonRobust;
392        type Niche = WithNiche<Unstable>;
393        type Drop = <NoDrop as Add<R::Drop>>::Output;
394        type Mutability = R::Mutability;
395        type Opacity = NonOpaque;
396        type __IndirectTrap = R::__IndirectTrap;
397    }
398    unsafe impl<R> RustSpec for Option<R>
399    where
400        R: RustSpec<Niche = WithNiche<Stable>, Drop: Sized>,
401        NoDrop: Add<<R as RustSpec>::Drop>,
402    {
403        type Layout = R::Layout;
404        type Size = size::Sized<Gt<Zero>>;
405        type Alignment = R::Alignment;
406        type Trap = R::__IndirectTrap;
407        type Niche = WithoutNiche;
408        type Drop = <NoDrop as Add<R::Drop>>::Output;
409        type Mutability = R::Mutability;
410        type Opacity = NonOpaque;
411        type __IndirectTrap = R::__IndirectTrap;
412    }
413
414    unsafe impl<R, E, K: SizedKind> RustSpec for Result<R, E>
415    where
416        R: RustSpec<
417            Size = size::Sized<K>,
418            Mutability: Add<<E as RustSpec>::Mutability>,
419            Drop: Add<<E as RustSpec>::Drop>,
420            __IndirectTrap: Add<<E as RustSpec>::__IndirectTrap>,
421        >,
422        E: RustSpec< Size = size::Sized<K>, Mutability: Sized, Drop: Sized>,
423        <E as RustSpec>::Alignment: Sized,
424        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
425    {
426        type Layout = Unstable;
427        type Size = size::Sized<Gt<Zero>>;
428        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
429        type Trap = layout::NonRobust;
430        type Niche = WithNiche<Unstable>;
431        type Drop = <R::Drop as Add<E::Drop>>::Output;
432        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
433        type Opacity = NonOpaque;
434        type __IndirectTrap = <R::__IndirectTrap as Add<E::__IndirectTrap>>::Output;
435    }
436
437    // TODO: The next 3 impls are the same
438    unsafe impl<R, E> RustSpec for Result<R, E>
439    where
440        R: RustSpec<
441            Size = size::Sized<Gt<Zero>>,
442            Niche = WithoutNiche,
443            Drop: Add<<E as RustSpec>::Drop>,
444            Mutability: Add<<E as RustSpec>::Mutability>,
445        >,
446        E: RustSpec< Size = size::Sized<Zero>, Mutability: Sized, Drop: Sized>,
447        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
448        <E as RustSpec>::Alignment: Sized,
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 Drop = <R::Drop as Add<E::Drop>>::Output;
456        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
457        type Opacity = NonOpaque;
458        type __IndirectTrap = R::__IndirectTrap;
459    }
460    unsafe impl<R, E> RustSpec for Result<R, E>
461    where
462        R: RustSpec<
463            Size = size::Sized<Gt<Zero>>,
464            Niche = WithNiche<Unstable>,
465            Drop: Add<<E as RustSpec>::Drop>,
466            Mutability: Add<<E as RustSpec>::Mutability>,
467        >,
468        E: RustSpec< Size = size::Sized<Zero>, Mutability: Sized, Drop: Sized>,
469        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
470        <E as RustSpec>::Alignment: Sized,
471    {
472        type Layout = Unstable;
473        type Size = size::Sized<Gt<Zero>>;
474        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
475        type Trap = layout::NonRobust;
476        type Niche = WithNiche<Unstable>;
477        type Drop = <R::Drop as Add<E::Drop>>::Output;
478        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
479        type Opacity = NonOpaque;
480        type __IndirectTrap = R::__IndirectTrap;
481    }
482    unsafe impl<R, E> RustSpec for Result<R, E>
483    where
484        R: RustSpec<
485            Size = size::Sized<Gt<Zero>>,
486            Niche = WithNiche<Stable>,
487            Drop: Add<<E as RustSpec>::Drop>,
488            Mutability: Add<<E as RustSpec>::Mutability>,
489        >,
490        E: RustSpec< Size = size::Sized<Zero>, Alignment = Gt<One>, Mutability: Sized, Drop: Sized>,
491        <E as RustSpec>::Alignment: Sized,
492        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
493    {
494        type Layout = Unstable;
495        type Size = size::Sized<Gt<Zero>>;
496        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
497        type Trap = layout::NonRobust;
498        type Niche = WithNiche<Unstable>;
499        type Drop = <R::Drop as Add<E::Drop>>::Output;
500        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
501        type Opacity = NonOpaque;
502        type __IndirectTrap = R::__IndirectTrap;
503    }
504    unsafe impl<R, E> RustSpec for Result<R, E>
505    where
506        R: RustSpec<
507            Size = size::Sized<Gt<Zero>>,
508            Niche = WithNiche<Stable>,
509            Drop: Add<<E as RustSpec>::Drop>,
510            Mutability: Add<<E as RustSpec>::Mutability>,
511        >,
512        E: RustSpec< Size = size::Sized<Zero>, Alignment = One, Mutability: Sized, Drop: Sized>,
513        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
514        <E as RustSpec>::Alignment: Sized,
515    {
516        type Layout = R::Layout;
517        type Size = size::Sized<Gt<Zero>>;
518        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
519        type Trap = R::__IndirectTrap;
520        type Niche = WithoutNiche;
521        type Drop = <R::Drop as Add<E::Drop>>::Output;
522        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
523        type Opacity = NonOpaque;
524        type __IndirectTrap = R::__IndirectTrap;
525    }
526
527    // TODO: The next 3 impls are the same
528    unsafe impl<R, E> RustSpec for Result<R, E>
529    where
530        R: RustSpec<
531            Size = size::Sized<Zero>,
532            Drop: Add<<E as RustSpec>::Drop>,
533            Mutability: Add<<E as RustSpec>::Mutability>,
534        >,
535        E: RustSpec< Size = size::Sized<Gt<Zero>>, Niche = WithoutNiche, Mutability: Sized, Drop: Sized>,
536        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
537        <E as RustSpec>::Alignment: Sized,
538    {
539        type Layout = Unstable;
540        type Size = size::Sized<Gt<Zero>>;
541        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
542        type Trap = layout::NonRobust;
543        type Niche = WithNiche<Unstable>;
544        type Drop = <R::Drop as Add<E::Drop>>::Output;
545        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
546        type Opacity = NonOpaque;
547        type __IndirectTrap = E::__IndirectTrap;
548    }
549    unsafe impl<R, E> RustSpec for Result<R, E>
550    where
551        R: RustSpec<
552            Size = size::Sized<Zero>,
553            Niche: WithoutOrUnstableNiche,
554            Drop: Add<<E as RustSpec>::Drop>,
555            Mutability: Add<<E as RustSpec>::Mutability>,
556        >,
557        E: RustSpec<
558            Size = size::Sized<Gt<Zero>>,
559            Niche = WithNiche<Unstable>,
560            Mutability: Sized,
561            Drop: Sized,
562        >,
563        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
564        <E as RustSpec>::Alignment: Sized,
565    {
566        type Layout = Unstable;
567        type Size = size::Sized<Gt<Zero>>;
568        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
569        type Trap = layout::NonRobust;
570        type Niche = WithNiche<Unstable>;
571        type Drop = <R::Drop as Add<E::Drop>>::Output;
572        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
573        type Opacity = NonOpaque;
574        type __IndirectTrap = E::__IndirectTrap;
575    }
576    unsafe impl<R, E> RustSpec for Result<R, E>
577    where
578        R: RustSpec<
579            Size = size::Sized<Zero>,
580            Alignment = Gt<One>,
581            Drop: Add<<E as RustSpec>::Drop>,
582            Mutability: Add<<E as RustSpec>::Mutability>,
583        >,
584        E: RustSpec<
585            Size = size::Sized<Gt<Zero>>,
586            Niche = WithNiche<Stable>,
587            Mutability: Sized,
588            Drop: Sized,
589        >,
590        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
591        <E as RustSpec>::Alignment: Sized,
592    {
593        type Layout = Unstable;
594        type Size = size::Sized<Gt<Zero>>;
595        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
596        type Trap = layout::NonRobust;
597        type Niche = WithNiche<Unstable>;
598        type Drop = <R::Drop as Add<E::Drop>>::Output;
599        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
600        type Opacity = NonOpaque;
601        type __IndirectTrap = E::__IndirectTrap;
602    }
603    unsafe impl<R, E> RustSpec for Result<R, E>
604    where
605        R: RustSpec<
606            Size = size::Sized<Zero>,
607            Alignment = One,
608            Drop: Add<<E as RustSpec>::Drop>,
609            Mutability: Add<<E as RustSpec>::Mutability>,
610        >,
611        E: RustSpec<
612            Size = size::Sized<Gt<Zero>>,
613            Niche = WithNiche<Stable>,
614            Mutability: Sized,
615            Drop: Sized,
616        >,
617        <R as RustSpec>::Alignment: Max<<E as RustSpec>::Alignment>,
618        <E as RustSpec>::Alignment: Sized,
619    {
620        type Layout = E::Layout;
621        type Size = size::Sized<Gt<Zero>>;
622        type Alignment = <R::Alignment as Max<E::Alignment>>::Output;
623        type Trap = E::__IndirectTrap;
624        type Niche = WithoutNiche;
625        type Drop = <R::Drop as Add<E::Drop>>::Output;
626        type Mutability = <R::Mutability as Add<E::Mutability>>::Output;
627        type Opacity = NonOpaque;
628        type __IndirectTrap = E::__IndirectTrap;
629    }
630
631    unsafe impl<R: ?Sized> RustSpec for *const R
632    where
633        R: RustSpec<Size: size::Thin>,
634    {
635        type Layout = R::Layout;
636        type Size = size::Sized<crate::Gt<Zero>>;
637        type Alignment = <usize as RustSpec>::Alignment;
638        type Trap = R::Trap;
639        type Niche = WithoutNiche;
640        type Drop = NoDrop;
641        type Mutability = mutability::Exclusive;
642        type Opacity = NonOpaque;
643        type __IndirectTrap = R::Trap;
644    }
645    unsafe impl<R: ?Sized, K: MetadataKind> RustSpec for *const R
646    where
647        R: RustSpec<Size = size::MetaSized<K>>,
648    {
649        type Layout = Unstable;
650        type Size = size::Sized<crate::Gt<Zero>>;
651        type Alignment = <usize as RustSpec>::Alignment;
652        type Trap = R::Trap;
653        type Niche = WithoutNiche;
654        type Drop = NoDrop;
655        type Mutability = mutability::Exclusive;
656        type Opacity = NonOpaque;
657        type __IndirectTrap = R::Trap;
658    }
659    unsafe impl<R: ?Sized> RustSpec for *const R
660    where
661        R: RustSpec<Size = size::NulTerminated>,
662    {
663        type Layout = Unstable;
664        type Size = size::Sized<crate::Gt<Zero>>;
665        type Alignment = <usize as RustSpec>::Alignment;
666        type Trap = R::Trap;
667        type Niche = WithoutNiche;
668        type Drop = NoDrop;
669        type Mutability = mutability::Exclusive;
670        type Opacity = NonOpaque;
671        type __IndirectTrap = R::Trap;
672    }
673
674    unsafe impl<R: ?Sized> RustSpec for *mut R
675    where
676        R: RustSpec<Size: size::Thin>,
677    {
678        type Layout = R::Layout;
679        type Size = size::Sized<crate::Gt<Zero>>;
680        type Alignment = <usize as RustSpec>::Alignment;
681        type Trap = R::Trap;
682        type Niche = WithoutNiche;
683        type Drop = NoDrop;
684        type Mutability = mutability::Exclusive;
685        type Opacity = NonOpaque;
686        type __IndirectTrap = R::Trap;
687    }
688    unsafe impl<R: ?Sized, K: MetadataKind> RustSpec for *mut R
689    where
690        R: RustSpec<Size = size::MetaSized<K>>,
691    {
692        type Layout = Unstable;
693        type Size = size::Sized<crate::Gt<Zero>>;
694        type Alignment = <usize as RustSpec>::Alignment;
695        type Trap = R::Trap;
696        type Niche = WithoutNiche;
697        type Drop = NoDrop;
698        type Mutability = mutability::Exclusive;
699        type Opacity = NonOpaque;
700        type __IndirectTrap = R::Trap;
701    }
702    unsafe impl<R: ?Sized> RustSpec for *mut R
703    where
704        R: RustSpec<Size = size::NulTerminated>,
705    {
706        type Layout = Unstable;
707        type Size = size::Sized<crate::Gt<Zero>>;
708        type Alignment = <usize as RustSpec>::Alignment;
709        type Trap = R::Trap;
710        type Niche = WithoutNiche;
711        type Drop = NoDrop;
712        type Mutability = mutability::Exclusive;
713        type Opacity = NonOpaque;
714        type __IndirectTrap = R::Trap;
715    }
716
717    unsafe impl<R> RustSpec for NonNull<R>
718    where
719        R: RustSpec<Size: size::Thin>,
720    {
721        type Layout = R::Layout;
722        type Size = size::Sized<crate::Gt<Zero>>;
723        type Alignment = <usize as RustSpec>::Alignment;
724        type Trap = NonRobust;
725        type Niche = WithNiche<Stable>;
726        type Drop = NoDrop;
727        type Mutability = mutability::Exclusive;
728        type Opacity = NonOpaque;
729        type __IndirectTrap = R::Trap;
730    }
731    unsafe impl<R: ?Sized, K: MetadataKind> RustSpec for NonNull<R>
732    where
733        R: RustSpec<Size = size::MetaSized<K>>,
734    {
735        type Layout = Unstable;
736        type Size = size::Sized<crate::Gt<Zero>>;
737        type Alignment = <usize as RustSpec>::Alignment;
738        type Trap = NonRobust;
739        type Niche = WithNiche<Stable>;
740        type Drop = NoDrop;
741        type Mutability = mutability::Exclusive;
742        type Opacity = NonOpaque;
743        type __IndirectTrap = R::Trap;
744    }
745    unsafe impl<R: ?Sized> RustSpec for NonNull<R>
746    where
747        R: RustSpec<Size = size::NulTerminated>,
748    {
749        type Layout = Unstable;
750        type Size = size::Sized<crate::Gt<Zero>>;
751        type Alignment = <usize as RustSpec>::Alignment;
752        type Trap = NonRobust;
753        type Niche = WithNiche<Stable>;
754        type Drop = NoDrop;
755        type Mutability = mutability::Exclusive;
756        type Opacity = NonOpaque;
757        type __IndirectTrap = R::Trap;
758    }
759}
760
761#[cfg(test)]
762mod tests {
763    #[cfg(feature = "alloc")]
764    use alloc::vec::Vec;
765
766    use static_assertions::assert_impl_all;
767
768    use super::*;
769    use {
770        layout::{NonRobust, Robust},
771        mutability::Exclusive,
772        niche::{WithNiche, WithoutNiche},
773        size::{Gt, Sized as RustSpecSized},
774    };
775
776    #[test]
777    fn indirect_trap_follows_supported_pointers_only() {
778        assert_impl_all!(&u8: RustSpec<__IndirectTrap = Robust>);
779        assert_impl_all!(&bool: RustSpec<__IndirectTrap = NonRobust>);
780        assert_impl_all!(&&u8: RustSpec<__IndirectTrap = NonRobust>);
781        assert_impl_all!(Option<&u8>: RustSpec<__IndirectTrap = Robust>);
782        assert_impl_all!(*const bool: RustSpec<__IndirectTrap = NonRobust>);
783    }
784
785    #[test]
786    fn transparent_type() {
787        assert_impl_all!(bool:
788            RustSpec<
789                Layout = Stable,
790                Size = RustSpecSized<Gt<Zero>>,
791                Alignment = One,
792                Trap = NonRobust,
793                Niche = WithNiche<Unstable>,
794                Mutability = Exclusive,
795                __IndirectTrap = Robust,
796            >,
797        );
798        assert_impl_all!(&bool:
799            RustSpec<
800                Layout = Stable,
801                Size = RustSpecSized<Gt<Zero>>,
802                Alignment = <usize as RustSpec>::Alignment,
803                Trap = NonRobust,
804                Niche = WithNiche<Stable>,
805                Mutability = Exclusive,
806                __IndirectTrap = NonRobust,
807            >,
808        );
809        assert_impl_all!(&mut bool:
810            RustSpec<
811                Layout = Stable,
812                Size = RustSpecSized<Gt<Zero>>,
813                Alignment = <usize as RustSpec>::Alignment,
814                Trap = NonRobust,
815                Niche = WithNiche<Stable>,
816                Mutability = Exclusive,
817                __IndirectTrap = NonRobust,
818            >,
819        );
820        #[cfg(feature = "alloc")]
821        assert_impl_all!(Box<bool>:
822            RustSpec<
823                Layout = Stable,
824                Size = RustSpecSized<Gt<Zero>>,
825                Alignment = <usize as RustSpec>::Alignment,
826                Trap = NonRobust,
827                Niche = WithNiche<Stable>,
828                Mutability = Exclusive,
829                __IndirectTrap = NonRobust,
830            >,
831        );
832        assert_impl_all!(&[bool]:
833            RustSpec<
834                Layout = Unstable,
835                Size = RustSpecSized<Gt<Zero>>,
836                Alignment = <usize as RustSpec>::Alignment,
837                Trap = NonRobust,
838                Niche = WithNiche<Unstable>,
839                Mutability = Exclusive,
840                __IndirectTrap = NonRobust,
841            >,
842        );
843        #[cfg(feature = "alloc")]
844        assert_impl_all!(&mut [bool]:
845            RustSpec<
846                Layout = Unstable,
847                Size = RustSpecSized<Gt<Zero>>,
848                Alignment = <usize as RustSpec>::Alignment,
849                Trap = NonRobust,
850                Niche = WithNiche<Unstable>,
851                Mutability = Exclusive,
852                __IndirectTrap = NonRobust,
853            >,
854        );
855        #[cfg(feature = "alloc")]
856        assert_impl_all!(Box<[bool]>:
857            RustSpec<
858                Layout = Unstable,
859                Size = RustSpecSized<Gt<Zero>>,
860                Alignment = <usize as RustSpec>::Alignment,
861                Trap = NonRobust,
862                Niche = WithNiche<Unstable>,
863                Mutability = Exclusive,
864                __IndirectTrap = NonRobust,
865            >,
866        );
867        #[cfg(feature = "alloc")]
868        assert_impl_all!(Vec<bool>:
869            RustSpec<
870                Layout = Unstable,
871                Size = RustSpecSized<Gt<Zero>>,
872                Alignment = <usize as RustSpec>::Alignment,
873                Trap = NonRobust,
874                Niche = WithNiche<Unstable>,
875                Mutability = Exclusive,
876                __IndirectTrap = NonRobust,
877            >,
878        );
879        assert_impl_all!([bool; 2]:
880            RustSpec<
881                Layout = Stable,
882                Size = RustSpecSized<Gt<Zero>>,
883                Alignment = One,
884                Trap = NonRobust,
885                Niche = WithNiche<Unstable>,
886                Mutability = Exclusive,
887                __IndirectTrap = Robust,
888            >,
889        );
890        // FIXME:
891        //assert_impl_all!(Option<bool>:
892        //    RustSpec<
893        //        Layout = Unstable,
894        //        Size = RustSpecSized<Gt<Zero>>,
895        //        Trap = NonRobust,
896        //        Niche = WithNiche<Unstable>,
897        //        Mutability = Exclusive,
898        //    >,
899        //);
900    }
901
902    #[test]
903    fn option_stable_niche_layout() {
904        use core::num::NonZeroU8;
905
906        assert_impl_all!(Option<NonZeroU8>:
907            RustSpec<
908                Layout = Stable,
909                Size = RustSpecSized<Gt<Zero>>,
910                Alignment = One,
911                Trap = Robust,
912                Niche = WithoutNiche,
913                Mutability = Exclusive,
914                __IndirectTrap = Robust,
915            >,
916        );
917        assert_impl_all!(Option<&u8>:
918            RustSpec<
919                Layout = Stable,
920                Size = RustSpecSized<Gt<Zero>>,
921                Alignment = <usize as RustSpec>::Alignment,
922                Trap = Robust,
923                Niche = WithoutNiche,
924                Mutability = Exclusive,
925                __IndirectTrap = Robust,
926            >,
927        );
928        assert_impl_all!(Option<&(u8, u8, u8)>:
929            RustSpec<
930                Layout = Unstable,
931                Size = RustSpecSized<Gt<Zero>>,
932                Alignment = <usize as RustSpec>::Alignment,
933                Trap = Robust,
934                Niche = WithoutNiche,
935                Mutability = Exclusive,
936                __IndirectTrap = Robust,
937            >,
938        );
939        assert_impl_all!(Option<&NonZeroU8>:
940            RustSpec<
941                Layout = Stable,
942                Size = RustSpecSized<Gt<Zero>>,
943                Alignment = <usize as RustSpec>::Alignment,
944                Trap = NonRobust,
945                Niche = WithoutNiche,
946                Mutability = Exclusive,
947                __IndirectTrap = NonRobust,
948            >,
949        );
950    }
951
952    #[test]
953    fn result_stable_niche_layout() {
954        use core::num::NonZeroU8;
955
956        assert_impl_all!(Result<NonZeroU8, ()>:
957            RustSpec<
958                Layout = Stable,
959                Size = RustSpecSized<Gt<Zero>>,
960                Alignment = One,
961                Trap = Robust,
962                Niche = WithoutNiche,
963                Mutability = Exclusive,
964                __IndirectTrap = Robust,
965            >,
966        );
967        assert_impl_all!(Result<&u8, ()>:
968            RustSpec<
969                Layout = Stable,
970                Size = RustSpecSized<Gt<Zero>>,
971                Alignment = <usize as RustSpec>::Alignment,
972                Trap = Robust,
973                Niche = WithoutNiche,
974                Mutability = Exclusive,
975                __IndirectTrap = Robust,
976            >,
977        );
978        assert_impl_all!(Result<&NonZeroU8, ()>:
979            RustSpec<
980                Layout = Stable,
981                Size = RustSpecSized<Gt<Zero>>,
982                Alignment = <usize as RustSpec>::Alignment,
983                Trap = NonRobust,
984                Niche = WithoutNiche,
985                Mutability = Exclusive,
986                __IndirectTrap = NonRobust,
987            >,
988        );
989        assert_impl_all!(Result<(), NonZeroU8>:
990            RustSpec<
991                Layout = Stable,
992                Size = RustSpecSized<Gt<Zero>>,
993                Alignment = One,
994                Trap = Robust,
995                Niche = WithoutNiche,
996                Mutability = Exclusive,
997                __IndirectTrap = Robust,
998            >,
999        );
1000        assert_impl_all!(Result<&mut u8, ()>:
1001            RustSpec<
1002                Layout = Stable,
1003                Size = RustSpecSized<Gt<Zero>>,
1004                Alignment = <usize as RustSpec>::Alignment,
1005                Trap = Robust,
1006                Niche = WithoutNiche,
1007                Mutability = Exclusive,
1008                __IndirectTrap = Robust,
1009            >,
1010        );
1011    }
1012
1013    #[test]
1014    fn robust_ref() {
1015        assert_impl_all!(&&u8:
1016            RustSpec<
1017                Layout = Stable,
1018                Size = RustSpecSized<Gt<Zero>>,
1019                Alignment = <usize as RustSpec>::Alignment,
1020                Trap = NonRobust,
1021                Niche = WithNiche<Stable>,
1022                Mutability = Exclusive,
1023                __IndirectTrap = NonRobust,
1024            >,
1025        );
1026        assert_impl_all!(&mut &u8:
1027            RustSpec<
1028                Layout = Stable,
1029                Size = RustSpecSized<Gt<Zero>>,
1030                Alignment = <usize as RustSpec>::Alignment,
1031                Trap = NonRobust,
1032                Niche = WithNiche<Stable>,
1033                Mutability = Exclusive,
1034                __IndirectTrap = NonRobust,
1035            >,
1036        );
1037        #[cfg(feature = "alloc")]
1038        assert_impl_all!(Box<&bool>:
1039            RustSpec<
1040                Layout = Stable,
1041                Size = RustSpecSized<Gt<Zero>>,
1042                Alignment = <usize as RustSpec>::Alignment,
1043                Trap = NonRobust,
1044                Niche = WithNiche<Stable>,
1045                Mutability = Exclusive,
1046                __IndirectTrap = NonRobust,
1047            >,
1048        );
1049        assert_impl_all!(&[&u8]:
1050            RustSpec<
1051                Layout = Unstable,
1052                Size = RustSpecSized<Gt<Zero>>,
1053                Alignment = <usize as RustSpec>::Alignment,
1054                Trap = NonRobust,
1055                Niche = WithNiche<Unstable>,
1056                Mutability = Exclusive,
1057                __IndirectTrap = NonRobust,
1058            >,
1059        );
1060        assert_impl_all!(&mut [&u8]:
1061            RustSpec<
1062                Layout = Unstable,
1063                Size = RustSpecSized<Gt<Zero>>,
1064                Alignment = <usize as RustSpec>::Alignment,
1065                Trap = NonRobust,
1066                Niche = WithNiche<Unstable>,
1067                Mutability = Exclusive,
1068                __IndirectTrap = NonRobust,
1069            >,
1070        );
1071        #[cfg(feature = "alloc")]
1072        assert_impl_all!(Box<[&u8]>:
1073            RustSpec<
1074                Layout = Unstable,
1075                Size = RustSpecSized<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!(Vec<&u8>:
1085            RustSpec<
1086                Layout = Unstable,
1087                Size = RustSpecSized<Gt<Zero>>,
1088                Alignment = <usize as RustSpec>::Alignment,
1089                Trap = NonRobust,
1090                Niche = WithNiche<Unstable>,
1091                Mutability = Exclusive,
1092                __IndirectTrap = NonRobust,
1093            >,
1094        );
1095        assert_impl_all!([&u8; 2]:
1096            RustSpec<
1097                Layout = Stable,
1098                Size = RustSpecSized<Gt<Zero>>,
1099                Alignment = <usize as RustSpec>::Alignment,
1100                Trap = NonRobust,
1101                Niche = WithNiche<Unstable>,
1102                Mutability = Exclusive,
1103                __IndirectTrap = Robust,
1104            >,
1105        );
1106        assert_impl_all!(Option<&u8>:
1107            RustSpec<
1108                Layout = Stable,
1109                Size = RustSpecSized<Gt<Zero>>,
1110                Alignment = <usize as RustSpec>::Alignment,
1111                Trap = Robust,
1112                Niche = WithoutNiche,
1113                Mutability = Exclusive,
1114                __IndirectTrap = Robust,
1115            >,
1116        );
1117    }
1118
1119    #[test]
1120    fn transparent_ref() {
1121        assert_impl_all!(&&bool:
1122            RustSpec<
1123                Layout = Stable,
1124                Size = RustSpecSized<Gt<Zero>>,
1125                Alignment = <usize as RustSpec>::Alignment,
1126                Trap = NonRobust,
1127                Niche = WithNiche<Stable>,
1128                Mutability = Exclusive,
1129                __IndirectTrap = NonRobust,
1130            >,
1131        );
1132        assert_impl_all!(&mut &bool:
1133            RustSpec<
1134                Layout = Stable,
1135                Size = RustSpecSized<Gt<Zero>>,
1136                Alignment = <usize as RustSpec>::Alignment,
1137                Trap = NonRobust,
1138                Niche = WithNiche<Stable>,
1139                Mutability = Exclusive,
1140                __IndirectTrap = NonRobust,
1141            >,
1142        );
1143        #[cfg(feature = "alloc")]
1144        assert_impl_all!(Box<&bool>:
1145            RustSpec<
1146                Layout = Stable,
1147                Size = RustSpecSized<Gt<Zero>>,
1148                Alignment = <usize as RustSpec>::Alignment,
1149                Trap = NonRobust,
1150                Niche = WithNiche<Stable>,
1151                Mutability = Exclusive,
1152                __IndirectTrap = NonRobust,
1153            >,
1154        );
1155        assert_impl_all!(&[&bool]:
1156            RustSpec<
1157                Layout = Unstable,
1158                Size = RustSpecSized<Gt<Zero>>,
1159                Alignment = <usize as RustSpec>::Alignment,
1160                Trap = NonRobust,
1161                Niche = WithNiche<Unstable>,
1162                Mutability = Exclusive,
1163                __IndirectTrap = NonRobust,
1164            >,
1165        );
1166        #[cfg(feature = "alloc")]
1167        assert_impl_all!(&mut [&bool]:
1168            RustSpec<
1169                Layout = Unstable,
1170                Size = RustSpecSized<Gt<Zero>>,
1171                Alignment = <usize as RustSpec>::Alignment,
1172                Trap = NonRobust,
1173                Niche = WithNiche<Unstable>,
1174                Mutability = Exclusive,
1175                __IndirectTrap = NonRobust,
1176            >,
1177        );
1178        #[cfg(feature = "alloc")]
1179        assert_impl_all!(Box<[&bool]>:
1180            RustSpec<
1181                Layout = Unstable,
1182                Size = RustSpecSized<Gt<Zero>>,
1183                Alignment = <usize as RustSpec>::Alignment,
1184                Trap = NonRobust,
1185                Niche = WithNiche<Unstable>,
1186                Mutability = Exclusive,
1187                __IndirectTrap = NonRobust,
1188            >,
1189        );
1190        #[cfg(feature = "alloc")]
1191        assert_impl_all!(Vec<&bool>:
1192            RustSpec<
1193                Layout = Unstable,
1194                Size = RustSpecSized<Gt<Zero>>,
1195                Alignment = <usize as RustSpec>::Alignment,
1196                Trap = NonRobust,
1197                Niche = WithNiche<Unstable>,
1198                Mutability = Exclusive,
1199                __IndirectTrap = NonRobust,
1200            >,
1201        );
1202        assert_impl_all!([&bool; 2]:
1203            RustSpec<
1204                Layout = Stable,
1205                Size = RustSpecSized<Gt<Zero>>,
1206                Alignment = <usize as RustSpec>::Alignment,
1207                Trap = NonRobust,
1208                Niche = WithNiche<Unstable>,
1209                Mutability = Exclusive,
1210                __IndirectTrap = NonRobust,
1211            >,
1212        );
1213        assert_impl_all!(Option<&bool>:
1214            RustSpec<
1215                Layout = Stable,
1216                Size = RustSpecSized<Gt<Zero>>,
1217                Alignment = <usize as RustSpec>::Alignment,
1218                Trap = NonRobust,
1219                Niche = WithoutNiche,
1220                Mutability = Exclusive,
1221                __IndirectTrap = NonRobust,
1222            >,
1223        );
1224    }
1225
1226    #[test]
1227    fn robust_ref_mut() {
1228        assert_impl_all!(&&mut u8:
1229            RustSpec<
1230                Layout = Stable,
1231                Size = RustSpecSized<Gt<Zero>>,
1232                Alignment = <usize as RustSpec>::Alignment,
1233                Trap = NonRobust,
1234                Niche = WithNiche<Stable>,
1235                Mutability = Exclusive,
1236                __IndirectTrap = NonRobust,
1237            >,
1238        );
1239        assert_impl_all!(&mut &mut u8:
1240            RustSpec<
1241                Layout = Stable,
1242                Size = RustSpecSized<Gt<Zero>>,
1243                Alignment = <usize as RustSpec>::Alignment,
1244                Trap = NonRobust,
1245                Niche = WithNiche<Stable>,
1246                Mutability = Exclusive,
1247                __IndirectTrap = NonRobust,
1248            >,
1249        );
1250        #[cfg(feature = "alloc")]
1251        assert_impl_all!(Box<&mut u8>:
1252            RustSpec<
1253                Layout = Stable,
1254                Size = RustSpecSized<Gt<Zero>>,
1255                Alignment = <usize as RustSpec>::Alignment,
1256                Trap = NonRobust,
1257                Niche = WithNiche<Stable>,
1258                Mutability = Exclusive,
1259                __IndirectTrap = NonRobust,
1260            >,
1261        );
1262        assert_impl_all!(&[&mut u8]:
1263            RustSpec<
1264                Layout = Unstable,
1265                Size = RustSpecSized<Gt<Zero>>,
1266                Alignment = <usize as RustSpec>::Alignment,
1267                Trap = NonRobust,
1268                Niche = WithNiche<Unstable>,
1269                Mutability = Exclusive,
1270                __IndirectTrap = NonRobust,
1271            >,
1272        );
1273        assert_impl_all!(&mut [&mut u8]:
1274            RustSpec<
1275                Layout = Unstable,
1276                Size = RustSpecSized<Gt<Zero>>,
1277                Alignment = <usize as RustSpec>::Alignment,
1278                Trap = NonRobust,
1279                Niche = WithNiche<Unstable>,
1280                Mutability = Exclusive,
1281                __IndirectTrap = NonRobust,
1282            >,
1283        );
1284        #[cfg(feature = "alloc")]
1285        assert_impl_all!(Box<[&mut u8]>:
1286            RustSpec<
1287                Layout = Unstable,
1288                Size = RustSpecSized<Gt<Zero>>,
1289                Alignment = <usize as RustSpec>::Alignment,
1290                Trap = NonRobust,
1291                Niche = WithNiche<Unstable>,
1292                Mutability = Exclusive,
1293                __IndirectTrap = NonRobust,
1294            >,
1295        );
1296        #[cfg(feature = "alloc")]
1297        assert_impl_all!(Vec<&mut u8>:
1298            RustSpec<
1299                Layout = Unstable,
1300                Size = RustSpecSized<Gt<Zero>>,
1301                Alignment = <usize as RustSpec>::Alignment,
1302                Trap = NonRobust,
1303                Niche = WithNiche<Unstable>,
1304                Mutability = Exclusive,
1305                __IndirectTrap = NonRobust,
1306            >,
1307        );
1308        assert_impl_all!([&mut u8; 2]:
1309            RustSpec<
1310                Layout = Stable,
1311                Size = RustSpecSized<Gt<Zero>>,
1312                Alignment = <usize as RustSpec>::Alignment,
1313                Trap = NonRobust,
1314                Niche = WithNiche<Unstable>,
1315                Mutability = Exclusive,
1316                __IndirectTrap = Robust,
1317            >,
1318        );
1319        assert_impl_all!(Option<&mut u8>:
1320            RustSpec<
1321                Layout = Stable,
1322                Size = RustSpecSized<Gt<Zero>>,
1323                Alignment = <usize as RustSpec>::Alignment,
1324                Trap = Robust,
1325                Niche = WithoutNiche,
1326                Mutability = Exclusive,
1327                __IndirectTrap = Robust,
1328            >,
1329        );
1330    }
1331
1332    #[test]
1333    fn transparent_ref_mut() {
1334        assert_impl_all!(&&mut bool:
1335            RustSpec<
1336                Layout = Stable,
1337                Size = RustSpecSized<Gt<Zero>>,
1338                Alignment = <usize as RustSpec>::Alignment,
1339                Trap = NonRobust,
1340                Niche = WithNiche<Stable>,
1341                Mutability = Exclusive,
1342                __IndirectTrap = NonRobust,
1343            >,
1344        );
1345        assert_impl_all!(&mut &mut bool:
1346            RustSpec<
1347                Layout = Stable,
1348                Size = RustSpecSized<Gt<Zero>>,
1349                Alignment = <usize as RustSpec>::Alignment,
1350                Trap = NonRobust,
1351                Niche = WithNiche<Stable>,
1352                Mutability = Exclusive,
1353                __IndirectTrap = NonRobust,
1354            >,
1355        );
1356        #[cfg(feature = "alloc")]
1357        assert_impl_all!(Box<&mut bool>:
1358            RustSpec<
1359                Layout = Stable,
1360                Size = RustSpecSized<Gt<Zero>>,
1361                Alignment = <usize as RustSpec>::Alignment,
1362                Trap = NonRobust,
1363                Niche = WithNiche<Stable>,
1364                Mutability = Exclusive,
1365                __IndirectTrap = NonRobust,
1366            >,
1367        );
1368        assert_impl_all!(&[&mut bool]:
1369            RustSpec<
1370                Layout = Unstable,
1371                Size = RustSpecSized<Gt<Zero>>,
1372                Alignment = <usize as RustSpec>::Alignment,
1373                Trap = NonRobust,
1374                Niche = WithNiche<Unstable>,
1375                Mutability = Exclusive,
1376                __IndirectTrap = NonRobust,
1377            >,
1378        );
1379        assert_impl_all!(&mut [&mut bool]:
1380            RustSpec<
1381                Layout = Unstable,
1382                Size = RustSpecSized<Gt<Zero>>,
1383                Alignment = <usize as RustSpec>::Alignment,
1384                Trap = NonRobust,
1385                Niche = WithNiche<Unstable>,
1386                Mutability = Exclusive,
1387                __IndirectTrap = NonRobust,
1388            >,
1389        );
1390        #[cfg(feature = "alloc")]
1391        assert_impl_all!(Box<[&mut bool]>:
1392            RustSpec<
1393                Layout = Unstable,
1394                Size = RustSpecSized<Gt<Zero>>,
1395                Alignment = <usize as RustSpec>::Alignment,
1396                Trap = NonRobust,
1397                Niche = WithNiche<Unstable>,
1398                Mutability = Exclusive,
1399                __IndirectTrap = NonRobust,
1400            >,
1401        );
1402        #[cfg(feature = "alloc")]
1403        assert_impl_all!(Vec<&mut bool>:
1404            RustSpec<
1405                Layout = Unstable,
1406                Size = RustSpecSized<Gt<Zero>>,
1407                Alignment = <usize as RustSpec>::Alignment,
1408                Trap = NonRobust,
1409                Niche = WithNiche<Unstable>,
1410                Mutability = Exclusive,
1411                __IndirectTrap = NonRobust,
1412            >,
1413        );
1414        assert_impl_all!([&mut bool; 2]:
1415            RustSpec<
1416                Layout = Stable,
1417                Size = RustSpecSized<Gt<Zero>>,
1418                Alignment = <usize as RustSpec>::Alignment,
1419                Trap = NonRobust,
1420                Niche = WithNiche<Unstable>,
1421                Mutability = Exclusive,
1422                __IndirectTrap = NonRobust,
1423            >,
1424        );
1425        assert_impl_all!(Option<&mut bool>:
1426            RustSpec<
1427                Layout = Stable,
1428                Size = RustSpecSized<Gt<Zero>>,
1429                Alignment = <usize as RustSpec>::Alignment,
1430                Trap = NonRobust,
1431                Niche = WithoutNiche,
1432                Mutability = Exclusive,
1433                __IndirectTrap = NonRobust,
1434            >,
1435        );
1436    }
1437}