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