Skip to main content

rustc_abi/
lib.rs

1// tidy-alphabetical-start
2#![cfg_attr(feature = "nightly", allow(internal_features))]
3#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
4#![cfg_attr(feature = "nightly", feature(step_trait))]
5// tidy-alphabetical-end
6
7/*! ABI handling for rustc
8
9## What is an "ABI"?
10
11Literally, "application binary interface", which means it is everything about how code interacts,
12at the machine level, with other code. This means it technically covers all of the following:
13- object binary format for e.g. relocations or offset tables
14- in-memory layout of types
15- procedure calling conventions
16
17When we discuss "ABI" in the context of rustc, we are probably discussing calling conventions.
18To describe those `rustc_abi` also covers type layout, as it must for values passed on the stack.
19Despite `rustc_abi` being about calling conventions, it is good to remember these usages exist.
20You will encounter all of them and more if you study target-specific codegen enough!
21Even in general conversation, when someone says "the Rust ABI is unstable", it may allude to
22either or both of
23- `repr(Rust)` types have a mostly-unspecified layout
24- `extern "Rust" fn(A) -> R` has an unspecified calling convention
25
26## Crate Goal
27
28ABI is a foundational concept, so the `rustc_abi` crate serves as an equally foundational crate.
29It cannot carry all details relevant to an ABI: those permeate code generation and linkage.
30Instead, `rustc_abi` is intended to provide the interface for reasoning about the binary interface.
31It should contain traits and types that other crates then use in their implementation.
32For example, a platform's `extern "C" fn` calling convention will be implemented in `rustc_target`
33but `rustc_abi` contains the types for calculating layout and describing register-passing.
34This makes it easier to describe things in the same way across targets, codegen backends, and
35even other Rust compilers, such as rust-analyzer!
36
37*/
38
39use std::fmt;
40#[cfg(feature = "nightly")]
41use std::iter::Step;
42use std::num::{NonZeroUsize, ParseIntError};
43use std::ops::{Add, AddAssign, Deref, Mul, RangeFull, Sub};
44use std::range::RangeInclusive;
45use std::str::FromStr;
46
47use bitflags::bitflags;
48#[cfg(feature = "nightly")]
49use rustc_data_structures::stable_hash::StableOrd;
50#[cfg(feature = "nightly")]
51use rustc_error_messages::{DiagArgValue, IntoDiagArg};
52#[cfg(feature = "nightly")]
53use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg};
54use rustc_hashes::Hash64;
55use rustc_index::{Idx, IndexSlice, IndexVec};
56#[cfg(feature = "nightly")]
57use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash};
58#[cfg(feature = "nightly")]
59use rustc_span::{Symbol, sym};
60
61mod callconv;
62mod canon_abi;
63mod extern_abi;
64mod layout;
65#[cfg(test)]
66mod tests;
67
68pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
69pub use canon_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
70#[cfg(feature = "nightly")]
71pub use extern_abi::CVariadicStatus;
72pub use extern_abi::{ExternAbi, all_names};
73pub use layout::{FIRST_VARIANT, FieldIdx, LayoutCalculator, LayoutCalculatorError, VariantIdx};
74#[cfg(feature = "nightly")]
75pub use layout::{Layout, TyAbiInterface, TyAndLayout};
76
77#[derive(#[automatically_derived]
impl ::core::clone::Clone for ReprFlags {
    #[inline]
    fn clone(&self) -> ReprFlags {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ReprFlags { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ReprFlags {
    #[inline]
    fn eq(&self, other: &ReprFlags) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ReprFlags {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::default::Default for ReprFlags {
    #[inline]
    fn default() -> ReprFlags {
        ReprFlags(::core::default::Default::default())
    }
}Default)]
78#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ReprFlags {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ReprFlags(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ReprFlags {
            fn decode(__decoder: &mut __D) -> Self {
                ReprFlags(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for ReprFlags {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    ReprFlags(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
79pub struct ReprFlags(u8);
80
81impl ReprFlags {
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IS_C: Self = Self::from_bits_retain(1 << 0);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IS_SIMD: Self = Self::from_bits_retain(1 << 1);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IS_TRANSPARENT: Self = Self::from_bits_retain(1 << 2);
    #[doc = r" Internal only for now. If true, don't reorder fields."]
    #[doc = r" On its own it does not prevent ABI optimizations."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IS_LINEAR: Self = Self::from_bits_retain(1 << 3);
    #[doc =
    r" If true, the type's crate has opted into layout randomization."]
    #[doc =
    r" Other flags can still inhibit reordering and thus randomization."]
    #[doc = r" The seed stored in `ReprOptions.field_shuffle_seed`."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const RANDOMIZE_LAYOUT: Self = Self::from_bits_retain(1 << 4);
    #[doc =
    r" If true, the type is always passed indirectly by non-Rustic ABIs."]
    #[doc =
    r" See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS: Self =
        Self::from_bits_retain(1 << 5);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IS_SCALABLE: Self = Self::from_bits_retain(1 << 6);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const FIELD_ORDER_UNOPTIMIZABLE: Self =
        Self::from_bits_retain(ReprFlags::IS_C.bits() |
                        ReprFlags::IS_SIMD.bits() | ReprFlags::IS_SCALABLE.bits() |
                ReprFlags::IS_LINEAR.bits());
    #[allow(deprecated, non_upper_case_globals,)]
    pub const ABI_UNOPTIMIZABLE: Self =
        Self::from_bits_retain(ReprFlags::IS_C.bits() |
                ReprFlags::IS_SIMD.bits());
}
impl ::bitflags::Flags for ReprFlags {
    const FLAGS: &'static [::bitflags::Flag<ReprFlags>] =
        &[{

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IS_C", ReprFlags::IS_C)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IS_SIMD", ReprFlags::IS_SIMD)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IS_TRANSPARENT",
                            ReprFlags::IS_TRANSPARENT)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IS_LINEAR", ReprFlags::IS_LINEAR)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("RANDOMIZE_LAYOUT",
                            ReprFlags::RANDOMIZE_LAYOUT)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS",
                            ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IS_SCALABLE", ReprFlags::IS_SCALABLE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("FIELD_ORDER_UNOPTIMIZABLE",
                            ReprFlags::FIELD_ORDER_UNOPTIMIZABLE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("ABI_UNOPTIMIZABLE",
                            ReprFlags::ABI_UNOPTIMIZABLE)
                    }];
    type Bits = u8;
    fn bits(&self) -> u8 { ReprFlags::bits(self) }
    fn from_bits_retain(bits: u8) -> ReprFlags {
        ReprFlags::from_bits_retain(bits)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy ::
assign_op_pattern, clippy :: iter_without_into_iter,)]
const _: () =
    {
        #[allow(dead_code, deprecated, unused_attributes)]
        impl ReprFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u8 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                let mut truncated = <u8 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <ReprFlags as ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                let _ = i;
                Self(truncated)
            }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u8 { self.0 }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u8)
                -> ::bitflags::__private::core::option::Option<Self> {
                let truncated = Self::from_bits_truncate(bits).0;
                if truncated == bits {
                    ::bitflags::__private::core::option::Option::Some(Self(bits))
                } else { ::bitflags::__private::core::option::Option::None }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u8) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u8) -> Self { Self(bits) }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                {
                    if name == "IS_C" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::IS_C.bits()));
                    }
                };
                ;
                {
                    if name == "IS_SIMD" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::IS_SIMD.bits()));
                    }
                };
                ;
                {
                    if name == "IS_TRANSPARENT" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::IS_TRANSPARENT.bits()));
                    }
                };
                ;
                {
                    if name == "IS_LINEAR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::IS_LINEAR.bits()));
                    }
                };
                ;
                {
                    if name == "RANDOMIZE_LAYOUT" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::RANDOMIZE_LAYOUT.bits()));
                    }
                };
                ;
                {
                    if name == "PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS.bits()));
                    }
                };
                ;
                {
                    if name == "IS_SCALABLE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::IS_SCALABLE.bits()));
                    }
                };
                ;
                {
                    if name == "FIELD_ORDER_UNOPTIMIZABLE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE.bits()));
                    }
                };
                ;
                {
                    if name == "ABI_UNOPTIMIZABLE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(ReprFlags::ABI_UNOPTIMIZABLE.bits()));
                    }
                };
                ;
                let _ = name;
                ::bitflags::__private::core::option::Option::None
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool {
                self.0 == <u8 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool {
                Self::all().0 | self.0 == self.0
            }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0 & other.0 != <u8 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0 & other.0 == other.0
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) {
                *self = Self(self.0).union(other);
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) {
                *self = Self(self.0).difference(other);
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) {
                *self = Self(self.0).symmetric_difference(other);
            }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                if value { self.insert(other); } else { self.remove(other); }
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0 & other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0 | other.0)
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0 & !other.0)
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0 ^ other.0)
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self::from_bits_truncate(!self.0)
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for ReprFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for ReprFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for ReprFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for ReprFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for ReprFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: ReprFlags) -> Self { self.union(other) }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for ReprFlags {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for ReprFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for ReprFlags {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for ReprFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for ReprFlags {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for ReprFlags {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for ReprFlags {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for ReprFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<ReprFlags> for
            ReprFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<ReprFlags> for
            ReprFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl ReprFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<ReprFlags> {
                ::bitflags::iter::Iter::__private_const_new(<ReprFlags as
                        ::bitflags::Flags>::FLAGS,
                    ReprFlags::from_bits_retain(self.bits()),
                    ReprFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<ReprFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<ReprFlags as
                        ::bitflags::Flags>::FLAGS,
                    ReprFlags::from_bits_retain(self.bits()),
                    ReprFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for ReprFlags {
            type Item = ReprFlags;
            type IntoIter = ::bitflags::iter::Iter<ReprFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags! {
82    impl ReprFlags: u8 {
83        const IS_C               = 1 << 0;
84        const IS_SIMD            = 1 << 1;
85        const IS_TRANSPARENT     = 1 << 2;
86        /// Internal only for now. If true, don't reorder fields.
87        /// On its own it does not prevent ABI optimizations.
88        const IS_LINEAR          = 1 << 3;
89        /// If true, the type's crate has opted into layout randomization.
90        /// Other flags can still inhibit reordering and thus randomization.
91        /// The seed stored in `ReprOptions.field_shuffle_seed`.
92        const RANDOMIZE_LAYOUT   = 1 << 4;
93        /// If true, the type is always passed indirectly by non-Rustic ABIs.
94        /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details.
95        const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS = 1 << 5;
96        const IS_SCALABLE        = 1 << 6;
97         // Any of these flags being set prevent field reordering optimisation.
98        const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
99                                 | ReprFlags::IS_SIMD.bits()
100                                 | ReprFlags::IS_SCALABLE.bits()
101                                 | ReprFlags::IS_LINEAR.bits();
102        const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
103    }
104}
105
106// This is the same as `rustc_data_structures::external_bitflags_debug` but without the
107// `rustc_data_structures` to make it build on stable.
108impl std::fmt::Debug for ReprFlags {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        bitflags::parser::to_writer(self, f)
111    }
112}
113
114#[derive(#[automatically_derived]
impl ::core::marker::Copy for IntegerType { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IntegerType {
    #[inline]
    fn clone(&self) -> IntegerType {
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<Integer>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for IntegerType {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            IntegerType::Pointer(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Pointer", &__self_0),
            IntegerType::Fixed(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Fixed",
                    __self_0, &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for IntegerType {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Integer>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for IntegerType {
    #[inline]
    fn eq(&self, other: &IntegerType) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IntegerType::Pointer(__self_0),
                    IntegerType::Pointer(__arg1_0)) => __self_0 == __arg1_0,
                (IntegerType::Fixed(__self_0, __self_1),
                    IntegerType::Fixed(__arg1_0, __arg1_1)) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq)]
115#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for IntegerType {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        IntegerType::Pointer(ref __binding_0) => { 0usize }
                        IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
                            1usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    IntegerType::Pointer(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for IntegerType {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        IntegerType::Pointer(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        IntegerType::Fixed(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `IntegerType`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for IntegerType
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    IntegerType::Pointer(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
116pub enum IntegerType {
117    /// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g.
118    /// `Pointer(true)` means `isize`.
119    Pointer(bool),
120    /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. The bool field shows signedness, e.g.
121    /// `Fixed(I8, false)` means `u8`.
122    Fixed(Integer, bool),
123}
124
125impl IntegerType {
126    pub fn is_signed(&self) -> bool {
127        match self {
128            IntegerType::Pointer(b) => *b,
129            IntegerType::Fixed(_, b) => *b,
130        }
131    }
132}
133
134#[derive(#[automatically_derived]
impl ::core::marker::Copy for ScalableElt { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ScalableElt {
    #[inline]
    fn clone(&self) -> ScalableElt {
        let _: ::core::clone::AssertParamIsClone<u16>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ScalableElt {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ScalableElt::ElementCount(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ElementCount", &__self_0),
            ScalableElt::Container =>
                ::core::fmt::Formatter::write_str(f, "Container"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for ScalableElt {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u16>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for ScalableElt {
    #[inline]
    fn eq(&self, other: &ScalableElt) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ScalableElt::ElementCount(__self_0),
                    ScalableElt::ElementCount(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq)]
135#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ScalableElt {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        ScalableElt::ElementCount(ref __binding_0) => { 0usize }
                        ScalableElt::Container => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    ScalableElt::ElementCount(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    ScalableElt::Container => {}
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ScalableElt {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        ScalableElt::ElementCount(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { ScalableElt::Container }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ScalableElt`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for ScalableElt
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    ScalableElt::ElementCount(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    ScalableElt::Container => {}
                }
            }
        }
    };StableHash))]
136pub enum ScalableElt {
137    /// `N` in `rustc_scalable_vector(N)` - the element count of the scalable vector
138    ElementCount(u16),
139    /// `rustc_scalable_vector` w/out `N`, used for tuple types of scalable vectors that only
140    /// contain other scalable vectors
141    Container,
142}
143
144/// Represents the repr options provided by the user.
145#[derive(#[automatically_derived]
impl ::core::marker::Copy for ReprOptions { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ReprOptions {
    #[inline]
    fn clone(&self) -> ReprOptions {
        let _: ::core::clone::AssertParamIsClone<Option<IntegerType>>;
        let _: ::core::clone::AssertParamIsClone<Option<Align>>;
        let _: ::core::clone::AssertParamIsClone<Option<Align>>;
        let _: ::core::clone::AssertParamIsClone<ReprFlags>;
        let _: ::core::clone::AssertParamIsClone<Option<ScalableElt>>;
        let _: ::core::clone::AssertParamIsClone<Hash64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ReprOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["int", "align", "pack", "flags", "scalable",
                        "field_shuffle_seed"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.int, &self.align, &self.pack, &self.flags, &self.scalable,
                        &&self.field_shuffle_seed];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "ReprOptions",
            names, values)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for ReprOptions {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Option<IntegerType>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Align>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Align>>;
        let _: ::core::cmp::AssertParamIsEq<ReprFlags>;
        let _: ::core::cmp::AssertParamIsEq<Option<ScalableElt>>;
        let _: ::core::cmp::AssertParamIsEq<Hash64>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for ReprOptions {
    #[inline]
    fn eq(&self, other: &ReprOptions) -> bool {
        self.int == other.int && self.align == other.align &&
                        self.pack == other.pack && self.flags == other.flags &&
                self.scalable == other.scalable &&
            self.field_shuffle_seed == other.field_shuffle_seed
    }
}PartialEq, #[automatically_derived]
impl ::core::default::Default for ReprOptions {
    #[inline]
    fn default() -> ReprOptions {
        ReprOptions {
            int: ::core::default::Default::default(),
            align: ::core::default::Default::default(),
            pack: ::core::default::Default::default(),
            flags: ::core::default::Default::default(),
            scalable: ::core::default::Default::default(),
            field_shuffle_seed: ::core::default::Default::default(),
        }
    }
}Default)]
146#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for ReprOptions {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    ReprOptions {
                        int: ref __binding_0,
                        align: ref __binding_1,
                        pack: ref __binding_2,
                        flags: ref __binding_3,
                        scalable: ref __binding_4,
                        field_shuffle_seed: ref __binding_5 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for ReprOptions {
            fn decode(__decoder: &mut __D) -> Self {
                ReprOptions {
                    int: ::rustc_serialize::Decodable::decode(__decoder),
                    align: ::rustc_serialize::Decodable::decode(__decoder),
                    pack: ::rustc_serialize::Decodable::decode(__decoder),
                    flags: ::rustc_serialize::Decodable::decode(__decoder),
                    scalable: ::rustc_serialize::Decodable::decode(__decoder),
                    field_shuffle_seed: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for ReprOptions
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    ReprOptions {
                        int: ref __binding_0,
                        align: ref __binding_1,
                        pack: ref __binding_2,
                        flags: ref __binding_3,
                        scalable: ref __binding_4,
                        field_shuffle_seed: ref __binding_5 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
147pub struct ReprOptions {
148    pub int: Option<IntegerType>,
149    pub align: Option<Align>,
150    pub pack: Option<Align>,
151    pub flags: ReprFlags,
152    /// `#[rustc_scalable_vector]`
153    pub scalable: Option<ScalableElt>,
154    /// The seed to be used for randomizing a type's layout
155    ///
156    /// Note: This could technically be a `u128` which would
157    /// be the "most accurate" hash as it'd encompass the item and crate
158    /// hash without loss, but it does pay the price of being larger.
159    /// Everything's a tradeoff, a 64-bit seed should be sufficient for our
160    /// purposes (primarily `-Z randomize-layout`)
161    pub field_shuffle_seed: Hash64,
162}
163
164impl ReprOptions {
165    #[inline]
166    pub fn simd(&self) -> bool {
167        self.flags.contains(ReprFlags::IS_SIMD)
168    }
169
170    #[inline]
171    pub fn scalable(&self) -> bool {
172        self.flags.contains(ReprFlags::IS_SCALABLE)
173    }
174
175    #[inline]
176    pub fn c(&self) -> bool {
177        self.flags.contains(ReprFlags::IS_C)
178    }
179
180    #[inline]
181    pub fn packed(&self) -> bool {
182        self.pack.is_some()
183    }
184
185    #[inline]
186    pub fn transparent(&self) -> bool {
187        self.flags.contains(ReprFlags::IS_TRANSPARENT)
188    }
189
190    #[inline]
191    pub fn linear(&self) -> bool {
192        self.flags.contains(ReprFlags::IS_LINEAR)
193    }
194
195    /// Returns the discriminant type, given these `repr` options.
196    /// This must only be called on enums!
197    ///
198    /// This is the "typeck type" of the discriminant, which is effectively the maximum size:
199    /// discriminant values will be wrapped to fit (with a lint). Layout can later decide to use a
200    /// smaller type for the tag that stores the discriminant at runtime and that will work just
201    /// fine, it just induces casts when getting/setting the discriminant.
202    pub fn discr_type(&self) -> IntegerType {
203        self.int.unwrap_or(IntegerType::Pointer(true))
204    }
205
206    /// Returns `true` if this `#[repr()]` should inhabit "smart enum
207    /// layout" optimizations, such as representing `Foo<&T>` as a
208    /// single pointer.
209    pub fn inhibit_enum_layout_opt(&self) -> bool {
210        self.c() || self.int.is_some()
211    }
212
213    pub fn inhibit_newtype_abi_optimization(&self) -> bool {
214        self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
215    }
216
217    /// Returns `true` if this `#[repr()]` guarantees a fixed field order,
218    /// e.g. `repr(C)` or `repr(<int>)`.
219    pub fn inhibit_struct_field_reordering(&self) -> bool {
220        self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
221    }
222
223    /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
224    /// was enabled for its declaration crate.
225    pub fn can_randomize_type_layout(&self) -> bool {
226        !self.inhibit_struct_field_reordering() && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
227    }
228
229    /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
230    pub fn inhibits_union_abi_opt(&self) -> bool {
231        self.c()
232    }
233}
234
235/// The maximum supported number of lanes in a SIMD vector.
236///
237/// This value is selected based on backend support:
238/// * LLVM does not appear to have a vector width limit.
239/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
240pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
241
242/// How pointers are represented in a given address space
243#[derive(#[automatically_derived]
impl ::core::marker::Copy for PointerSpec { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PointerSpec {
    #[inline]
    fn clone(&self) -> PointerSpec {
        let _: ::core::clone::AssertParamIsClone<Size>;
        let _: ::core::clone::AssertParamIsClone<Align>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PointerSpec {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "PointerSpec",
            "pointer_size", &self.pointer_size, "pointer_align",
            &self.pointer_align, "pointer_offset", &self.pointer_offset,
            "_is_fat", &&self._is_fat)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PointerSpec {
    #[inline]
    fn eq(&self, other: &PointerSpec) -> bool {
        self._is_fat == other._is_fat &&
                    self.pointer_size == other.pointer_size &&
                self.pointer_align == other.pointer_align &&
            self.pointer_offset == other.pointer_offset
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PointerSpec {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Size>;
        let _: ::core::cmp::AssertParamIsEq<Align>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq)]
244pub struct PointerSpec {
245    /// The size of the bitwise representation of the pointer.
246    pointer_size: Size,
247    /// The alignment of pointers for this address space
248    pointer_align: Align,
249    /// The size of the value a pointer can be offset by in this address space.
250    pointer_offset: Size,
251    /// Pointers into this address space contain extra metadata
252    /// FIXME(workingjubilee): Consider adequately reflecting this in the compiler?
253    _is_fat: bool,
254}
255
256/// Parsed [Data layout](https://llvm.org/docs/LangRef.html#data-layout)
257/// for a target, which contains everything needed to compute layouts.
258#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TargetDataLayout {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["endian", "i1_align", "i8_align", "i16_align", "i32_align",
                        "i64_align", "i128_align", "f16_align", "f32_align",
                        "f64_align", "f128_align", "aggregate_align",
                        "vector_align", "default_address_space",
                        "default_address_space_pointer_spec", "address_space_info",
                        "instruction_address_space", "c_enum_min_size"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.endian, &self.i1_align, &self.i8_align, &self.i16_align,
                        &self.i32_align, &self.i64_align, &self.i128_align,
                        &self.f16_align, &self.f32_align, &self.f64_align,
                        &self.f128_align, &self.aggregate_align, &self.vector_align,
                        &self.default_address_space,
                        &self.default_address_space_pointer_spec,
                        &self.address_space_info, &self.instruction_address_space,
                        &&self.c_enum_min_size];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "TargetDataLayout", names, values)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for TargetDataLayout {
    #[inline]
    fn eq(&self, other: &TargetDataLayout) -> bool {
        self.endian == other.endian && self.i1_align == other.i1_align &&
                                                                        self.i8_align == other.i8_align &&
                                                                    self.i16_align == other.i16_align &&
                                                                self.i32_align == other.i32_align &&
                                                            self.i64_align == other.i64_align &&
                                                        self.i128_align == other.i128_align &&
                                                    self.f16_align == other.f16_align &&
                                                self.f32_align == other.f32_align &&
                                            self.f64_align == other.f64_align &&
                                        self.f128_align == other.f128_align &&
                                    self.aggregate_align == other.aggregate_align &&
                                self.vector_align == other.vector_align &&
                            self.default_address_space == other.default_address_space &&
                        self.default_address_space_pointer_spec ==
                            other.default_address_space_pointer_spec &&
                    self.address_space_info == other.address_space_info &&
                self.instruction_address_space ==
                    other.instruction_address_space &&
            self.c_enum_min_size == other.c_enum_min_size
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for TargetDataLayout {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Endian>;
        let _: ::core::cmp::AssertParamIsEq<Align>;
        let _: ::core::cmp::AssertParamIsEq<Vec<(Size, Align)>>;
        let _: ::core::cmp::AssertParamIsEq<AddressSpace>;
        let _: ::core::cmp::AssertParamIsEq<PointerSpec>;
        let _: ::core::cmp::AssertParamIsEq<Vec<(AddressSpace, PointerSpec)>>;
        let _: ::core::cmp::AssertParamIsEq<Integer>;
    }
}Eq)]
259pub struct TargetDataLayout {
260    pub endian: Endian,
261    pub i1_align: Align,
262    pub i8_align: Align,
263    pub i16_align: Align,
264    pub i32_align: Align,
265    pub i64_align: Align,
266    pub i128_align: Align,
267    pub f16_align: Align,
268    pub f32_align: Align,
269    pub f64_align: Align,
270    pub f128_align: Align,
271    pub aggregate_align: Align,
272
273    /// Alignments for vector types.
274    pub vector_align: Vec<(Size, Align)>,
275
276    pub default_address_space: AddressSpace,
277    pub default_address_space_pointer_spec: PointerSpec,
278
279    /// Address space information of all known address spaces.
280    ///
281    /// # Note
282    ///
283    /// This vector does not contain the [`PointerSpec`] relative to the default address space,
284    /// which instead lives in [`Self::default_address_space_pointer_spec`].
285    address_space_info: Vec<(AddressSpace, PointerSpec)>,
286
287    pub instruction_address_space: AddressSpace,
288
289    /// Minimum size of #[repr(C)] enums (default c_int::BITS, usually 32)
290    /// Note: This isn't in LLVM's data layout string, it is `short_enum`
291    /// so the only valid spec for LLVM is c_int::BITS or 8
292    pub c_enum_min_size: Integer,
293}
294
295impl Default for TargetDataLayout {
296    /// Creates an instance of `TargetDataLayout`.
297    fn default() -> TargetDataLayout {
298        let align = |bits| Align::from_bits(bits).unwrap();
299        TargetDataLayout {
300            endian: Endian::Big,
301            i1_align: align(8),
302            i8_align: align(8),
303            i16_align: align(16),
304            i32_align: align(32),
305            i64_align: align(32),
306            i128_align: align(32),
307            f16_align: align(16),
308            f32_align: align(32),
309            f64_align: align(64),
310            f128_align: align(128),
311            aggregate_align: align(8),
312            vector_align: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(Size::from_bits(64), align(64)),
                (Size::from_bits(128), align(128))]))vec![
313                (Size::from_bits(64), align(64)),
314                (Size::from_bits(128), align(128)),
315            ],
316            default_address_space: AddressSpace::ZERO,
317            default_address_space_pointer_spec: PointerSpec {
318                pointer_size: Size::from_bits(64),
319                pointer_align: align(64),
320                pointer_offset: Size::from_bits(64),
321                _is_fat: false,
322            },
323            address_space_info: ::alloc::vec::Vec::new()vec![],
324            instruction_address_space: AddressSpace::ZERO,
325            c_enum_min_size: Integer::I32,
326        }
327    }
328}
329
330pub enum TargetDataLayoutError<'a> {
331    InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
332    InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
333    MissingAlignment { cause: &'a str },
334    InvalidAlignment { cause: &'a str, err: AlignFromBytesError },
335    InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
336    InconsistentTargetPointerWidth { pointer_size: u64, target: u16 },
337    InvalidBitsSize { err: String },
338    UnknownPointerSpecification { err: String },
339}
340
341#[cfg(feature = "nightly")]
342impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutError<'_> {
343    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
344        match self {
345            TargetDataLayoutError::InvalidAddressSpace { addr_space, err, cause } => {
346                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
347                    .with_arg("addr_space", addr_space)
348                    .with_arg("cause", cause)
349                    .with_arg("err", err)
350            }
351            TargetDataLayoutError::InvalidBits { kind, bit, cause, err } => {
352                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
353                    .with_arg("kind", kind)
354                    .with_arg("bit", bit)
355                    .with_arg("cause", cause)
356                    .with_arg("err", err)
357            }
358            TargetDataLayoutError::MissingAlignment { cause } => {
359                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("missing alignment for `{$cause}` in \"data-layout\""))msg!("missing alignment for `{$cause}` in \"data-layout\""))
360                    .with_arg("cause", cause)
361            }
362            TargetDataLayoutError::InvalidAlignment { cause, err } => {
363                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))
364                    .with_arg("cause", cause)
365                    .with_arg("err", err.to_string())
366            }
367            TargetDataLayoutError::InconsistentTargetArchitecture { dl, target } => {
368                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))msg!("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))
369                    .with_arg("dl", dl).with_arg("target", target)
370            }
371            TargetDataLayoutError::InconsistentTargetPointerWidth { pointer_size, target } => {
372                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))msg!("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))
373                    .with_arg("pointer_size", pointer_size).with_arg("target", target)
374            }
375            TargetDataLayoutError::InvalidBitsSize { err } => {
376                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$err}"))msg!("{$err}")).with_arg("err", err)
377            }
378            TargetDataLayoutError::UnknownPointerSpecification { err } => {
379                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("unknown pointer specification `{$err}` in datalayout string"))msg!("unknown pointer specification `{$err}` in datalayout string"))
380                    .with_arg("err", err)
381            }
382        }
383    }
384}
385
386impl TargetDataLayout {
387    /// Parse data layout from an
388    /// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
389    ///
390    /// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be
391    /// determined from llvm string.
392    pub fn parse_from_llvm_datalayout_string<'a>(
393        input: &'a str,
394        default_address_space: AddressSpace,
395    ) -> Result<TargetDataLayout, TargetDataLayoutError<'a>> {
396        // Parse an address space index from a string.
397        let parse_address_space = |s: &'a str, cause: &'a str| {
398            s.parse::<u32>().map(AddressSpace).map_err(|err| {
399                TargetDataLayoutError::InvalidAddressSpace { addr_space: s, cause, err }
400            })
401        };
402
403        // Parse a bit count from a string.
404        let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
405            s.parse::<u64>().map_err(|err| TargetDataLayoutError::InvalidBits {
406                kind,
407                bit: s,
408                cause,
409                err,
410            })
411        };
412
413        // Parse a size string.
414        let parse_size =
415            |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
416
417        // Parse an alignment string.
418        let parse_align_str = |s: &'a str, cause: &'a str| {
419            let align_from_bits = |bits| {
420                Align::from_bits(bits)
421                    .map_err(|err| TargetDataLayoutError::InvalidAlignment { cause, err })
422            };
423            let abi = parse_bits(s, "alignment", cause)?;
424            Ok(align_from_bits(abi)?)
425        };
426
427        // Parse an alignment sequence, possibly in the form `<align>[:<preferred_alignment>]`,
428        // ignoring the secondary alignment specifications.
429        let parse_align_seq = |s: &[&'a str], cause: &'a str| {
430            if s.is_empty() {
431                return Err(TargetDataLayoutError::MissingAlignment { cause });
432            }
433            parse_align_str(s[0], cause)
434        };
435
436        let mut dl = TargetDataLayout::default();
437        dl.default_address_space = default_address_space;
438
439        let mut i128_align_src = 64;
440        for spec in input.split('-') {
441            let spec_parts = spec.split(':').collect::<Vec<_>>();
442
443            match &*spec_parts {
444                ["e"] => dl.endian = Endian::Little,
445                ["E"] => dl.endian = Endian::Big,
446                [p] if p.starts_with('P') => {
447                    dl.instruction_address_space = parse_address_space(&p[1..], "P")?
448                }
449                ["a", a @ ..] => dl.aggregate_align = parse_align_seq(a, "a")?,
450                ["f16", a @ ..] => dl.f16_align = parse_align_seq(a, "f16")?,
451                ["f32", a @ ..] => dl.f32_align = parse_align_seq(a, "f32")?,
452                ["f64", a @ ..] => dl.f64_align = parse_align_seq(a, "f64")?,
453                ["f128", a @ ..] => dl.f128_align = parse_align_seq(a, "f128")?,
454                [p, s, a @ ..] if p.starts_with("p") => {
455                    let mut p = p.strip_prefix('p').unwrap();
456                    let mut _is_fat = false;
457
458                    // Some targets, such as CHERI, use the 'f' suffix in the p- spec to signal that
459                    // they use 'fat' pointers. The resulting prefix may look like `pf<addr_space>`.
460
461                    if p.starts_with('f') {
462                        p = p.strip_prefix('f').unwrap();
463                        _is_fat = true;
464                    }
465
466                    // However, we currently don't take into account further specifications:
467                    // an error is emitted instead.
468                    if p.starts_with(char::is_alphabetic) {
469                        return Err(TargetDataLayoutError::UnknownPointerSpecification {
470                            err: p.to_string(),
471                        });
472                    }
473
474                    let addr_space = if !p.is_empty() {
475                        parse_address_space(p, "p-")?
476                    } else {
477                        AddressSpace::ZERO
478                    };
479
480                    let pointer_size = parse_size(s, "p-")?;
481                    let pointer_align = parse_align_seq(a, "p-")?;
482                    let info = PointerSpec {
483                        pointer_offset: pointer_size,
484                        pointer_size,
485                        pointer_align,
486                        _is_fat,
487                    };
488                    if addr_space == default_address_space {
489                        dl.default_address_space_pointer_spec = info;
490                    } else {
491                        match dl.address_space_info.iter_mut().find(|(a, _)| *a == addr_space) {
492                            Some(e) => e.1 = info,
493                            None => {
494                                dl.address_space_info.push((addr_space, info));
495                            }
496                        }
497                    }
498                }
499                [p, s, a, _pr, i] if p.starts_with("p") => {
500                    let mut p = p.strip_prefix('p').unwrap();
501                    let mut _is_fat = false;
502
503                    // Some targets, such as CHERI, use the 'f' suffix in the p- spec to signal that
504                    // they use 'fat' pointers. The resulting prefix may look like `pf<addr_space>`.
505
506                    if p.starts_with('f') {
507                        p = p.strip_prefix('f').unwrap();
508                        _is_fat = true;
509                    }
510
511                    // However, we currently don't take into account further specifications:
512                    // an error is emitted instead.
513                    if p.starts_with(char::is_alphabetic) {
514                        return Err(TargetDataLayoutError::UnknownPointerSpecification {
515                            err: p.to_string(),
516                        });
517                    }
518
519                    let addr_space = if !p.is_empty() {
520                        parse_address_space(p, "p")?
521                    } else {
522                        AddressSpace::ZERO
523                    };
524
525                    let info = PointerSpec {
526                        pointer_size: parse_size(s, "p-")?,
527                        pointer_align: parse_align_str(a, "p-")?,
528                        pointer_offset: parse_size(i, "p-")?,
529                        _is_fat,
530                    };
531
532                    if addr_space == default_address_space {
533                        dl.default_address_space_pointer_spec = info;
534                    } else {
535                        match dl.address_space_info.iter_mut().find(|(a, _)| *a == addr_space) {
536                            Some(e) => e.1 = info,
537                            None => {
538                                dl.address_space_info.push((addr_space, info));
539                            }
540                        }
541                    }
542                }
543
544                [s, a @ ..] if s.starts_with('i') => {
545                    let Ok(bits) = s[1..].parse::<u64>() else {
546                        parse_size(&s[1..], "i")?; // For the user error.
547                        continue;
548                    };
549                    let a = parse_align_seq(a, s)?;
550                    match bits {
551                        1 => dl.i1_align = a,
552                        8 => dl.i8_align = a,
553                        16 => dl.i16_align = a,
554                        32 => dl.i32_align = a,
555                        64 => dl.i64_align = a,
556                        _ => {}
557                    }
558                    if bits >= i128_align_src && bits <= 128 {
559                        // Default alignment for i128 is decided by taking the alignment of
560                        // largest-sized i{64..=128}.
561                        i128_align_src = bits;
562                        dl.i128_align = a;
563                    }
564                }
565                [s, a @ ..] if s.starts_with('v') => {
566                    let v_size = parse_size(&s[1..], "v")?;
567                    let a = parse_align_seq(a, s)?;
568                    if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
569                        v.1 = a;
570                        continue;
571                    }
572                    // No existing entry, add a new one.
573                    dl.vector_align.push((v_size, a));
574                }
575                _ => {} // Ignore everything else.
576            }
577        }
578
579        // Inherit, if not given, address space information for specific LLVM elements from the
580        // default data address space.
581        if (dl.instruction_address_space != dl.default_address_space)
582            && dl
583                .address_space_info
584                .iter()
585                .find(|(a, _)| *a == dl.instruction_address_space)
586                .is_none()
587        {
588            dl.address_space_info.push((
589                dl.instruction_address_space,
590                dl.default_address_space_pointer_spec.clone(),
591            ));
592        }
593
594        Ok(dl)
595    }
596
597    /// Returns **exclusive** upper bound on object size in bytes, in the default data address
598    /// space.
599    ///
600    /// The theoretical maximum object size is defined as the maximum positive `isize` value.
601    /// This ensures that the `offset` semantics remain well-defined by allowing it to correctly
602    /// index every address within an object along with one byte past the end, along with allowing
603    /// `isize` to store the difference between any two pointers into an object.
604    ///
605    /// LLVM uses a 64-bit integer to represent object size in *bits*, but we care only for bytes,
606    /// so we adopt such a more-constrained size bound due to its technical limitations.
607    #[inline]
608    pub fn obj_size_bound(&self) -> u64 {
609        match self.pointer_size().bits() {
610            16 => 1 << 15,
611            32 => 1 << 31,
612            64 => 1 << 61,
613            bits => {
    ::core::panicking::panic_fmt(format_args!("obj_size_bound: unknown pointer bit size {0}",
            bits));
}panic!("obj_size_bound: unknown pointer bit size {bits}"),
614        }
615    }
616
617    /// Returns **exclusive** upper bound on object size in bytes.
618    ///
619    /// The theoretical maximum object size is defined as the maximum positive `isize` value.
620    /// This ensures that the `offset` semantics remain well-defined by allowing it to correctly
621    /// index every address within an object along with one byte past the end, along with allowing
622    /// `isize` to store the difference between any two pointers into an object.
623    ///
624    /// LLVM uses a 64-bit integer to represent object size in *bits*, but we care only for bytes,
625    /// so we adopt such a more-constrained size bound due to its technical limitations.
626    #[inline]
627    pub fn obj_size_bound_in(&self, address_space: AddressSpace) -> u64 {
628        match self.pointer_size_in(address_space).bits() {
629            16 => 1 << 15,
630            32 => 1 << 31,
631            64 => 1 << 61,
632            bits => {
    ::core::panicking::panic_fmt(format_args!("obj_size_bound: unknown pointer bit size {0}",
            bits));
}panic!("obj_size_bound: unknown pointer bit size {bits}"),
633        }
634    }
635
636    #[inline]
637    pub fn ptr_sized_integer(&self) -> Integer {
638        use Integer::*;
639        match self.pointer_offset().bits() {
640            16 => I16,
641            32 => I32,
642            64 => I64,
643            bits => {
    ::core::panicking::panic_fmt(format_args!("ptr_sized_integer: unknown pointer bit size {0}",
            bits));
}panic!("ptr_sized_integer: unknown pointer bit size {bits}"),
644        }
645    }
646
647    #[inline]
648    pub fn ptr_sized_integer_in(&self, address_space: AddressSpace) -> Integer {
649        use Integer::*;
650        match self.pointer_offset_in(address_space).bits() {
651            16 => I16,
652            32 => I32,
653            64 => I64,
654            bits => {
    ::core::panicking::panic_fmt(format_args!("ptr_sized_integer: unknown pointer bit size {0}",
            bits));
}panic!("ptr_sized_integer: unknown pointer bit size {bits}"),
655        }
656    }
657
658    /// psABI-mandated alignment for a vector type, if any
659    #[inline]
660    fn cabi_vector_align(&self, vec_size: Size) -> Option<Align> {
661        self.vector_align
662            .iter()
663            .find(|(size, _align)| *size == vec_size)
664            .map(|(_size, align)| *align)
665    }
666
667    /// an alignment resembling the one LLVM would pick for a vector
668    #[inline]
669    pub fn llvmlike_vector_align(&self, vec_size: Size) -> Align {
670        self.cabi_vector_align(vec_size)
671            .unwrap_or(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap())
672    }
673
674    /// Get the pointer size in the default data address space.
675    #[inline]
676    pub fn pointer_size(&self) -> Size {
677        self.default_address_space_pointer_spec.pointer_size
678    }
679
680    /// Get the pointer size in a specific address space.
681    #[inline]
682    pub fn pointer_size_in(&self, c: AddressSpace) -> Size {
683        if c == self.default_address_space {
684            return self.default_address_space_pointer_spec.pointer_size;
685        }
686
687        if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
688            e.1.pointer_size
689        } else {
690            {
    ::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
            c));
};panic!("Use of unknown address space {c:?}");
691        }
692    }
693
694    /// Get the pointer index in the default data address space.
695    #[inline]
696    pub fn pointer_offset(&self) -> Size {
697        self.default_address_space_pointer_spec.pointer_offset
698    }
699
700    /// Get the pointer index in a specific address space.
701    #[inline]
702    pub fn pointer_offset_in(&self, c: AddressSpace) -> Size {
703        if c == self.default_address_space {
704            return self.default_address_space_pointer_spec.pointer_offset;
705        }
706
707        if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
708            e.1.pointer_offset
709        } else {
710            {
    ::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
            c));
};panic!("Use of unknown address space {c:?}");
711        }
712    }
713
714    /// Get the pointer alignment in the default data address space.
715    #[inline]
716    pub fn pointer_align(&self) -> AbiAlign {
717        AbiAlign::new(self.default_address_space_pointer_spec.pointer_align)
718    }
719
720    /// Get the pointer alignment in a specific address space.
721    #[inline]
722    pub fn pointer_align_in(&self, c: AddressSpace) -> AbiAlign {
723        AbiAlign::new(if c == self.default_address_space {
724            self.default_address_space_pointer_spec.pointer_align
725        } else if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
726            e.1.pointer_align
727        } else {
728            {
    ::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
            c));
};panic!("Use of unknown address space {c:?}");
729        })
730    }
731}
732
733pub trait HasDataLayout {
734    fn data_layout(&self) -> &TargetDataLayout;
735}
736
737impl HasDataLayout for TargetDataLayout {
738    #[inline]
739    fn data_layout(&self) -> &TargetDataLayout {
740        self
741    }
742}
743
744// used by rust-analyzer
745impl HasDataLayout for &TargetDataLayout {
746    #[inline]
747    fn data_layout(&self) -> &TargetDataLayout {
748        (**self).data_layout()
749    }
750}
751
752/// Endianness of the target, which must match cfg(target-endian).
753#[derive(#[automatically_derived]
impl ::core::marker::Copy for Endian { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Endian {
    #[inline]
    fn clone(&self) -> Endian { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Endian {
    #[inline]
    fn eq(&self, other: &Endian) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Endian {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
754pub enum Endian {
755    Little,
756    Big,
757}
758
759impl Endian {
760    pub fn as_str(&self) -> &'static str {
761        match self {
762            Self::Little => "little",
763            Self::Big => "big",
764        }
765    }
766
767    #[cfg(feature = "nightly")]
768    pub fn desc_symbol(&self) -> Symbol {
769        match self {
770            Self::Little => sym::little,
771            Self::Big => sym::big,
772        }
773    }
774}
775
776impl fmt::Debug for Endian {
777    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
778        f.write_str(self.as_str())
779    }
780}
781
782impl FromStr for Endian {
783    type Err = String;
784
785    fn from_str(s: &str) -> Result<Self, Self::Err> {
786        match s {
787            "little" => Ok(Self::Little),
788            "big" => Ok(Self::Big),
789            _ => Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown endian: \"{0}\"", s))
    })format!(r#"unknown endian: "{s}""#)),
790        }
791    }
792}
793
794/// Size of a type in bytes.
795#[derive(#[automatically_derived]
impl ::core::marker::Copy for Size { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Size {
    #[inline]
    fn clone(&self) -> Size {
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Size {
    #[inline]
    fn eq(&self, other: &Size) -> bool { self.raw == other.raw }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Size {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u64>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Size {
    #[inline]
    fn partial_cmp(&self, other: &Size)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Size {
    #[inline]
    fn cmp(&self, other: &Size) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.raw, &other.raw)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Size {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.raw, state)
    }
}Hash)]
796#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Size {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Size { raw: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Size {
            fn decode(__decoder: &mut __D) -> Self {
                Size { raw: ::rustc_serialize::Decodable::decode(__decoder) }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Size {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Size { raw: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
797pub struct Size {
798    raw: u64,
799}
800
801#[cfg(feature = "nightly")]
802impl StableOrd for Size {
803    const CAN_USE_UNSTABLE_SORT: bool = true;
804
805    // `Ord` is implemented as just comparing numerical values and numerical values
806    // are not changed by (de-)serialization.
807    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
808}
809
810// This is debug-printed a lot in larger structs, don't waste too much space there
811impl fmt::Debug for Size {
812    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
813        f.write_fmt(format_args!("Size({0} bytes)", self.bytes()))write!(f, "Size({} bytes)", self.bytes())
814    }
815}
816
817impl Size {
818    pub const ZERO: Size = Size { raw: 0 };
819
820    /// Rounds `bits` up to the next-higher byte boundary, if `bits` is
821    /// not a multiple of 8.
822    pub fn from_bits(bits: impl TryInto<u64>) -> Size {
823        let bits = bits.try_into().ok().unwrap();
824        Size { raw: bits.div_ceil(8) }
825    }
826
827    #[inline]
828    pub fn from_bytes(bytes: impl TryInto<u64>) -> Size {
829        let bytes: u64 = bytes.try_into().ok().unwrap();
830        Size { raw: bytes }
831    }
832
833    #[inline]
834    pub fn bytes(self) -> u64 {
835        self.raw
836    }
837
838    #[inline]
839    pub fn bytes_usize(self) -> usize {
840        self.bytes().try_into().unwrap()
841    }
842
843    #[inline]
844    pub fn bits(self) -> u64 {
845        #[cold]
846        fn overflow(bytes: u64) -> ! {
847            {
    ::core::panicking::panic_fmt(format_args!("Size::bits: {0} bytes in bits doesn\'t fit in u64",
            bytes));
}panic!("Size::bits: {bytes} bytes in bits doesn't fit in u64")
848        }
849
850        self.bytes().checked_mul(8).unwrap_or_else(|| overflow(self.bytes()))
851    }
852
853    #[inline]
854    pub fn bits_usize(self) -> usize {
855        self.bits().try_into().unwrap()
856    }
857
858    #[inline]
859    pub fn align_to(self, align: Align) -> Size {
860        let mask = align.bytes() - 1;
861        Size::from_bytes((self.bytes() + mask) & !mask)
862    }
863
864    #[inline]
865    pub fn is_aligned(self, align: Align) -> bool {
866        let mask = align.bytes() - 1;
867        self.bytes() & mask == 0
868    }
869
870    #[inline]
871    pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: &C) -> Option<Size> {
872        let dl = cx.data_layout();
873
874        let bytes = self.bytes().checked_add(offset.bytes())?;
875
876        if bytes < dl.obj_size_bound() { Some(Size::from_bytes(bytes)) } else { None }
877    }
878
879    #[inline]
880    pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: &C) -> Option<Size> {
881        let dl = cx.data_layout();
882
883        let bytes = self.bytes().checked_mul(count)?;
884        if bytes < dl.obj_size_bound() { Some(Size::from_bytes(bytes)) } else { None }
885    }
886
887    /// Truncates `value` to `self` bits and then sign-extends it to 128 bits
888    /// (i.e., if it is negative, fill with 1's on the left).
889    #[inline]
890    pub fn sign_extend(self, value: u128) -> i128 {
891        let size = self.bits();
892        if size == 0 {
893            // Truncated until nothing is left.
894            return 0;
895        }
896        // Sign-extend it.
897        let shift = 128 - size;
898        // Shift the unsigned value to the left, then shift back to the right as signed
899        // (essentially fills with sign bit on the left).
900        ((value << shift) as i128) >> shift
901    }
902
903    /// Truncates `value` to `self` bits.
904    #[inline]
905    pub fn truncate(self, value: u128) -> u128 {
906        let size = self.bits();
907        if size == 0 {
908            // Truncated until nothing is left.
909            return 0;
910        }
911        let shift = 128 - size;
912        // Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
913        (value << shift) >> shift
914    }
915
916    #[inline]
917    pub fn signed_int_min(&self) -> i128 {
918        self.sign_extend(1_u128 << (self.bits() - 1))
919    }
920
921    #[inline]
922    pub fn signed_int_max(&self) -> i128 {
923        i128::MAX >> (128 - self.bits())
924    }
925
926    #[inline]
927    pub fn unsigned_int_max(&self) -> u128 {
928        u128::MAX >> (128 - self.bits())
929    }
930}
931
932// Panicking addition, subtraction and multiplication for convenience.
933// Avoid during layout computation, return `LayoutError` instead.
934
935impl Add for Size {
936    type Output = Size;
937    #[inline]
938    fn add(self, other: Size) -> Size {
939        Size::from_bytes(self.bytes().checked_add(other.bytes()).unwrap_or_else(|| {
940            {
    ::core::panicking::panic_fmt(format_args!("Size::add: {0} + {1} doesn\'t fit in u64",
            self.bytes(), other.bytes()));
}panic!("Size::add: {} + {} doesn't fit in u64", self.bytes(), other.bytes())
941        }))
942    }
943}
944
945impl Sub for Size {
946    type Output = Size;
947    #[inline]
948    fn sub(self, other: Size) -> Size {
949        Size::from_bytes(self.bytes().checked_sub(other.bytes()).unwrap_or_else(|| {
950            {
    ::core::panicking::panic_fmt(format_args!("Size::sub: {0} - {1} would result in negative size",
            self.bytes(), other.bytes()));
}panic!("Size::sub: {} - {} would result in negative size", self.bytes(), other.bytes())
951        }))
952    }
953}
954
955impl Mul<Size> for u64 {
956    type Output = Size;
957    #[inline]
958    fn mul(self, size: Size) -> Size {
959        size * self
960    }
961}
962
963impl Mul<u64> for Size {
964    type Output = Size;
965    #[inline]
966    fn mul(self, count: u64) -> Size {
967        match self.bytes().checked_mul(count) {
968            Some(bytes) => Size::from_bytes(bytes),
969            None => {
    ::core::panicking::panic_fmt(format_args!("Size::mul: {0} * {1} doesn\'t fit in u64",
            self.bytes(), count));
}panic!("Size::mul: {} * {} doesn't fit in u64", self.bytes(), count),
970        }
971    }
972}
973
974impl AddAssign for Size {
975    #[inline]
976    fn add_assign(&mut self, other: Size) {
977        *self = *self + other;
978    }
979}
980
981#[cfg(feature = "nightly")]
982impl Step for Size {
983    #[inline]
984    fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
985        u64::steps_between(&start.bytes(), &end.bytes())
986    }
987
988    #[inline]
989    fn forward_checked(start: Self, count: usize) -> Option<Self> {
990        u64::forward_checked(start.bytes(), count).map(Self::from_bytes)
991    }
992
993    #[inline]
994    fn forward(start: Self, count: usize) -> Self {
995        Self::from_bytes(u64::forward(start.bytes(), count))
996    }
997
998    #[inline]
999    unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
1000        Self::from_bytes(unsafe { u64::forward_unchecked(start.bytes(), count) })
1001    }
1002
1003    #[inline]
1004    fn backward_checked(start: Self, count: usize) -> Option<Self> {
1005        u64::backward_checked(start.bytes(), count).map(Self::from_bytes)
1006    }
1007
1008    #[inline]
1009    fn backward(start: Self, count: usize) -> Self {
1010        Self::from_bytes(u64::backward(start.bytes(), count))
1011    }
1012
1013    #[inline]
1014    unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
1015        Self::from_bytes(unsafe { u64::backward_unchecked(start.bytes(), count) })
1016    }
1017}
1018
1019/// Alignment of a type in bytes (always a power of two).
1020#[derive(#[automatically_derived]
impl ::core::marker::Copy for Align { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Align {
    #[inline]
    fn clone(&self) -> Align {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Align {
    #[inline]
    fn eq(&self, other: &Align) -> bool { self.pow2 == other.pow2 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Align {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Align {
    #[inline]
    fn partial_cmp(&self, other: &Align)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Align {
    #[inline]
    fn cmp(&self, other: &Align) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.pow2, &other.pow2)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Align {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.pow2, state)
    }
}Hash)]
1021#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Align {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Align { pow2: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Align {
            fn decode(__decoder: &mut __D) -> Self {
                Align {
                    pow2: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Align {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Align { pow2: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1022pub struct Align {
1023    pow2: u8,
1024}
1025
1026// This is debug-printed a lot in larger structs, don't waste too much space there
1027impl fmt::Debug for Align {
1028    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1029        f.write_fmt(format_args!("Align({0} bytes)", self.bytes()))write!(f, "Align({} bytes)", self.bytes())
1030    }
1031}
1032
1033#[derive(#[automatically_derived]
impl ::core::clone::Clone for AlignFromBytesError {
    #[inline]
    fn clone(&self) -> AlignFromBytesError {
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AlignFromBytesError { }Copy)]
1034pub enum AlignFromBytesError {
1035    NotPowerOfTwo(u64),
1036    TooLarge(u64),
1037}
1038
1039impl fmt::Debug for AlignFromBytesError {
1040    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1041        fmt::Display::fmt(self, f)
1042    }
1043}
1044
1045impl fmt::Display for AlignFromBytesError {
1046    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1047        match self {
1048            AlignFromBytesError::NotPowerOfTwo(align) => f.write_fmt(format_args!("{0} is not a power of 2", align))write!(f, "{align} is not a power of 2"),
1049            AlignFromBytesError::TooLarge(align) => f.write_fmt(format_args!("{0} is too large", align))write!(f, "{align} is too large"),
1050        }
1051    }
1052}
1053
1054impl Align {
1055    pub const ONE: Align = Align { pow2: 0 };
1056    pub const EIGHT: Align = Align { pow2: 3 };
1057    // LLVM has a maximal supported alignment of 2^29, we inherit that.
1058    pub const MAX: Align = Align { pow2: 29 };
1059
1060    /// Either `1 << (pointer_bits - 1)` or [`Align::MAX`], whichever is smaller.
1061    #[inline]
1062    pub fn max_for_target(tdl: &TargetDataLayout) -> Align {
1063        let pointer_bits = tdl.pointer_size().bits();
1064        if let Ok(pointer_bits) = u8::try_from(pointer_bits)
1065            && pointer_bits <= Align::MAX.pow2
1066        {
1067            Align { pow2: pointer_bits - 1 }
1068        } else {
1069            Align::MAX
1070        }
1071    }
1072
1073    #[inline]
1074    pub fn from_bits(bits: u64) -> Result<Align, AlignFromBytesError> {
1075        Align::from_bytes(Size::from_bits(bits).bytes())
1076    }
1077
1078    #[inline]
1079    pub const fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
1080        // Treat an alignment of 0 bytes like 1-byte alignment.
1081        if align == 0 {
1082            return Ok(Align::ONE);
1083        }
1084
1085        #[cold]
1086        const fn not_power_of_2(align: u64) -> AlignFromBytesError {
1087            AlignFromBytesError::NotPowerOfTwo(align)
1088        }
1089
1090        #[cold]
1091        const fn too_large(align: u64) -> AlignFromBytesError {
1092            AlignFromBytesError::TooLarge(align)
1093        }
1094
1095        let tz = align.trailing_zeros();
1096        if align != (1 << tz) {
1097            return Err(not_power_of_2(align));
1098        }
1099
1100        let pow2 = tz as u8;
1101        if pow2 > Self::MAX.pow2 {
1102            return Err(too_large(align));
1103        }
1104
1105        Ok(Align { pow2 })
1106    }
1107
1108    #[inline]
1109    pub const fn bytes(self) -> u64 {
1110        1 << self.pow2
1111    }
1112
1113    #[inline]
1114    pub fn bytes_usize(self) -> usize {
1115        self.bytes().try_into().unwrap()
1116    }
1117
1118    #[inline]
1119    pub const fn bits(self) -> u64 {
1120        self.bytes() * 8
1121    }
1122
1123    #[inline]
1124    pub fn bits_usize(self) -> usize {
1125        self.bits().try_into().unwrap()
1126    }
1127
1128    /// Obtain the greatest factor of `size` that is an alignment
1129    /// (the largest power of two the Size is a multiple of).
1130    ///
1131    /// Note that all numbers are factors of 0
1132    #[inline]
1133    pub fn max_aligned_factor(size: Size) -> Align {
1134        Align { pow2: size.bytes().trailing_zeros() as u8 }
1135    }
1136
1137    /// Reduces Align to an aligned factor of `size`.
1138    #[inline]
1139    pub fn restrict_for_offset(self, size: Size) -> Align {
1140        self.min(Align::max_aligned_factor(size))
1141    }
1142}
1143
1144/// A pair of alignments, ABI-mandated and preferred.
1145///
1146/// The "preferred" alignment is an LLVM concept that is virtually meaningless to Rust code:
1147/// it is not exposed semantically to programmers nor can they meaningfully affect it.
1148/// The only concern for us is that preferred alignment must not be less than the mandated alignment
1149/// and thus in practice the two values are almost always identical.
1150///
1151/// An example of a rare thing actually affected by preferred alignment is aligning of statics.
1152/// It is of effectively no consequence for layout in structs and on the stack.
1153#[derive(#[automatically_derived]
impl ::core::marker::Copy for AbiAlign { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AbiAlign {
    #[inline]
    fn clone(&self) -> AbiAlign {
        let _: ::core::clone::AssertParamIsClone<Align>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AbiAlign {
    #[inline]
    fn eq(&self, other: &AbiAlign) -> bool { self.abi == other.abi }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AbiAlign {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Align>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for AbiAlign {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.abi, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AbiAlign {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "AbiAlign",
            "abi", &&self.abi)
    }
}Debug)]
1154#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for AbiAlign {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    AbiAlign { abi: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1155pub struct AbiAlign {
1156    pub abi: Align,
1157}
1158
1159impl AbiAlign {
1160    #[inline]
1161    pub fn new(align: Align) -> AbiAlign {
1162        AbiAlign { abi: align }
1163    }
1164
1165    #[inline]
1166    pub fn min(self, other: AbiAlign) -> AbiAlign {
1167        AbiAlign { abi: self.abi.min(other.abi) }
1168    }
1169
1170    #[inline]
1171    pub fn max(self, other: AbiAlign) -> AbiAlign {
1172        AbiAlign { abi: self.abi.max(other.abi) }
1173    }
1174}
1175
1176impl Deref for AbiAlign {
1177    type Target = Align;
1178
1179    fn deref(&self) -> &Self::Target {
1180        &self.abi
1181    }
1182}
1183
1184/// Integers, also used for enum discriminants.
1185#[derive(#[automatically_derived]
impl ::core::marker::Copy for Integer { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Integer {
    #[inline]
    fn clone(&self) -> Integer { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Integer {
    #[inline]
    fn eq(&self, other: &Integer) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Integer {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Integer {
    #[inline]
    fn partial_cmp(&self, other: &Integer)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Integer {
    #[inline]
    fn cmp(&self, other: &Integer) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Integer {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Integer {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Integer::I8 => "I8",
                Integer::I16 => "I16",
                Integer::I32 => "I32",
                Integer::I64 => "I64",
                Integer::I128 => "I128",
            })
    }
}Debug)]
1186#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Integer {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Integer::I8 => { 0usize }
                        Integer::I16 => { 1usize }
                        Integer::I32 => { 2usize }
                        Integer::I64 => { 3usize }
                        Integer::I128 => { 4usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Integer::I8 => {}
                    Integer::I16 => {}
                    Integer::I32 => {}
                    Integer::I64 => {}
                    Integer::I128 => {}
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Integer {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Integer::I8 }
                    1usize => { Integer::I16 }
                    2usize => { Integer::I32 }
                    3usize => { Integer::I64 }
                    4usize => { Integer::I128 }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Integer`, expected 0..5, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Integer {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Integer::I8 => {}
                    Integer::I16 => {}
                    Integer::I32 => {}
                    Integer::I64 => {}
                    Integer::I128 => {}
                }
            }
        }
    };StableHash))]
1187pub enum Integer {
1188    I8,
1189    I16,
1190    I32,
1191    I64,
1192    I128,
1193}
1194
1195impl Integer {
1196    pub fn int_ty_str(self) -> &'static str {
1197        use Integer::*;
1198        match self {
1199            I8 => "i8",
1200            I16 => "i16",
1201            I32 => "i32",
1202            I64 => "i64",
1203            I128 => "i128",
1204        }
1205    }
1206
1207    pub fn uint_ty_str(self) -> &'static str {
1208        use Integer::*;
1209        match self {
1210            I8 => "u8",
1211            I16 => "u16",
1212            I32 => "u32",
1213            I64 => "u64",
1214            I128 => "u128",
1215        }
1216    }
1217
1218    #[inline]
1219    pub fn size(self) -> Size {
1220        use Integer::*;
1221        match self {
1222            I8 => Size::from_bytes(1),
1223            I16 => Size::from_bytes(2),
1224            I32 => Size::from_bytes(4),
1225            I64 => Size::from_bytes(8),
1226            I128 => Size::from_bytes(16),
1227        }
1228    }
1229
1230    /// Gets the Integer type from an IntegerType.
1231    pub fn from_attr<C: HasDataLayout>(cx: &C, ity: IntegerType) -> Integer {
1232        let dl = cx.data_layout();
1233
1234        match ity {
1235            IntegerType::Pointer(_) => dl.ptr_sized_integer(),
1236            IntegerType::Fixed(x, _) => x,
1237        }
1238    }
1239
1240    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1241        use Integer::*;
1242        let dl = cx.data_layout();
1243
1244        AbiAlign::new(match self {
1245            I8 => dl.i8_align,
1246            I16 => dl.i16_align,
1247            I32 => dl.i32_align,
1248            I64 => dl.i64_align,
1249            I128 => dl.i128_align,
1250        })
1251    }
1252
1253    /// Returns the largest signed value that can be represented by this Integer.
1254    #[inline]
1255    pub fn signed_max(self) -> i128 {
1256        use Integer::*;
1257        match self {
1258            I8 => i8::MAX as i128,
1259            I16 => i16::MAX as i128,
1260            I32 => i32::MAX as i128,
1261            I64 => i64::MAX as i128,
1262            I128 => i128::MAX,
1263        }
1264    }
1265
1266    /// Returns the smallest signed value that can be represented by this Integer.
1267    #[inline]
1268    pub fn signed_min(self) -> i128 {
1269        use Integer::*;
1270        match self {
1271            I8 => i8::MIN as i128,
1272            I16 => i16::MIN as i128,
1273            I32 => i32::MIN as i128,
1274            I64 => i64::MIN as i128,
1275            I128 => i128::MIN,
1276        }
1277    }
1278
1279    /// Finds the smallest Integer type which can represent the signed value.
1280    #[inline]
1281    pub fn fit_signed(x: i128) -> Integer {
1282        use Integer::*;
1283        match x {
1284            -0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8,
1285            -0x0000_0000_0000_8000..=0x0000_0000_0000_7fff => I16,
1286            -0x0000_0000_8000_0000..=0x0000_0000_7fff_ffff => I32,
1287            -0x8000_0000_0000_0000..=0x7fff_ffff_ffff_ffff => I64,
1288            _ => I128,
1289        }
1290    }
1291
1292    /// Finds the smallest Integer type which can represent the unsigned value.
1293    #[inline]
1294    pub fn fit_unsigned(x: u128) -> Integer {
1295        use Integer::*;
1296        match x {
1297            0..=0x0000_0000_0000_00ff => I8,
1298            0..=0x0000_0000_0000_ffff => I16,
1299            0..=0x0000_0000_ffff_ffff => I32,
1300            0..=0xffff_ffff_ffff_ffff => I64,
1301            _ => I128,
1302        }
1303    }
1304
1305    /// Finds the smallest integer with the given alignment.
1306    pub fn for_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Option<Integer> {
1307        use Integer::*;
1308        let dl = cx.data_layout();
1309
1310        [I8, I16, I32, I64, I128].into_iter().find(|&candidate| {
1311            wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes()
1312        })
1313    }
1314
1315    /// Find the largest integer with the given alignment or less.
1316    pub fn approximate_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Integer {
1317        use Integer::*;
1318        let dl = cx.data_layout();
1319
1320        // FIXME(eddyb) maybe include I128 in the future, when it works everywhere.
1321        for candidate in [I64, I32, I16] {
1322            if wanted >= candidate.align(dl).abi && wanted.bytes() >= candidate.size().bytes() {
1323                return candidate;
1324            }
1325        }
1326        I8
1327    }
1328
1329    // FIXME(eddyb) consolidate this and other methods that find the appropriate
1330    // `Integer` given some requirements.
1331    #[inline]
1332    pub fn from_size(size: Size) -> Result<Self, String> {
1333        match size.bits() {
1334            8 => Ok(Integer::I8),
1335            16 => Ok(Integer::I16),
1336            32 => Ok(Integer::I32),
1337            64 => Ok(Integer::I64),
1338            128 => Ok(Integer::I128),
1339            _ => Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("rust does not support integers with {0} bits",
                size.bits()))
    })format!("rust does not support integers with {} bits", size.bits())),
1340        }
1341    }
1342}
1343
1344/// Floating-point types.
1345#[derive(#[automatically_derived]
impl ::core::marker::Copy for Float { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Float {
    #[inline]
    fn clone(&self) -> Float { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Float {
    #[inline]
    fn eq(&self, other: &Float) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Float {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Float {
    #[inline]
    fn partial_cmp(&self, other: &Float)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Float {
    #[inline]
    fn cmp(&self, other: &Float) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Float {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Float {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Float::F16 => "F16",
                Float::F32 => "F32",
                Float::F64 => "F64",
                Float::F128 => "F128",
            })
    }
}Debug)]
1346#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Float {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Float::F16 => {}
                    Float::F32 => {}
                    Float::F64 => {}
                    Float::F128 => {}
                }
            }
        }
    };StableHash))]
1347pub enum Float {
1348    F16,
1349    F32,
1350    F64,
1351    F128,
1352}
1353
1354impl Float {
1355    pub fn size(self) -> Size {
1356        use Float::*;
1357
1358        match self {
1359            F16 => Size::from_bits(16),
1360            F32 => Size::from_bits(32),
1361            F64 => Size::from_bits(64),
1362            F128 => Size::from_bits(128),
1363        }
1364    }
1365
1366    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1367        use Float::*;
1368        let dl = cx.data_layout();
1369
1370        AbiAlign::new(match self {
1371            F16 => dl.f16_align,
1372            F32 => dl.f32_align,
1373            F64 => dl.f64_align,
1374            F128 => dl.f128_align,
1375        })
1376    }
1377}
1378
1379/// Fundamental unit of memory access and layout.
1380#[derive(#[automatically_derived]
impl ::core::marker::Copy for Primitive { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Primitive {
    #[inline]
    fn clone(&self) -> Primitive {
        let _: ::core::clone::AssertParamIsClone<Integer>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<Float>;
        let _: ::core::clone::AssertParamIsClone<AddressSpace>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Primitive {
    #[inline]
    fn eq(&self, other: &Primitive) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Primitive::Int(__self_0, __self_1),
                    Primitive::Int(__arg1_0, __arg1_1)) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0,
                (Primitive::Float(__self_0), Primitive::Float(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Primitive::Pointer(__self_0), Primitive::Pointer(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Primitive {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Integer>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Float>;
        let _: ::core::cmp::AssertParamIsEq<AddressSpace>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Primitive {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Primitive::Int(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            Primitive::Float(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            Primitive::Pointer(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Primitive {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Primitive::Int(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Int",
                    __self_0, &__self_1),
            Primitive::Float(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Float",
                    &__self_0),
            Primitive::Pointer(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Pointer", &__self_0),
        }
    }
}Debug)]
1381#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Primitive {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Primitive::Int(ref __binding_0, ref __binding_1) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    Primitive::Float(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    Primitive::Pointer(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1382pub enum Primitive {
1383    /// The `bool` is the signedness of the `Integer` type.
1384    ///
1385    /// One would think we would not care about such details this low down,
1386    /// but some ABIs are described in terms of C types and ISAs where the
1387    /// integer arithmetic is done on {sign,zero}-extended registers, e.g.
1388    /// a negative integer passed by zero-extension will appear positive in
1389    /// the callee, and most operations on it will produce the wrong values.
1390    Int(Integer, bool),
1391    Float(Float),
1392    Pointer(AddressSpace),
1393}
1394
1395impl Primitive {
1396    pub fn size<C: HasDataLayout>(self, cx: &C) -> Size {
1397        use Primitive::*;
1398        let dl = cx.data_layout();
1399
1400        match self {
1401            Int(i, _) => i.size(),
1402            Float(f) => f.size(),
1403            Pointer(a) => dl.pointer_size_in(a),
1404        }
1405    }
1406
1407    pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1408        use Primitive::*;
1409        let dl = cx.data_layout();
1410
1411        match self {
1412            Int(i, _) => i.align(dl),
1413            Float(f) => f.align(dl),
1414            Pointer(a) => dl.pointer_align_in(a),
1415        }
1416    }
1417}
1418
1419/// Inclusive wrap-around range of valid values, that is, if
1420/// start > end, it represents `start..=MAX`, followed by `0..=end`.
1421///
1422/// That is, for an i8 primitive, a range of `254..=2` means following
1423/// sequence:
1424///
1425///    254 (-2), 255 (-1), 0, 1, 2
1426///
1427/// This is intended specifically to mirror LLVM’s `!range` metadata semantics.
1428#[derive(#[automatically_derived]
impl ::core::clone::Clone for WrappingRange {
    #[inline]
    fn clone(&self) -> WrappingRange {
        let _: ::core::clone::AssertParamIsClone<u128>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for WrappingRange { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for WrappingRange {
    #[inline]
    fn eq(&self, other: &WrappingRange) -> bool {
        self.start == other.start && self.end == other.end
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for WrappingRange {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u128>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for WrappingRange {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.start, state);
        ::core::hash::Hash::hash(&self.end, state)
    }
}Hash)]
1429#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            WrappingRange {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    WrappingRange { start: ref __binding_0, end: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1430pub struct WrappingRange {
1431    pub start: u128,
1432    pub end: u128,
1433}
1434
1435impl WrappingRange {
1436    pub fn full(size: Size) -> Self {
1437        Self { start: 0, end: size.unsigned_int_max() }
1438    }
1439
1440    /// Returns `true` if `v` is contained in the range.
1441    #[inline(always)]
1442    pub fn contains(&self, v: u128) -> bool {
1443        if self.start <= self.end {
1444            self.start <= v && v <= self.end
1445        } else {
1446            self.start <= v || v <= self.end
1447        }
1448    }
1449
1450    /// Returns `true` if all the values in `other` are contained in this range,
1451    /// when the values are considered as having width `size`.
1452    #[inline(always)]
1453    pub fn contains_range(&self, other: Self, size: Size) -> bool {
1454        if self.is_full_for(size) {
1455            true
1456        } else {
1457            let trunc = |x| size.truncate(x);
1458
1459            let delta = self.start;
1460            let max = trunc(self.end.wrapping_sub(delta));
1461
1462            let other_start = trunc(other.start.wrapping_sub(delta));
1463            let other_end = trunc(other.end.wrapping_sub(delta));
1464
1465            // Having shifted both input ranges by `delta`, now we only need to check
1466            // whether `0..=max` contains `other_start..=other_end`, which can only
1467            // happen if the other doesn't wrap since `self` isn't everything.
1468            (other_start <= other_end) && (other_end <= max)
1469        }
1470    }
1471
1472    /// Returns `self` with replaced `start`
1473    #[inline(always)]
1474    fn with_start(mut self, start: u128) -> Self {
1475        self.start = start;
1476        self
1477    }
1478
1479    /// Returns `self` with replaced `end`
1480    #[inline(always)]
1481    fn with_end(mut self, end: u128) -> Self {
1482        self.end = end;
1483        self
1484    }
1485
1486    /// Returns `true` if `size` completely fills the range.
1487    ///
1488    /// Note that this is *not* the same as `self == WrappingRange::full(size)`.
1489    /// Niche calculations can produce full ranges which are not the canonical one;
1490    /// for example `Option<NonZero<u16>>` gets `valid_range: (..=0) | (1..)`.
1491    #[inline]
1492    fn is_full_for(&self, size: Size) -> bool {
1493        let max_value = size.unsigned_int_max();
1494        if true {
    if !(self.start <= max_value && self.end <= max_value) {
        ::core::panicking::panic("assertion failed: self.start <= max_value && self.end <= max_value")
    };
};debug_assert!(self.start <= max_value && self.end <= max_value);
1495        self.start == (self.end.wrapping_add(1) & max_value)
1496    }
1497
1498    /// Checks whether this range is considered non-wrapping when the values are
1499    /// interpreted as *unsigned* numbers of width `size`.
1500    ///
1501    /// Returns `Ok(true)` if there's no wrap-around, `Ok(false)` if there is,
1502    /// and `Err(..)` if the range is full so it depends how you think about it.
1503    #[inline]
1504    pub fn no_unsigned_wraparound(&self, size: Size) -> Result<bool, RangeFull> {
1505        if self.is_full_for(size) { Err(..) } else { Ok(self.start <= self.end) }
1506    }
1507
1508    /// Checks whether this range is considered non-wrapping when the values are
1509    /// interpreted as *signed* numbers of width `size`.
1510    ///
1511    /// This is heavily dependent on the `size`, as `100..=200` does wrap when
1512    /// interpreted as `i8`, but doesn't when interpreted as `i16`.
1513    ///
1514    /// Returns `Ok(true)` if there's no wrap-around, `Ok(false)` if there is,
1515    /// and `Err(..)` if the range is full so it depends how you think about it.
1516    #[inline]
1517    pub fn no_signed_wraparound(&self, size: Size) -> Result<bool, RangeFull> {
1518        if self.is_full_for(size) {
1519            Err(..)
1520        } else {
1521            let start: i128 = size.sign_extend(self.start);
1522            let end: i128 = size.sign_extend(self.end);
1523            Ok(start <= end)
1524        }
1525    }
1526}
1527
1528impl fmt::Debug for WrappingRange {
1529    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1530        if self.start > self.end {
1531            fmt.write_fmt(format_args!("(..={0}) | ({1}..)", self.end, self.start))write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
1532        } else {
1533            fmt.write_fmt(format_args!("{0}..={1}", self.start, self.end))write!(fmt, "{}..={}", self.start, self.end)?;
1534        }
1535        Ok(())
1536    }
1537}
1538
1539/// Information about one scalar component of a Rust type.
1540#[derive(#[automatically_derived]
impl ::core::clone::Clone for Scalar {
    #[inline]
    fn clone(&self) -> Scalar {
        let _: ::core::clone::AssertParamIsClone<Primitive>;
        let _: ::core::clone::AssertParamIsClone<WrappingRange>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Scalar { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Scalar {
    #[inline]
    fn eq(&self, other: &Scalar) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Scalar::Initialized { value: __self_0, valid_range: __self_1
                    }, Scalar::Initialized {
                    value: __arg1_0, valid_range: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (Scalar::Union { value: __self_0 }, Scalar::Union {
                    value: __arg1_0 }) => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Scalar {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Primitive>;
        let _: ::core::cmp::AssertParamIsEq<WrappingRange>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Scalar {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Scalar::Initialized { value: __self_0, valid_range: __self_1 } =>
                {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            Scalar::Union { value: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Scalar {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Scalar::Initialized { value: __self_0, valid_range: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Initialized", "value", __self_0, "valid_range", &__self_1),
            Scalar::Union { value: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Union",
                    "value", &__self_0),
        }
    }
}Debug)]
1541#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Scalar {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Scalar::Initialized {
                        value: ref __binding_0, valid_range: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    Scalar::Union { value: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1542pub enum Scalar {
1543    Initialized {
1544        value: Primitive,
1545
1546        // FIXME(eddyb) always use the shortest range, e.g., by finding
1547        // the largest space between two consecutive valid values and
1548        // taking everything else as the (shortest) valid range.
1549        valid_range: WrappingRange,
1550    },
1551    Union {
1552        /// Even for unions, we need to use the correct registers for the kind of
1553        /// values inside the union, so we keep the `Primitive` type around. We
1554        /// also use it to compute the size of the scalar.
1555        /// However, unions never have niches and even allow undef,
1556        /// so there is no `valid_range`.
1557        value: Primitive,
1558    },
1559}
1560
1561impl Scalar {
1562    #[inline]
1563    pub fn is_bool(&self) -> bool {
1564        use Integer::*;
1565        #[allow(non_exhaustive_omitted_patterns)] match self {
    Scalar::Initialized {
        value: Primitive::Int(I8, false),
        valid_range: WrappingRange { start: 0, end: 1 } } => true,
    _ => false,
}matches!(
1566            self,
1567            Scalar::Initialized {
1568                value: Primitive::Int(I8, false),
1569                valid_range: WrappingRange { start: 0, end: 1 }
1570            }
1571        )
1572    }
1573
1574    /// Get the primitive representation of this type, ignoring the valid range and whether the
1575    /// value is allowed to be undefined (due to being a union).
1576    pub fn primitive(&self) -> Primitive {
1577        match *self {
1578            Scalar::Initialized { value, .. } | Scalar::Union { value } => value,
1579        }
1580    }
1581
1582    pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign {
1583        self.primitive().align(cx)
1584    }
1585
1586    pub fn size(self, cx: &impl HasDataLayout) -> Size {
1587        self.primitive().size(cx)
1588    }
1589
1590    #[inline]
1591    pub fn to_union(&self) -> Self {
1592        Self::Union { value: self.primitive() }
1593    }
1594
1595    #[inline]
1596    pub fn valid_range(&self, cx: &impl HasDataLayout) -> WrappingRange {
1597        match *self {
1598            Scalar::Initialized { valid_range, .. } => valid_range,
1599            Scalar::Union { value } => WrappingRange::full(value.size(cx)),
1600        }
1601    }
1602
1603    #[inline]
1604    /// Allows the caller to mutate the valid range. This operation will panic if attempted on a
1605    /// union.
1606    pub fn valid_range_mut(&mut self) -> &mut WrappingRange {
1607        match self {
1608            Scalar::Initialized { valid_range, .. } => valid_range,
1609            Scalar::Union { .. } => {
    ::core::panicking::panic_fmt(format_args!("cannot change the valid range of a union"));
}panic!("cannot change the valid range of a union"),
1610        }
1611    }
1612
1613    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole
1614    /// layout.
1615    #[inline]
1616    pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
1617        match *self {
1618            Scalar::Initialized { valid_range, .. } => valid_range.is_full_for(self.size(cx)),
1619            Scalar::Union { .. } => true,
1620        }
1621    }
1622
1623    /// Returns `true` if this type can be left uninit.
1624    #[inline]
1625    pub fn is_uninit_valid(&self) -> bool {
1626        match *self {
1627            Scalar::Initialized { .. } => false,
1628            Scalar::Union { .. } => true,
1629        }
1630    }
1631
1632    /// Returns `true` if this is a signed integer scalar
1633    #[inline]
1634    pub fn is_signed(&self) -> bool {
1635        match self.primitive() {
1636            Primitive::Int(_, signed) => signed,
1637            _ => false,
1638        }
1639    }
1640}
1641
1642// NOTE: This struct is generic over the FieldIdx for rust-analyzer usage.
1643/// Describes how the fields of a type are located in memory.
1644#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
    FieldsShape<FieldIdx> {
    #[inline]
    fn eq(&self, other: &FieldsShape<FieldIdx>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (FieldsShape::Union(__self_0), FieldsShape::Union(__arg1_0))
                    => __self_0 == __arg1_0,
                (FieldsShape::Array { stride: __self_0, count: __self_1 },
                    FieldsShape::Array { stride: __arg1_0, count: __arg1_1 }) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0,
                (FieldsShape::Arbitrary {
                    offsets: __self_0, in_memory_order: __self_1 },
                    FieldsShape::Arbitrary {
                    offsets: __arg1_0, in_memory_order: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx> ::core::cmp::Eq for
    FieldsShape<FieldIdx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<NonZeroUsize>;
        let _: ::core::cmp::AssertParamIsEq<Size>;
        let _: ::core::cmp::AssertParamIsEq<u64>;
        let _: ::core::cmp::AssertParamIsEq<IndexVec<FieldIdx, Size>>;
        let _: ::core::cmp::AssertParamIsEq<IndexVec<u32, FieldIdx>>;
    }
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx> ::core::hash::Hash for
    FieldsShape<FieldIdx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            FieldsShape::Union(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            FieldsShape::Array { stride: __self_0, count: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            FieldsShape::Arbitrary {
                offsets: __self_0, in_memory_order: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx> ::core::clone::Clone for
    FieldsShape<FieldIdx> {
    #[inline]
    fn clone(&self) -> FieldsShape<FieldIdx> {
        match self {
            FieldsShape::Primitive => FieldsShape::Primitive,
            FieldsShape::Union(__self_0) =>
                FieldsShape::Union(::core::clone::Clone::clone(__self_0)),
            FieldsShape::Array { stride: __self_0, count: __self_1 } =>
                FieldsShape::Array {
                    stride: ::core::clone::Clone::clone(__self_0),
                    count: ::core::clone::Clone::clone(__self_1),
                },
            FieldsShape::Arbitrary {
                offsets: __self_0, in_memory_order: __self_1 } =>
                FieldsShape::Arbitrary {
                    offsets: ::core::clone::Clone::clone(__self_0),
                    in_memory_order: ::core::clone::Clone::clone(__self_1),
                },
        }
    }
}Clone, #[automatically_derived]
impl<FieldIdx: ::core::fmt::Debug + Idx> ::core::fmt::Debug for
    FieldsShape<FieldIdx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            FieldsShape::Primitive =>
                ::core::fmt::Formatter::write_str(f, "Primitive"),
            FieldsShape::Union(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Union",
                    &__self_0),
            FieldsShape::Array { stride: __self_0, count: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Array",
                    "stride", __self_0, "count", &__self_1),
            FieldsShape::Arbitrary {
                offsets: __self_0, in_memory_order: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Arbitrary", "offsets", __self_0, "in_memory_order",
                    &__self_1),
        }
    }
}Debug)]
1645#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<FieldIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
            for FieldsShape<FieldIdx> where
            FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    FieldsShape::Primitive => {}
                    FieldsShape::Union(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    FieldsShape::Array {
                        stride: ref __binding_0, count: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    FieldsShape::Arbitrary {
                        offsets: ref __binding_0, in_memory_order: ref __binding_1 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1646pub enum FieldsShape<FieldIdx: Idx> {
1647    /// Scalar primitives and `!`, which never have fields.
1648    Primitive,
1649
1650    /// All fields start at no offset. The `usize` is the field count.
1651    Union(NonZeroUsize),
1652
1653    /// Array/vector-like placement, with all fields of identical types.
1654    Array { stride: Size, count: u64 },
1655
1656    /// Struct-like placement, with precomputed offsets.
1657    ///
1658    /// Fields are guaranteed to not overlap, but note that gaps
1659    /// before, between and after all the fields are NOT always
1660    /// padding, and as such their contents may not be discarded.
1661    /// For example, enum variants leave a gap at the start,
1662    /// where the discriminant field in the enum layout goes.
1663    Arbitrary {
1664        /// Offsets for the first byte of each field,
1665        /// ordered to match the source definition order.
1666        /// This vector does not go in increasing order.
1667        // FIXME(eddyb) use small vector optimization for the common case.
1668        offsets: IndexVec<FieldIdx, Size>,
1669
1670        /// Maps memory order field indices to source order indices,
1671        /// depending on how the fields were reordered (if at all).
1672        /// This is a permutation, with both the source order and the
1673        /// memory order using the same (0..n) index ranges.
1674        ///
1675        // FIXME(eddyb) build a better abstraction for permutations, if possible.
1676        // FIXME(camlorn) also consider small vector optimization here.
1677        in_memory_order: IndexVec<u32, FieldIdx>,
1678    },
1679}
1680
1681impl<FieldIdx: Idx> FieldsShape<FieldIdx> {
1682    #[inline]
1683    pub fn count(&self) -> usize {
1684        match *self {
1685            FieldsShape::Primitive => 0,
1686            FieldsShape::Union(count) => count.get(),
1687            FieldsShape::Array { count, .. } => count.try_into().unwrap(),
1688            FieldsShape::Arbitrary { ref offsets, .. } => offsets.len(),
1689        }
1690    }
1691
1692    #[inline]
1693    pub fn offset(&self, i: usize) -> Size {
1694        match *self {
1695            FieldsShape::Primitive => {
1696                {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("FieldsShape::offset: `Primitive`s have no fields")));
}unreachable!("FieldsShape::offset: `Primitive`s have no fields")
1697            }
1698            FieldsShape::Union(count) => {
1699                if !(i < count.get()) {
    {
        ::core::panicking::panic_fmt(format_args!("tried to access field {0} of union with {1} fields",
                i, count));
    }
};assert!(i < count.get(), "tried to access field {i} of union with {count} fields");
1700                Size::ZERO
1701            }
1702            FieldsShape::Array { stride, count } => {
1703                let i = u64::try_from(i).unwrap();
1704                if !(i < count) {
    {
        ::core::panicking::panic_fmt(format_args!("tried to access field {0} of array with {1} fields",
                i, count));
    }
};assert!(i < count, "tried to access field {i} of array with {count} fields");
1705                stride * i
1706            }
1707            FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::new(i)],
1708        }
1709    }
1710
1711    /// Gets source indices of the fields by increasing offsets.
1712    #[inline]
1713    pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator<Item = usize> {
1714        // Primitives don't really have fields in the way that structs do,
1715        // but having this return an empty iterator for them is unhelpful
1716        // since that makes them look kinda like ZSTs, which they're not.
1717        let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() };
1718
1719        (0..pseudofield_count).map(move |i| match self {
1720            FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
1721            FieldsShape::Arbitrary { in_memory_order, .. } => in_memory_order[i as u32].index(),
1722        })
1723    }
1724}
1725
1726/// An identifier that specifies the address space that some operation
1727/// should operate on. Special address spaces have an effect on code generation,
1728/// depending on the target and the address spaces it implements.
1729#[derive(#[automatically_derived]
impl ::core::marker::Copy for AddressSpace { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AddressSpace {
    #[inline]
    fn clone(&self) -> AddressSpace {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AddressSpace {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "AddressSpace",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for AddressSpace {
    #[inline]
    fn eq(&self, other: &AddressSpace) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AddressSpace {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for AddressSpace {
    #[inline]
    fn partial_cmp(&self, other: &AddressSpace)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for AddressSpace {
    #[inline]
    fn cmp(&self, other: &AddressSpace) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for AddressSpace {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash)]
1730#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for AddressSpace
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    AddressSpace(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1731pub struct AddressSpace(pub u32);
1732
1733impl AddressSpace {
1734    /// LLVM's `0` address space.
1735    pub const ZERO: Self = AddressSpace(0);
1736    /// The address space for workgroup memory on nvptx and amdgpu.
1737    /// See e.g. the `gpu_launch_sized_workgroup_mem` intrinsic for details.
1738    pub const GPU_WORKGROUP: Self = AddressSpace(3);
1739}
1740
1741/// How many scalable vectors are in a `BackendRepr::ScalableVector`?
1742#[derive(#[automatically_derived]
impl ::core::clone::Clone for NumScalableVectors {
    #[inline]
    fn clone(&self) -> NumScalableVectors {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NumScalableVectors { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for NumScalableVectors {
    #[inline]
    fn eq(&self, other: &NumScalableVectors) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NumScalableVectors {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for NumScalableVectors {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for NumScalableVectors {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "NumScalableVectors", &&self.0)
    }
}Debug)]
1743#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            NumScalableVectors {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    NumScalableVectors(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1744pub struct NumScalableVectors(pub u8);
1745
1746impl NumScalableVectors {
1747    /// Returns a `NumScalableVector` for a non-tuple scalable vector (e.g. a single vector).
1748    pub fn for_non_tuple() -> Self {
1749        NumScalableVectors(1)
1750    }
1751
1752    // Returns `NumScalableVectors` for values of two through eight, which are a valid number of
1753    // fields for a tuple of scalable vectors to have. `1` is a valid value of `NumScalableVectors`
1754    // but not for a tuple which would have a field count.
1755    pub fn from_field_count(count: usize) -> Option<Self> {
1756        match count {
1757            2..8 => Some(NumScalableVectors(count as u8)),
1758            _ => None,
1759        }
1760    }
1761}
1762
1763#[cfg(feature = "nightly")]
1764impl IntoDiagArg for NumScalableVectors {
1765    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1766        DiagArgValue::Str(std::borrow::Cow::Borrowed(match self.0 {
1767            0 => {
    ::core::panicking::panic_fmt(format_args!("`NumScalableVectors(0)` is illformed"));
}panic!("`NumScalableVectors(0)` is illformed"),
1768            1 => "one",
1769            2 => "two",
1770            3 => "three",
1771            4 => "four",
1772            5 => "five",
1773            6 => "six",
1774            7 => "seven",
1775            8 => "eight",
1776            _ => {
    ::core::panicking::panic_fmt(format_args!("`NumScalableVectors(N)` for N>8 is illformed"));
}panic!("`NumScalableVectors(N)` for N>8 is illformed"),
1777        }))
1778    }
1779}
1780
1781/// The way we represent values to the backend
1782///
1783/// Previously this was conflated with the "ABI" a type is given, as in the platform-specific ABI.
1784/// In reality, this implies little about that, but is mostly used to describe the syntactic form
1785/// emitted for the backend, as most backends handle SSA values and blobs of memory differently.
1786/// The psABI may need consideration in doing so, but this enum does not constitute a promise for
1787/// how the value will be lowered to the calling convention, in itself.
1788///
1789/// Generally, a codegen backend will prefer to handle smaller values as a scalar or short vector,
1790/// and larger values will usually prefer to be represented as memory.
1791#[derive(#[automatically_derived]
impl ::core::clone::Clone for BackendRepr {
    #[inline]
    fn clone(&self) -> BackendRepr {
        let _: ::core::clone::AssertParamIsClone<Scalar>;
        let _: ::core::clone::AssertParamIsClone<u64>;
        let _: ::core::clone::AssertParamIsClone<NumScalableVectors>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BackendRepr { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for BackendRepr {
    #[inline]
    fn eq(&self, other: &BackendRepr) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (BackendRepr::Scalar(__self_0), BackendRepr::Scalar(__arg1_0))
                    => __self_0 == __arg1_0,
                (BackendRepr::ScalarPair(__self_0, __self_1),
                    BackendRepr::ScalarPair(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (BackendRepr::SimdScalableVector {
                    element: __self_0,
                    count: __self_1,
                    number_of_vectors: __self_2 },
                    BackendRepr::SimdScalableVector {
                    element: __arg1_0,
                    count: __arg1_1,
                    number_of_vectors: __arg1_2 }) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0 &&
                        __self_2 == __arg1_2,
                (BackendRepr::SimdVector { element: __self_0, count: __self_1
                    }, BackendRepr::SimdVector {
                    element: __arg1_0, count: __arg1_1 }) =>
                    __self_1 == __arg1_1 && __self_0 == __arg1_0,
                (BackendRepr::Memory { sized: __self_0 },
                    BackendRepr::Memory { sized: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BackendRepr {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Scalar>;
        let _: ::core::cmp::AssertParamIsEq<u64>;
        let _: ::core::cmp::AssertParamIsEq<NumScalableVectors>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for BackendRepr {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            BackendRepr::Scalar(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            BackendRepr::ScalarPair(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            BackendRepr::SimdScalableVector {
                element: __self_0,
                count: __self_1,
                number_of_vectors: __self_2 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state)
            }
            BackendRepr::SimdVector { element: __self_0, count: __self_1 } =>
                {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            BackendRepr::Memory { sized: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for BackendRepr {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BackendRepr::Scalar(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Scalar",
                    &__self_0),
            BackendRepr::ScalarPair(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "ScalarPair", __self_0, &__self_1),
            BackendRepr::SimdScalableVector {
                element: __self_0,
                count: __self_1,
                number_of_vectors: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "SimdScalableVector", "element", __self_0, "count",
                    __self_1, "number_of_vectors", &__self_2),
            BackendRepr::SimdVector { element: __self_0, count: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "SimdVector", "element", __self_0, "count", &__self_1),
            BackendRepr::Memory { sized: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Memory", "sized", &__self_0),
        }
    }
}Debug)]
1792#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for BackendRepr
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    BackendRepr::Scalar(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    BackendRepr::ScalarPair(ref __binding_0, ref __binding_1) =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    BackendRepr::SimdScalableVector {
                        element: ref __binding_0,
                        count: ref __binding_1,
                        number_of_vectors: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    BackendRepr::SimdVector {
                        element: ref __binding_0, count: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    BackendRepr::Memory { sized: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1793pub enum BackendRepr {
1794    Scalar(Scalar),
1795    ScalarPair(Scalar, Scalar),
1796    SimdScalableVector {
1797        element: Scalar,
1798        count: u64,
1799        number_of_vectors: NumScalableVectors,
1800    },
1801    SimdVector {
1802        element: Scalar,
1803        count: u64,
1804    },
1805    // FIXME: I sometimes use memory, sometimes use an IR aggregate!
1806    Memory {
1807        /// If true, the size is exact, otherwise it's only a lower bound.
1808        sized: bool,
1809    },
1810}
1811
1812impl BackendRepr {
1813    /// Returns `true` if the layout corresponds to an unsized type.
1814    #[inline]
1815    pub fn is_unsized(&self) -> bool {
1816        match *self {
1817            BackendRepr::Scalar(_)
1818            | BackendRepr::ScalarPair(..)
1819            // FIXME(rustc_scalable_vector): Scalable vectors are `Sized` while the
1820            // `sized_hierarchy` feature is not yet fully implemented. After `sized_hierarchy` is
1821            // fully implemented, scalable vectors will remain `Sized`, they just won't be
1822            // `const Sized` - whether `is_unsized` continues to return `false` at that point will
1823            // need to be revisited and will depend on what `is_unsized` is used for.
1824            | BackendRepr::SimdScalableVector { .. }
1825            | BackendRepr::SimdVector { .. } => false,
1826            BackendRepr::Memory { sized } => !sized,
1827        }
1828    }
1829
1830    #[inline]
1831    pub fn is_sized(&self) -> bool {
1832        !self.is_unsized()
1833    }
1834
1835    /// Returns `true` if this is a single signed integer scalar.
1836    /// Sanity check: panics if this is not a scalar type (see PR #70189).
1837    #[inline]
1838    pub fn is_signed(&self) -> bool {
1839        match self {
1840            BackendRepr::Scalar(scal) => scal.is_signed(),
1841            _ => {
    ::core::panicking::panic_fmt(format_args!("`is_signed` on non-scalar ABI {0:?}",
            self));
}panic!("`is_signed` on non-scalar ABI {self:?}"),
1842        }
1843    }
1844
1845    /// Returns `true` if this is a scalar type
1846    #[inline]
1847    pub fn is_scalar(&self) -> bool {
1848        #[allow(non_exhaustive_omitted_patterns)] match *self {
    BackendRepr::Scalar(_) => true,
    _ => false,
}matches!(*self, BackendRepr::Scalar(_))
1849    }
1850
1851    /// Returns `true` if this is a bool
1852    #[inline]
1853    pub fn is_bool(&self) -> bool {
1854        #[allow(non_exhaustive_omitted_patterns)] match *self {
    BackendRepr::Scalar(s) if s.is_bool() => true,
    _ => false,
}matches!(*self, BackendRepr::Scalar(s) if s.is_bool())
1855    }
1856
1857    /// The psABI alignment for a `Scalar` or `ScalarPair`
1858    ///
1859    /// `None` for other variants.
1860    pub fn scalar_align<C: HasDataLayout>(&self, cx: &C) -> Option<Align> {
1861        match *self {
1862            BackendRepr::Scalar(s) => Some(s.align(cx).abi),
1863            BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi),
1864            // The align of a Vector can vary in surprising ways
1865            BackendRepr::SimdVector { .. }
1866            | BackendRepr::Memory { .. }
1867            | BackendRepr::SimdScalableVector { .. } => None,
1868        }
1869    }
1870
1871    /// The psABI size for a `Scalar` or `ScalarPair`
1872    ///
1873    /// `None` for other variants
1874    pub fn scalar_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
1875        match *self {
1876            // No padding in scalars.
1877            BackendRepr::Scalar(s) => Some(s.size(cx)),
1878            // May have some padding between the pair.
1879            BackendRepr::ScalarPair(s1, s2) => {
1880                let field2_offset = s1.size(cx).align_to(s2.align(cx).abi);
1881                let size = (field2_offset + s2.size(cx)).align_to(
1882                    self.scalar_align(cx)
1883                        // We absolutely must have an answer here or everything is FUBAR.
1884                        .unwrap(),
1885                );
1886                Some(size)
1887            }
1888            // The size of a Vector can vary in surprising ways
1889            BackendRepr::SimdVector { .. }
1890            | BackendRepr::Memory { .. }
1891            | BackendRepr::SimdScalableVector { .. } => None,
1892        }
1893    }
1894
1895    /// Discard validity range information and allow undef.
1896    pub fn to_union(&self) -> Self {
1897        match *self {
1898            BackendRepr::Scalar(s) => BackendRepr::Scalar(s.to_union()),
1899            BackendRepr::ScalarPair(s1, s2) => {
1900                BackendRepr::ScalarPair(s1.to_union(), s2.to_union())
1901            }
1902            BackendRepr::SimdVector { element, count } => {
1903                BackendRepr::SimdVector { element: element.to_union(), count }
1904            }
1905            BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true },
1906            BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
1907                BackendRepr::SimdScalableVector {
1908                    element: element.to_union(),
1909                    count,
1910                    number_of_vectors,
1911                }
1912            }
1913        }
1914    }
1915
1916    pub fn eq_up_to_validity(&self, other: &Self) -> bool {
1917        match (self, other) {
1918            // Scalar, Vector, ScalarPair have `Scalar` in them where we ignore validity ranges.
1919            // We do *not* ignore the sign since it matters for some ABIs (e.g. s390x).
1920            (BackendRepr::Scalar(l), BackendRepr::Scalar(r)) => l.primitive() == r.primitive(),
1921            (
1922                BackendRepr::SimdVector { element: element_l, count: count_l },
1923                BackendRepr::SimdVector { element: element_r, count: count_r },
1924            ) => element_l.primitive() == element_r.primitive() && count_l == count_r,
1925            (BackendRepr::ScalarPair(l1, l2), BackendRepr::ScalarPair(r1, r2)) => {
1926                l1.primitive() == r1.primitive() && l2.primitive() == r2.primitive()
1927            }
1928            // Everything else must be strictly identical.
1929            _ => self == other,
1930        }
1931    }
1932}
1933
1934// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage.
1935#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx,
    VariantIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
    Variants<FieldIdx, VariantIdx> {
    #[inline]
    fn eq(&self, other: &Variants<FieldIdx, VariantIdx>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Variants::Single { index: __self_0 }, Variants::Single {
                    index: __arg1_0 }) => __self_0 == __arg1_0,
                (Variants::Multiple {
                    tag: __self_0,
                    tag_encoding: __self_1,
                    tag_field: __self_2,
                    variants: __self_3 }, Variants::Multiple {
                    tag: __arg1_0,
                    tag_encoding: __arg1_1,
                    tag_field: __arg1_2,
                    variants: __arg1_3 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                            __self_2 == __arg1_2 && __self_3 == __arg1_3,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx, VariantIdx: ::core::cmp::Eq + Idx>
    ::core::cmp::Eq for Variants<FieldIdx, VariantIdx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
        let _: ::core::cmp::AssertParamIsEq<Scalar>;
        let _: ::core::cmp::AssertParamIsEq<TagEncoding<VariantIdx>>;
        let _: ::core::cmp::AssertParamIsEq<FieldIdx>;
        let _:
                ::core::cmp::AssertParamIsEq<IndexVec<VariantIdx,
                VariantLayout<FieldIdx>>>;
    }
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx, VariantIdx: ::core::hash::Hash + Idx>
    ::core::hash::Hash for Variants<FieldIdx, VariantIdx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Variants::Single { index: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
            Variants::Multiple {
                tag: __self_0,
                tag_encoding: __self_1,
                tag_field: __self_2,
                variants: __self_3 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state);
                ::core::hash::Hash::hash(__self_3, state)
            }
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx, VariantIdx: ::core::clone::Clone +
    Idx> ::core::clone::Clone for Variants<FieldIdx, VariantIdx> {
    #[inline]
    fn clone(&self) -> Variants<FieldIdx, VariantIdx> {
        match self {
            Variants::Empty => Variants::Empty,
            Variants::Single { index: __self_0 } =>
                Variants::Single {
                    index: ::core::clone::Clone::clone(__self_0),
                },
            Variants::Multiple {
                tag: __self_0,
                tag_encoding: __self_1,
                tag_field: __self_2,
                variants: __self_3 } =>
                Variants::Multiple {
                    tag: ::core::clone::Clone::clone(__self_0),
                    tag_encoding: ::core::clone::Clone::clone(__self_1),
                    tag_field: ::core::clone::Clone::clone(__self_2),
                    variants: ::core::clone::Clone::clone(__self_3),
                },
        }
    }
}Clone, #[automatically_derived]
impl<FieldIdx: ::core::fmt::Debug + Idx, VariantIdx: ::core::fmt::Debug + Idx>
    ::core::fmt::Debug for Variants<FieldIdx, VariantIdx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Variants::Empty => ::core::fmt::Formatter::write_str(f, "Empty"),
            Variants::Single { index: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Single", "index", &__self_0),
            Variants::Multiple {
                tag: __self_0,
                tag_encoding: __self_1,
                tag_field: __self_2,
                variants: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "Multiple", "tag", __self_0, "tag_encoding", __self_1,
                    "tag_field", __self_2, "variants", &__self_3),
        }
    }
}Debug)]
1936#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<FieldIdx: Idx, VariantIdx: Idx>
            ::rustc_data_structures::stable_hash::StableHash for
            Variants<FieldIdx, VariantIdx> where
            VariantIdx: ::rustc_data_structures::stable_hash::StableHash,
            FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    Variants::Empty => {}
                    Variants::Single { index: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    Variants::Multiple {
                        tag: ref __binding_0,
                        tag_encoding: ref __binding_1,
                        tag_field: ref __binding_2,
                        variants: ref __binding_3 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1937pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
1938    /// A type with no valid variants. Must be uninhabited.
1939    Empty,
1940
1941    /// Single enum variants, structs/tuples, unions, and all non-ADTs.
1942    Single {
1943        /// Always `0` for types that cannot have multiple variants.
1944        index: VariantIdx,
1945    },
1946
1947    /// Enum-likes with more than one variant: each variant comes with
1948    /// a *discriminant* (usually the same as the variant index but the user can
1949    /// assign explicit discriminant values). That discriminant is encoded
1950    /// as a *tag* on the machine. The layout of each variant is
1951    /// a struct, and they all have space reserved for the tag.
1952    /// For enums, the tag is the sole field of the layout.
1953    Multiple {
1954        tag: Scalar,
1955        tag_encoding: TagEncoding<VariantIdx>,
1956        tag_field: FieldIdx,
1957        variants: IndexVec<VariantIdx, VariantLayout<FieldIdx>>,
1958    },
1959}
1960
1961// NOTE: This struct is generic over the VariantIdx for rust-analyzer usage.
1962#[derive(#[automatically_derived]
impl<VariantIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
    TagEncoding<VariantIdx> {
    #[inline]
    fn eq(&self, other: &TagEncoding<VariantIdx>) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (TagEncoding::Niche {
                    untagged_variant: __self_0,
                    niche_variants: __self_1,
                    niche_start: __self_2 }, TagEncoding::Niche {
                    untagged_variant: __arg1_0,
                    niche_variants: __arg1_1,
                    niche_start: __arg1_2 }) =>
                    __self_2 == __arg1_2 && __self_0 == __arg1_0 &&
                        __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<VariantIdx: ::core::cmp::Eq + Idx> ::core::cmp::Eq for
    TagEncoding<VariantIdx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
        let _: ::core::cmp::AssertParamIsEq<RangeInclusive<VariantIdx>>;
        let _: ::core::cmp::AssertParamIsEq<u128>;
    }
}Eq, #[automatically_derived]
impl<VariantIdx: ::core::hash::Hash + Idx> ::core::hash::Hash for
    TagEncoding<VariantIdx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            TagEncoding::Niche {
                untagged_variant: __self_0,
                niche_variants: __self_1,
                niche_start: __self_2 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state)
            }
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl<VariantIdx: ::core::marker::Copy + Idx> ::core::marker::Copy for
    TagEncoding<VariantIdx> {
}Copy, #[automatically_derived]
impl<VariantIdx: ::core::clone::Clone + Idx> ::core::clone::Clone for
    TagEncoding<VariantIdx> {
    #[inline]
    fn clone(&self) -> TagEncoding<VariantIdx> {
        match self {
            TagEncoding::Direct => TagEncoding::Direct,
            TagEncoding::Niche {
                untagged_variant: __self_0,
                niche_variants: __self_1,
                niche_start: __self_2 } =>
                TagEncoding::Niche {
                    untagged_variant: ::core::clone::Clone::clone(__self_0),
                    niche_variants: ::core::clone::Clone::clone(__self_1),
                    niche_start: ::core::clone::Clone::clone(__self_2),
                },
        }
    }
}Clone, #[automatically_derived]
impl<VariantIdx: ::core::fmt::Debug + Idx> ::core::fmt::Debug for
    TagEncoding<VariantIdx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            TagEncoding::Direct =>
                ::core::fmt::Formatter::write_str(f, "Direct"),
            TagEncoding::Niche {
                untagged_variant: __self_0,
                niche_variants: __self_1,
                niche_start: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Niche",
                    "untagged_variant", __self_0, "niche_variants", __self_1,
                    "niche_start", &__self_2),
        }
    }
}Debug)]
1963#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<VariantIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
            for TagEncoding<VariantIdx> where
            VariantIdx: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    TagEncoding::Direct => {}
                    TagEncoding::Niche {
                        untagged_variant: ref __binding_0,
                        niche_variants: ref __binding_1,
                        niche_start: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
1964pub enum TagEncoding<VariantIdx: Idx> {
1965    /// The tag directly stores the discriminant, but possibly with a smaller layout
1966    /// (so converting the tag to the discriminant can require sign extension).
1967    Direct,
1968
1969    /// Niche (values invalid for a type) encoding the discriminant.
1970    /// Note that for this encoding, the discriminant and variant index of each variant coincide!
1971    /// This invariant is codified as part of [`layout_sanity_check`](../rustc_ty_utils/layout/invariant/fn.layout_sanity_check.html).
1972    ///
1973    /// The variant `untagged_variant` contains a niche at an arbitrary
1974    /// offset (field [`Variants::Multiple::tag_field`] of the enum).
1975    /// For a variant with variant index `i`, such that `i != untagged_variant`,
1976    /// the tag is set to `(i - niche_variants.start).wrapping_add(niche_start)`
1977    /// (this is wrapping arithmetic using the type of the niche field, cf. the
1978    /// [`tag_for_variant`](../rustc_const_eval/interpret/struct.InterpCx.html#method.tag_for_variant)
1979    /// query implementation).
1980    /// To recover the variant index `i` from a `tag`, the above formula has to be reversed,
1981    /// i.e. `i = tag.wrapping_sub(niche_start) + niche_variants.start`. If `i` ends up outside
1982    /// `niche_variants`, the tag must have encoded the `untagged_variant`.
1983    ///
1984    /// For example, `Option<(usize, &T)>`  is represented such that the tag for
1985    /// `None` is the null pointer in the second tuple field, and
1986    /// `Some` is the identity function (with a non-null reference)
1987    /// and has no additional tag, i.e. the reference being non-null uniquely identifies this variant.
1988    ///
1989    /// Other variants that are not `untagged_variant` and that are outside the `niche_variants`
1990    /// range cannot be represented; they must be uninhabited.
1991    /// Nonetheless, uninhabited variants can also fall into the range of `niche_variants`.
1992    Niche {
1993        untagged_variant: VariantIdx,
1994        /// This range *may* contain `untagged_variant` or uninhabited variants;
1995        /// these are then just "dead values" and not used to encode anything.
1996        niche_variants: RangeInclusive<VariantIdx>,
1997        /// This is inbounds of the type of the niche field
1998        /// (not sign-extended, i.e., all bits beyond the niche field size are 0).
1999        niche_start: u128,
2000    },
2001}
2002
2003#[derive(#[automatically_derived]
impl ::core::clone::Clone for Niche {
    #[inline]
    fn clone(&self) -> Niche {
        let _: ::core::clone::AssertParamIsClone<Size>;
        let _: ::core::clone::AssertParamIsClone<Primitive>;
        let _: ::core::clone::AssertParamIsClone<WrappingRange>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Niche { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Niche {
    #[inline]
    fn eq(&self, other: &Niche) -> bool {
        self.offset == other.offset && self.value == other.value &&
            self.valid_range == other.valid_range
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Niche {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Size>;
        let _: ::core::cmp::AssertParamIsEq<Primitive>;
        let _: ::core::cmp::AssertParamIsEq<WrappingRange>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Niche {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.offset, state);
        ::core::hash::Hash::hash(&self.value, state);
        ::core::hash::Hash::hash(&self.valid_range, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Niche {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Niche",
            "offset", &self.offset, "value", &self.value, "valid_range",
            &&self.valid_range)
    }
}Debug)]
2004#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for Niche {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Niche {
                        offset: ref __binding_0,
                        value: ref __binding_1,
                        valid_range: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
2005pub struct Niche {
2006    pub offset: Size,
2007    pub value: Primitive,
2008    pub valid_range: WrappingRange,
2009}
2010
2011impl Niche {
2012    pub fn from_scalar<C: HasDataLayout>(cx: &C, offset: Size, scalar: Scalar) -> Option<Self> {
2013        let Scalar::Initialized { value, valid_range } = scalar else { return None };
2014        let niche = Niche { offset, value, valid_range };
2015        if niche.available(cx) > 0 { Some(niche) } else { None }
2016    }
2017
2018    pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
2019        let Self { value, valid_range: v, .. } = *self;
2020        let size = value.size(cx);
2021        if !(size.bits() <= 128) {
    ::core::panicking::panic("assertion failed: size.bits() <= 128")
};assert!(size.bits() <= 128);
2022        let max_value = size.unsigned_int_max();
2023
2024        // Find out how many values are outside the valid range.
2025        let niche = v.end.wrapping_add(1)..v.start;
2026        niche.end.wrapping_sub(niche.start) & max_value
2027    }
2028
2029    pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
2030        if !(count > 0) { ::core::panicking::panic("assertion failed: count > 0") };assert!(count > 0);
2031
2032        let Self { value, valid_range: v, .. } = *self;
2033        let size = value.size(cx);
2034        if !(size.bits() <= 128) {
    ::core::panicking::panic("assertion failed: size.bits() <= 128")
};assert!(size.bits() <= 128);
2035        let max_value = size.unsigned_int_max();
2036
2037        let available = v.start.wrapping_sub(v.end).wrapping_sub(1) & max_value;
2038        if count > available {
2039            return None;
2040        }
2041
2042        // Extend the range of valid values being reserved by moving either `v.start` or `v.end`
2043        // bound. Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy
2044        // the niche of zero. This is accomplished by preferring enums with 2 variants(`count==1`)
2045        // and always taking the shortest path to niche zero. Having `None` in niche zero can
2046        // enable some special optimizations.
2047        //
2048        // Bound selection criteria:
2049        // 1. Select closest to zero given wrapping semantics.
2050        // 2. Avoid moving past zero if possible.
2051        //
2052        // In practice this means that enums with `count > 1` are unlikely to claim niche zero,
2053        // since they have to fit perfectly. If niche zero is already reserved, the selection of
2054        // bounds are of little interest.
2055        let move_start = |v: WrappingRange| {
2056            let start = v.start.wrapping_sub(count) & max_value;
2057            Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) }))
2058        };
2059        let move_end = |v: WrappingRange| {
2060            let start = v.end.wrapping_add(1) & max_value;
2061            let end = v.end.wrapping_add(count) & max_value;
2062            Some((start, Scalar::Initialized { value, valid_range: v.with_end(end) }))
2063        };
2064        let distance_end_zero = max_value - v.end;
2065        // FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
2066        // <https://github.com/rust-lang/rust/pull/155473#issuecomment-4302036343>
2067        let is_bool = size.bytes() == 1 && v == WrappingRange { start: 0, end: 1 };
2068        if count == 1 && !is_bool {
2069            // We only need one, so just pick the one closest to zero.
2070            // Not only does that obviously use zero if it's possible, but it also
2071            // simplifies testing things like `Option<char>`, since looking for `-1`
2072            // is easier than looking for `1114112` (and matches clang's `WEOF`).
2073            let next_up = size.sign_extend(v.end.wrapping_add(1)).unsigned_abs();
2074            let next_down = size.sign_extend(v.start.wrapping_sub(1)).unsigned_abs();
2075            if next_down <= next_up { move_start(v) } else { move_end(v) }
2076        } else if v.start > v.end {
2077            // zero is unavailable because wrapping occurs
2078            move_end(v)
2079        } else if v.start <= distance_end_zero {
2080            if count <= v.start {
2081                move_start(v)
2082            } else {
2083                // moved past zero, use other bound
2084                move_end(v)
2085            }
2086        } else {
2087            let end = v.end.wrapping_add(count) & max_value;
2088            let overshot_zero = (1..=v.end).contains(&end);
2089            if overshot_zero {
2090                // moved past zero, use other bound
2091                move_start(v)
2092            } else {
2093                move_end(v)
2094            }
2095        }
2096    }
2097}
2098
2099// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage.
2100#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx,
    VariantIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
    LayoutData<FieldIdx, VariantIdx> {
    #[inline]
    fn eq(&self, other: &LayoutData<FieldIdx, VariantIdx>) -> bool {
        self.uninhabited == other.uninhabited && self.fields == other.fields
                                        && self.variants == other.variants &&
                                    self.backend_repr == other.backend_repr &&
                                self.largest_niche == other.largest_niche &&
                            self.align == other.align && self.size == other.size &&
                    self.max_repr_align == other.max_repr_align &&
                self.unadjusted_abi_align == other.unadjusted_abi_align &&
            self.randomization_seed == other.randomization_seed
    }
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx, VariantIdx: ::core::cmp::Eq + Idx>
    ::core::cmp::Eq for LayoutData<FieldIdx, VariantIdx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<FieldsShape<FieldIdx>>;
        let _: ::core::cmp::AssertParamIsEq<Variants<FieldIdx, VariantIdx>>;
        let _: ::core::cmp::AssertParamIsEq<BackendRepr>;
        let _: ::core::cmp::AssertParamIsEq<Option<Niche>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<AbiAlign>;
        let _: ::core::cmp::AssertParamIsEq<Size>;
        let _: ::core::cmp::AssertParamIsEq<Option<Align>>;
        let _: ::core::cmp::AssertParamIsEq<Align>;
        let _: ::core::cmp::AssertParamIsEq<Hash64>;
    }
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx, VariantIdx: ::core::hash::Hash + Idx>
    ::core::hash::Hash for LayoutData<FieldIdx, VariantIdx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.fields, state);
        ::core::hash::Hash::hash(&self.variants, state);
        ::core::hash::Hash::hash(&self.backend_repr, state);
        ::core::hash::Hash::hash(&self.largest_niche, state);
        ::core::hash::Hash::hash(&self.uninhabited, state);
        ::core::hash::Hash::hash(&self.align, state);
        ::core::hash::Hash::hash(&self.size, state);
        ::core::hash::Hash::hash(&self.max_repr_align, state);
        ::core::hash::Hash::hash(&self.unadjusted_abi_align, state);
        ::core::hash::Hash::hash(&self.randomization_seed, state)
    }
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx, VariantIdx: ::core::clone::Clone +
    Idx> ::core::clone::Clone for LayoutData<FieldIdx, VariantIdx> {
    #[inline]
    fn clone(&self) -> LayoutData<FieldIdx, VariantIdx> {
        LayoutData {
            fields: ::core::clone::Clone::clone(&self.fields),
            variants: ::core::clone::Clone::clone(&self.variants),
            backend_repr: ::core::clone::Clone::clone(&self.backend_repr),
            largest_niche: ::core::clone::Clone::clone(&self.largest_niche),
            uninhabited: ::core::clone::Clone::clone(&self.uninhabited),
            align: ::core::clone::Clone::clone(&self.align),
            size: ::core::clone::Clone::clone(&self.size),
            max_repr_align: ::core::clone::Clone::clone(&self.max_repr_align),
            unadjusted_abi_align: ::core::clone::Clone::clone(&self.unadjusted_abi_align),
            randomization_seed: ::core::clone::Clone::clone(&self.randomization_seed),
        }
    }
}Clone)]
2101#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<FieldIdx: Idx, VariantIdx: Idx>
            ::rustc_data_structures::stable_hash::StableHash for
            LayoutData<FieldIdx, VariantIdx> where
            FieldIdx: ::rustc_data_structures::stable_hash::StableHash,
            VariantIdx: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    LayoutData {
                        fields: ref __binding_0,
                        variants: ref __binding_1,
                        backend_repr: ref __binding_2,
                        largest_niche: ref __binding_3,
                        uninhabited: ref __binding_4,
                        align: ref __binding_5,
                        size: ref __binding_6,
                        max_repr_align: ref __binding_7,
                        unadjusted_abi_align: ref __binding_8,
                        randomization_seed: ref __binding_9 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                        { __binding_8.stable_hash(__hcx, __hasher); }
                        { __binding_9.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
2102pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
2103    /// Says where the fields are located within the layout.
2104    pub fields: FieldsShape<FieldIdx>,
2105
2106    /// Encodes information about multi-variant layouts.
2107    /// Even with `Multiple` variants, a layout still has its own fields! Those are then
2108    /// shared between all variants. One of them will be the discriminant,
2109    /// but e.g. coroutines can have more.
2110    ///
2111    /// To access all fields of this layout, both `fields` and the fields of the active variant
2112    /// must be taken into account.
2113    pub variants: Variants<FieldIdx, VariantIdx>,
2114
2115    /// The `backend_repr` defines how this data will be represented to the codegen backend,
2116    /// and encodes value restrictions via `valid_range`.
2117    ///
2118    /// Note that this is entirely orthogonal to the recursive structure defined by
2119    /// `variants` and `fields`; for example, `ManuallyDrop<Result<isize, isize>>` has
2120    /// `IrForm::ScalarPair`! So, even with non-`Memory` `backend_repr`, `fields` and `variants`
2121    /// have to be taken into account to find all fields of this layout.
2122    pub backend_repr: BackendRepr,
2123
2124    /// The leaf scalar with the largest number of invalid values
2125    /// (i.e. outside of its `valid_range`), if it exists.
2126    pub largest_niche: Option<Niche>,
2127    /// Is this type known to be uninhabted?
2128    ///
2129    /// This is separate from BackendRepr because uninhabited return types can affect ABI,
2130    /// especially in the case of by-pointer struct returns, which allocate stack even when unused.
2131    pub uninhabited: bool,
2132
2133    pub align: AbiAlign,
2134    pub size: Size,
2135
2136    /// The largest alignment explicitly requested with `repr(align)` on this type or any field.
2137    /// Only used on i686-windows, where the argument passing ABI is different when alignment is
2138    /// requested, even if the requested alignment is equal to the natural alignment.
2139    pub max_repr_align: Option<Align>,
2140
2141    /// The alignment the type would have, ignoring any `repr(align)` but including `repr(packed)`.
2142    /// Only used on aarch64-linux, where the argument passing ABI ignores the requested alignment
2143    /// in some cases.
2144    pub unadjusted_abi_align: Align,
2145
2146    /// The randomization seed based on this type's own repr and its fields.
2147    ///
2148    /// Since randomization is toggled on a per-crate basis even crates that do not have randomization
2149    /// enabled should still calculate a seed so that downstream uses can use it to distinguish different
2150    /// types.
2151    ///
2152    /// For every T and U for which we do not guarantee that a repr(Rust) `Foo<T>` can be coerced or
2153    /// transmuted to `Foo<U>` we aim to create probalistically distinct seeds so that Foo can choose
2154    /// to reorder its fields based on that information. The current implementation is a conservative
2155    /// approximation of this goal.
2156    pub randomization_seed: Hash64,
2157}
2158
2159impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
2160    /// Returns `true` if this is an aggregate type (including a ScalarPair!)
2161    pub fn is_aggregate(&self) -> bool {
2162        match self.backend_repr {
2163            BackendRepr::Scalar(_)
2164            | BackendRepr::SimdVector { .. }
2165            | BackendRepr::SimdScalableVector { .. } => false,
2166            BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true,
2167        }
2168    }
2169
2170    /// Returns `true` if this is an uninhabited type
2171    pub fn is_uninhabited(&self) -> bool {
2172        self.uninhabited
2173    }
2174}
2175
2176impl<FieldIdx: Idx, VariantIdx: Idx> fmt::Debug for LayoutData<FieldIdx, VariantIdx>
2177where
2178    FieldsShape<FieldIdx>: fmt::Debug,
2179    Variants<FieldIdx, VariantIdx>: fmt::Debug,
2180{
2181    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2182        // This is how `Layout` used to print before it become
2183        // `Interned<LayoutData>`. We print it like this to avoid having to update
2184        // expected output in a lot of tests.
2185        let LayoutData {
2186            size,
2187            align,
2188            backend_repr,
2189            fields,
2190            largest_niche,
2191            uninhabited,
2192            variants,
2193            max_repr_align,
2194            unadjusted_abi_align,
2195            randomization_seed,
2196        } = self;
2197        f.debug_struct("Layout")
2198            .field("size", size)
2199            .field("align", align)
2200            .field("backend_repr", backend_repr)
2201            .field("fields", fields)
2202            .field("largest_niche", largest_niche)
2203            .field("uninhabited", uninhabited)
2204            .field("variants", variants)
2205            .field("max_repr_align", max_repr_align)
2206            .field("unadjusted_abi_align", unadjusted_abi_align)
2207            .field("randomization_seed", randomization_seed)
2208            .finish()
2209    }
2210}
2211
2212#[derive(#[automatically_derived]
impl ::core::marker::Copy for PointerKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PointerKind {
    #[inline]
    fn clone(&self) -> PointerKind {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PointerKind {
    #[inline]
    fn eq(&self, other: &PointerKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (PointerKind::SharedRef { frozen: __self_0 },
                    PointerKind::SharedRef { frozen: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                (PointerKind::MutableRef { unpin: __self_0 },
                    PointerKind::MutableRef { unpin: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                (PointerKind::Box { unpin: __self_0, global: __self_1 },
                    PointerKind::Box { unpin: __arg1_0, global: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PointerKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for PointerKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PointerKind::SharedRef { frozen: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "SharedRef", "frozen", &__self_0),
            PointerKind::MutableRef { unpin: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "MutableRef", "unpin", &__self_0),
            PointerKind::Box { unpin: __self_0, global: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Box",
                    "unpin", __self_0, "global", &__self_1),
        }
    }
}Debug)]
2213pub enum PointerKind {
2214    /// Shared reference. `frozen` indicates the absence of any `UnsafeCell`.
2215    SharedRef { frozen: bool },
2216    /// Mutable reference. `unpin` indicates the absence of any pinned data.
2217    MutableRef { unpin: bool },
2218    /// Box. `unpin` indicates the absence of any pinned data. `global` indicates whether this box
2219    /// uses the global allocator or a custom one.
2220    Box { unpin: bool, global: bool },
2221}
2222
2223/// Encodes extra information we have about a pointer.
2224///
2225/// Note that this information is advisory only, and backends are free to ignore it:
2226/// if the information is wrong, that can cause UB, but if the information is absent,
2227/// that must always be okay.
2228#[derive(#[automatically_derived]
impl ::core::marker::Copy for PointeeInfo { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PointeeInfo {
    #[inline]
    fn clone(&self) -> PointeeInfo {
        let _: ::core::clone::AssertParamIsClone<Option<PointerKind>>;
        let _: ::core::clone::AssertParamIsClone<Size>;
        let _: ::core::clone::AssertParamIsClone<Align>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PointeeInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "PointeeInfo",
            "safe", &self.safe, "size", &self.size, "align", &&self.align)
    }
}Debug)]
2229pub struct PointeeInfo {
2230    /// If this is `None`, then this is a raw pointer.
2231    pub safe: Option<PointerKind>,
2232    /// If `size` is not zero, then the pointer is either null or dereferenceable for this many bytes
2233    /// (independent of `safe`).
2234    ///
2235    /// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration
2236    /// of this function call", i.e. it is UB for the memory that this pointer points to be freed
2237    /// while this function is still running.
2238    pub size: Size,
2239    /// The pointer is guaranteed to be aligned this much (independent of `safe`).
2240    pub align: Align,
2241}
2242
2243impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
2244    /// Returns `true` if the layout corresponds to an unsized type.
2245    #[inline]
2246    pub fn is_unsized(&self) -> bool {
2247        self.backend_repr.is_unsized()
2248    }
2249
2250    #[inline]
2251    pub fn is_sized(&self) -> bool {
2252        self.backend_repr.is_sized()
2253    }
2254
2255    /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
2256    pub fn is_1zst(&self) -> bool {
2257        self.is_sized() && self.size.bytes() == 0 && self.align.bytes() == 1
2258    }
2259
2260    /// Returns `true` if the size of the type is only known at runtime.
2261    pub fn is_scalable_vector(&self) -> bool {
2262        #[allow(non_exhaustive_omitted_patterns)] match self.backend_repr {
    BackendRepr::SimdScalableVector { .. } => true,
    _ => false,
}matches!(self.backend_repr, BackendRepr::SimdScalableVector { .. })
2263    }
2264
2265    /// Returns the elements count of a scalable vector.
2266    pub fn scalable_vector_element_count(&self) -> Option<u64> {
2267        match self.backend_repr {
2268            BackendRepr::SimdScalableVector { count, .. } => Some(count),
2269            _ => None,
2270        }
2271    }
2272
2273    /// Returns `true` if the type is a ZST and not unsized.
2274    ///
2275    /// Note that this does *not* imply that the type is irrelevant for layout! It can still have
2276    /// non-trivial alignment constraints. You probably want to use `is_1zst` instead.
2277    pub fn is_zst(&self) -> bool {
2278        match self.backend_repr {
2279            BackendRepr::Scalar(_)
2280            | BackendRepr::ScalarPair(..)
2281            | BackendRepr::SimdScalableVector { .. }
2282            | BackendRepr::SimdVector { .. } => false,
2283            BackendRepr::Memory { sized } => sized && self.size.bytes() == 0,
2284        }
2285    }
2286
2287    /// Checks if these two `Layout` are equal enough to be considered "the same for all function
2288    /// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
2289    /// `Layout`; the `PassMode` need to be compared as well. Also note that we assume
2290    /// aggregates are passed via `PassMode::Indirect` or `PassMode::Cast`; more strict
2291    /// checks would otherwise be required.
2292    pub fn eq_abi(&self, other: &Self) -> bool {
2293        // The one thing that we are not capturing here is that for unsized types, the metadata must
2294        // also have the same ABI, and moreover that the same metadata leads to the same size. The
2295        // 2nd point is quite hard to check though.
2296        self.size == other.size
2297            && self.is_sized() == other.is_sized()
2298            && self.backend_repr.eq_up_to_validity(&other.backend_repr)
2299            && self.backend_repr.is_bool() == other.backend_repr.is_bool()
2300            && self.align.abi == other.align.abi
2301            && self.max_repr_align == other.max_repr_align
2302            && self.unadjusted_abi_align == other.unadjusted_abi_align
2303    }
2304}
2305
2306#[derive(#[automatically_derived]
impl ::core::marker::Copy for StructKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for StructKind {
    #[inline]
    fn clone(&self) -> StructKind {
        let _: ::core::clone::AssertParamIsClone<Size>;
        let _: ::core::clone::AssertParamIsClone<Align>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for StructKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            StructKind::AlwaysSized =>
                ::core::fmt::Formatter::write_str(f, "AlwaysSized"),
            StructKind::MaybeUnsized =>
                ::core::fmt::Formatter::write_str(f, "MaybeUnsized"),
            StructKind::Prefixed(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "Prefixed", __self_0, &__self_1),
        }
    }
}Debug)]
2307pub enum StructKind {
2308    /// A tuple, closure, or univariant which cannot be coerced to unsized.
2309    AlwaysSized,
2310    /// A univariant, the last field of which may be coerced to unsized.
2311    MaybeUnsized,
2312    /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
2313    Prefixed(Size, Align),
2314}
2315
2316#[derive(#[automatically_derived]
impl ::core::clone::Clone for AbiFromStrErr {
    #[inline]
    fn clone(&self) -> AbiFromStrErr {
        match self {
            AbiFromStrErr::Unknown => AbiFromStrErr::Unknown,
            AbiFromStrErr::NoExplicitUnwind =>
                AbiFromStrErr::NoExplicitUnwind,
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AbiFromStrErr {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AbiFromStrErr::Unknown => "Unknown",
                AbiFromStrErr::NoExplicitUnwind => "NoExplicitUnwind",
            })
    }
}Debug)]
2317pub enum AbiFromStrErr {
2318    /// not a known ABI
2319    Unknown,
2320    /// no "-unwind" variant can be used here
2321    NoExplicitUnwind,
2322}
2323
2324// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage.
2325#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
    VariantLayout<FieldIdx> {
    #[inline]
    fn eq(&self, other: &VariantLayout<FieldIdx>) -> bool {
        self.uninhabited == other.uninhabited && self.size == other.size &&
                        self.backend_repr == other.backend_repr &&
                    self.field_offsets == other.field_offsets &&
                self.fields_in_memory_order == other.fields_in_memory_order &&
            self.largest_niche == other.largest_niche
    }
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx> ::core::cmp::Eq for
    VariantLayout<FieldIdx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Size>;
        let _: ::core::cmp::AssertParamIsEq<BackendRepr>;
        let _: ::core::cmp::AssertParamIsEq<IndexVec<FieldIdx, Size>>;
        let _: ::core::cmp::AssertParamIsEq<IndexVec<u32, FieldIdx>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Niche>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx> ::core::hash::Hash for
    VariantLayout<FieldIdx> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.size, state);
        ::core::hash::Hash::hash(&self.backend_repr, state);
        ::core::hash::Hash::hash(&self.field_offsets, state);
        ::core::hash::Hash::hash(&self.fields_in_memory_order, state);
        ::core::hash::Hash::hash(&self.largest_niche, state);
        ::core::hash::Hash::hash(&self.uninhabited, state)
    }
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx> ::core::clone::Clone for
    VariantLayout<FieldIdx> {
    #[inline]
    fn clone(&self) -> VariantLayout<FieldIdx> {
        VariantLayout {
            size: ::core::clone::Clone::clone(&self.size),
            backend_repr: ::core::clone::Clone::clone(&self.backend_repr),
            field_offsets: ::core::clone::Clone::clone(&self.field_offsets),
            fields_in_memory_order: ::core::clone::Clone::clone(&self.fields_in_memory_order),
            largest_niche: ::core::clone::Clone::clone(&self.largest_niche),
            uninhabited: ::core::clone::Clone::clone(&self.uninhabited),
        }
    }
}Clone, #[automatically_derived]
impl<FieldIdx: ::core::fmt::Debug + Idx> ::core::fmt::Debug for
    VariantLayout<FieldIdx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["size", "backend_repr", "field_offsets",
                        "fields_in_memory_order", "largest_niche", "uninhabited"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.size, &self.backend_repr, &self.field_offsets,
                        &self.fields_in_memory_order, &self.largest_niche,
                        &&self.uninhabited];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "VariantLayout",
            names, values)
    }
}Debug)]
2326#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<FieldIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
            for VariantLayout<FieldIdx> where
            FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    VariantLayout {
                        size: ref __binding_0,
                        backend_repr: ref __binding_1,
                        field_offsets: ref __binding_2,
                        fields_in_memory_order: ref __binding_3,
                        largest_niche: ref __binding_4,
                        uninhabited: ref __binding_5 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
2327pub struct VariantLayout<FieldIdx: Idx> {
2328    pub size: Size,
2329    pub backend_repr: BackendRepr,
2330    pub field_offsets: IndexVec<FieldIdx, Size>,
2331    fields_in_memory_order: IndexVec<u32, FieldIdx>,
2332    largest_niche: Option<Niche>,
2333    uninhabited: bool,
2334}
2335
2336impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
2337    pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self {
2338        let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else {
2339            {
    ::core::panicking::panic_fmt(format_args!("Layout of fields should be Arbitrary for variants"));
};panic!("Layout of fields should be Arbitrary for variants");
2340        };
2341
2342        Self {
2343            size: layout.size,
2344            backend_repr: layout.backend_repr,
2345            field_offsets: offsets,
2346            fields_in_memory_order: in_memory_order,
2347            largest_niche: layout.largest_niche,
2348            uninhabited: layout.uninhabited,
2349        }
2350    }
2351
2352    pub fn is_uninhabited(&self) -> bool {
2353        self.uninhabited
2354    }
2355
2356    pub fn has_fields(&self) -> bool {
2357        self.field_offsets.len() > 0
2358    }
2359}