Skip to main content

rustc_abi/
lib.rs

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