1#![cfg_attr(feature = "nightly", allow(internal_features))]
3#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
4#![cfg_attr(feature = "nightly", feature(step_trait))]
5use std::cmp::min;
40use std::fmt;
41#[cfg(feature = "nightly")]
42use std::iter::Step;
43use std::num::{NonZeroUsize, ParseIntError};
44use std::ops::{Add, AddAssign, Deref, Mul, RangeFull, Sub};
45use std::range::RangeInclusive;
46use std::str::FromStr;
47
48use bitflags::bitflags;
49#[cfg(feature = "nightly")]
50use rustc_data_structures::stable_hash::StableOrd;
51#[cfg(feature = "nightly")]
52use rustc_error_messages::{DiagArgValue, IntoDiagArg};
53#[cfg(feature = "nightly")]
54use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg};
55use rustc_hashes::Hash64;
56use rustc_index::{Idx, IndexSlice, IndexVec};
57#[cfg(feature = "nightly")]
58use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash};
59#[cfg(feature = "nightly")]
60use rustc_span::{Symbol, sym};
61
62mod callconv;
63mod canon_abi;
64mod extern_abi;
65mod layout;
66#[cfg(test)]
67mod tests;
68
69pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
70pub use canon_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
71#[cfg(feature = "nightly")]
72pub use extern_abi::CVariadicStatus;
73pub use extern_abi::{ExternAbi, all_names};
74pub use layout::{FIRST_VARIANT, FieldIdx, LayoutCalculator, LayoutCalculatorError, VariantIdx};
75#[cfg(feature = "nightly")]
76pub use layout::{Layout, TyAbiInterface, TyAndLayout};
77
78#[derive(#[automatically_derived]
impl ::core::clone::Clone for ReprFlags {
#[inline]
fn clone(&self) -> ReprFlags {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ReprFlags { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ReprFlags {
#[inline]
fn eq(&self, other: &ReprFlags) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ReprFlags {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::default::Default for ReprFlags {
#[inline]
fn default() -> ReprFlags {
ReprFlags(::core::default::Default::default())
}
}Default)]
79#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for ReprFlags {
fn encode(&self, __encoder: &mut __E) {
match *self {
ReprFlags(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for ReprFlags {
fn decode(__decoder: &mut __D) -> Self {
ReprFlags(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for ReprFlags {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
ReprFlags(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
80pub struct ReprFlags(u8);
81
82impl ReprFlags {
#[allow(deprecated, non_upper_case_globals,)]
pub const IS_C: Self = Self::from_bits_retain(1 << 0);
#[allow(deprecated, non_upper_case_globals,)]
pub const IS_SIMD: Self = Self::from_bits_retain(1 << 1);
#[allow(deprecated, non_upper_case_globals,)]
pub const IS_TRANSPARENT: Self = Self::from_bits_retain(1 << 2);
#[doc = r" Internal only for now. If true, don't reorder fields."]
#[doc = r" On its own it does not prevent ABI optimizations."]
#[allow(deprecated, non_upper_case_globals,)]
pub const IS_LINEAR: Self = Self::from_bits_retain(1 << 3);
#[doc =
r" If true, the type's crate has opted into layout randomization."]
#[doc =
r" Other flags can still inhibit reordering and thus randomization."]
#[doc = r" The seed stored in `ReprOptions.field_shuffle_seed`."]
#[allow(deprecated, non_upper_case_globals,)]
pub const RANDOMIZE_LAYOUT: Self = Self::from_bits_retain(1 << 4);
#[doc =
r" If true, the type is always passed indirectly by non-Rustic ABIs."]
#[doc =
r" See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details."]
#[allow(deprecated, non_upper_case_globals,)]
pub const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS: Self =
Self::from_bits_retain(1 << 5);
#[allow(deprecated, non_upper_case_globals,)]
pub const IS_SCALABLE: Self = Self::from_bits_retain(1 << 6);
#[allow(deprecated, non_upper_case_globals,)]
pub const FIELD_ORDER_UNOPTIMIZABLE: Self =
Self::from_bits_retain(ReprFlags::IS_C.bits() |
ReprFlags::IS_SIMD.bits() | ReprFlags::IS_SCALABLE.bits() |
ReprFlags::IS_LINEAR.bits());
#[allow(deprecated, non_upper_case_globals,)]
pub const ABI_UNOPTIMIZABLE: Self =
Self::from_bits_retain(ReprFlags::IS_C.bits() |
ReprFlags::IS_SIMD.bits());
}
impl ::bitflags::Flags for ReprFlags {
const FLAGS: &'static [::bitflags::Flag<ReprFlags>] =
&[{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("IS_C", ReprFlags::IS_C)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("IS_SIMD", ReprFlags::IS_SIMD)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("IS_TRANSPARENT",
ReprFlags::IS_TRANSPARENT)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("IS_LINEAR", ReprFlags::IS_LINEAR)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("RANDOMIZE_LAYOUT",
ReprFlags::RANDOMIZE_LAYOUT)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS",
ReprFlags::PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("IS_SCALABLE", ReprFlags::IS_SCALABLE)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("FIELD_ORDER_UNOPTIMIZABLE",
ReprFlags::FIELD_ORDER_UNOPTIMIZABLE)
},
{
#[allow(deprecated, non_upper_case_globals,)]
::bitflags::Flag::new("ABI_UNOPTIMIZABLE",
ReprFlags::ABI_UNOPTIMIZABLE)
}];
type Bits = u8;
fn bits(&self) -> u8 { ReprFlags::bits(self) }
fn from_bits_retain(bits: u8) -> ReprFlags {
ReprFlags::from_bits_retain(bits)
}
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy ::
assign_op_pattern, clippy :: iter_without_into_iter,)]
const _: () =
{
#[allow(dead_code, deprecated, unused_attributes)]
impl ReprFlags {
#[inline]
pub const fn empty() -> Self {
Self(<u8 as ::bitflags::Bits>::EMPTY)
}
#[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)
}
#[inline]
pub const fn bits(&self) -> u8 { self.0 }
#[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 }
}
#[inline]
pub const fn from_bits_truncate(bits: u8) -> Self {
Self(bits & Self::all().0)
}
#[inline]
pub const fn from_bits_retain(bits: u8) -> Self { Self(bits) }
#[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
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.0 == <u8 as ::bitflags::Bits>::EMPTY
}
#[inline]
pub const fn is_all(&self) -> bool {
Self::all().0 | self.0 == self.0
}
#[inline]
pub const fn intersects(&self, other: Self) -> bool {
self.0 & other.0 != <u8 as ::bitflags::Bits>::EMPTY
}
#[inline]
pub const fn contains(&self, other: Self) -> bool {
self.0 & other.0 == other.0
}
#[inline]
pub fn insert(&mut self, other: Self) {
*self = Self(self.0).union(other);
}
#[inline]
pub fn remove(&mut self, other: Self) {
*self = Self(self.0).difference(other);
}
#[inline]
pub fn toggle(&mut self, other: Self) {
*self = Self(self.0).symmetric_difference(other);
}
#[inline]
pub fn set(&mut self, other: Self, value: bool) {
if value { self.insert(other); } else { self.remove(other); }
}
#[inline]
#[must_use]
pub const fn intersection(self, other: Self) -> Self {
Self(self.0 & other.0)
}
#[inline]
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
#[inline]
#[must_use]
pub const fn difference(self, other: Self) -> Self {
Self(self.0 & !other.0)
}
#[inline]
#[must_use]
pub const fn symmetric_difference(self, other: Self) -> Self {
Self(self.0 ^ other.0)
}
#[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;
#[inline]
fn bitor(self, other: ReprFlags) -> Self { self.union(other) }
}
impl ::bitflags::__private::core::ops::BitOrAssign for ReprFlags {
#[inline]
fn bitor_assign(&mut self, other: Self) { self.insert(other); }
}
impl ::bitflags::__private::core::ops::BitXor for ReprFlags {
type Output = Self;
#[inline]
fn bitxor(self, other: Self) -> Self {
self.symmetric_difference(other)
}
}
impl ::bitflags::__private::core::ops::BitXorAssign for ReprFlags {
#[inline]
fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
}
impl ::bitflags::__private::core::ops::BitAnd for ReprFlags {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self { self.intersection(other) }
}
impl ::bitflags::__private::core::ops::BitAndAssign for ReprFlags {
#[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;
#[inline]
fn sub(self, other: Self) -> Self { self.difference(other) }
}
impl ::bitflags::__private::core::ops::SubAssign for ReprFlags {
#[inline]
fn sub_assign(&mut self, other: Self) { self.remove(other); }
}
impl ::bitflags::__private::core::ops::Not for ReprFlags {
type Output = Self;
#[inline]
fn not(self) -> Self { self.complement() }
}
impl ::bitflags::__private::core::iter::Extend<ReprFlags> for
ReprFlags {
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 {
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 {
#[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()))
}
#[inline]
pub const fn iter_names(&self)
-> ::bitflags::iter::IterNames<ReprFlags> {
::bitflags::iter::IterNames::__private_const_new(<ReprFlags as
::bitflags::Flags>::FLAGS,
ReprFlags::from_bits_retain(self.bits()),
ReprFlags::from_bits_retain(self.bits()))
}
}
impl ::bitflags::__private::core::iter::IntoIterator for ReprFlags {
type Item = ReprFlags;
type IntoIter = ::bitflags::iter::Iter<ReprFlags>;
fn into_iter(self) -> Self::IntoIter { self.iter() }
}
};bitflags! {
83 impl ReprFlags: u8 {
84 const IS_C = 1 << 0;
85 const IS_SIMD = 1 << 1;
86 const IS_TRANSPARENT = 1 << 2;
87 const IS_LINEAR = 1 << 3;
90 const RANDOMIZE_LAYOUT = 1 << 4;
94 const PASS_INDIRECTLY_IN_NON_RUSTIC_ABIS = 1 << 5;
97 const IS_SCALABLE = 1 << 6;
98 const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
100 | ReprFlags::IS_SIMD.bits()
101 | ReprFlags::IS_SCALABLE.bits()
102 | ReprFlags::IS_LINEAR.bits();
103 const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
104 }
105}
106
107impl std::fmt::Debug for ReprFlags {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 bitflags::parser::to_writer(self, f)
112 }
113}
114
115#[derive(#[automatically_derived]
impl ::core::marker::Copy for IntegerType { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IntegerType {
#[inline]
fn clone(&self) -> IntegerType {
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<Integer>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for IntegerType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
IntegerType::Pointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Pointer", &__self_0),
IntegerType::Fixed(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f, "Fixed",
__self_0, &__self_1),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for IntegerType {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<Integer>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for IntegerType {
#[inline]
fn eq(&self, other: &IntegerType) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(IntegerType::Pointer(__self_0),
IntegerType::Pointer(__arg1_0)) => __self_0 == __arg1_0,
(IntegerType::Fixed(__self_0, __self_1),
IntegerType::Fixed(__arg1_0, __arg1_1)) =>
__self_1 == __arg1_1 && __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
116#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for IntegerType {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
IntegerType::Pointer(ref __binding_0) => { 0usize }
IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
1usize
}
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
IntegerType::Pointer(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for IntegerType {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
IntegerType::Pointer(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
IntegerType::Fixed(::rustc_serialize::Decodable::decode(__decoder),
::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `IntegerType`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for IntegerType
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
IntegerType::Pointer(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
IntegerType::Fixed(ref __binding_0, ref __binding_1) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
117pub enum IntegerType {
118 Pointer(bool),
121 Fixed(Integer, bool),
124}
125
126impl IntegerType {
127 pub fn is_signed(&self) -> bool {
128 match self {
129 IntegerType::Pointer(b) => *b,
130 IntegerType::Fixed(_, b) => *b,
131 }
132 }
133}
134
135#[derive(#[automatically_derived]
impl ::core::marker::Copy for ScalableElt { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ScalableElt {
#[inline]
fn clone(&self) -> ScalableElt {
let _: ::core::clone::AssertParamIsClone<u16>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ScalableElt {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ScalableElt::ElementCount(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ElementCount", &__self_0),
ScalableElt::Container =>
::core::fmt::Formatter::write_str(f, "Container"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for ScalableElt {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u16>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for ScalableElt {
#[inline]
fn eq(&self, other: &ScalableElt) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ScalableElt::ElementCount(__self_0),
ScalableElt::ElementCount(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
136#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for ScalableElt {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
ScalableElt::ElementCount(ref __binding_0) => { 0usize }
ScalableElt::Container => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
ScalableElt::ElementCount(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
ScalableElt::Container => {}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for ScalableElt {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
ScalableElt::ElementCount(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => { ScalableElt::Container }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ScalableElt`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for ScalableElt
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
ScalableElt::ElementCount(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
ScalableElt::Container => {}
}
}
}
};StableHash))]
137pub enum ScalableElt {
138 ElementCount(u16),
140 Container,
143}
144
145#[derive(#[automatically_derived]
impl ::core::marker::Copy for ReprOptions { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ReprOptions {
#[inline]
fn clone(&self) -> ReprOptions {
let _: ::core::clone::AssertParamIsClone<Option<IntegerType>>;
let _: ::core::clone::AssertParamIsClone<Option<Align>>;
let _: ::core::clone::AssertParamIsClone<Option<Align>>;
let _: ::core::clone::AssertParamIsClone<ReprFlags>;
let _: ::core::clone::AssertParamIsClone<Option<ScalableElt>>;
let _: ::core::clone::AssertParamIsClone<Hash64>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ReprOptions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["int", "align", "pack", "flags", "scalable",
"field_shuffle_seed"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.int, &self.align, &self.pack, &self.flags, &self.scalable,
&&self.field_shuffle_seed];
::core::fmt::Formatter::debug_struct_fields_finish(f, "ReprOptions",
names, values)
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for ReprOptions {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Option<IntegerType>>;
let _: ::core::cmp::AssertParamIsEq<Option<Align>>;
let _: ::core::cmp::AssertParamIsEq<Option<Align>>;
let _: ::core::cmp::AssertParamIsEq<ReprFlags>;
let _: ::core::cmp::AssertParamIsEq<Option<ScalableElt>>;
let _: ::core::cmp::AssertParamIsEq<Hash64>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for ReprOptions {
#[inline]
fn eq(&self, other: &ReprOptions) -> bool {
self.int == other.int && self.align == other.align &&
self.pack == other.pack && self.flags == other.flags &&
self.scalable == other.scalable &&
self.field_shuffle_seed == other.field_shuffle_seed
}
}PartialEq, #[automatically_derived]
impl ::core::default::Default for ReprOptions {
#[inline]
fn default() -> ReprOptions {
ReprOptions {
int: ::core::default::Default::default(),
align: ::core::default::Default::default(),
pack: ::core::default::Default::default(),
flags: ::core::default::Default::default(),
scalable: ::core::default::Default::default(),
field_shuffle_seed: ::core::default::Default::default(),
}
}
}Default)]
147#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for ReprOptions {
fn encode(&self, __encoder: &mut __E) {
match *self {
ReprOptions {
int: ref __binding_0,
align: ref __binding_1,
pack: ref __binding_2,
flags: ref __binding_3,
scalable: ref __binding_4,
field_shuffle_seed: ref __binding_5 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_5,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for ReprOptions {
fn decode(__decoder: &mut __D) -> Self {
ReprOptions {
int: ::rustc_serialize::Decodable::decode(__decoder),
align: ::rustc_serialize::Decodable::decode(__decoder),
pack: ::rustc_serialize::Decodable::decode(__decoder),
flags: ::rustc_serialize::Decodable::decode(__decoder),
scalable: ::rustc_serialize::Decodable::decode(__decoder),
field_shuffle_seed: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for ReprOptions
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
ReprOptions {
int: ref __binding_0,
align: ref __binding_1,
pack: ref __binding_2,
flags: ref __binding_3,
scalable: ref __binding_4,
field_shuffle_seed: ref __binding_5 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
{ __binding_5.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
148pub struct ReprOptions {
149 pub int: Option<IntegerType>,
150 pub align: Option<Align>,
151 pub pack: Option<Align>,
152 pub flags: ReprFlags,
153 pub scalable: Option<ScalableElt>,
155 pub field_shuffle_seed: Hash64,
163}
164
165impl ReprOptions {
166 #[inline]
167 pub fn simd(&self) -> bool {
168 self.flags.contains(ReprFlags::IS_SIMD)
169 }
170
171 #[inline]
172 pub fn scalable(&self) -> bool {
173 self.flags.contains(ReprFlags::IS_SCALABLE)
174 }
175
176 #[inline]
177 pub fn c(&self) -> bool {
178 self.flags.contains(ReprFlags::IS_C)
179 }
180
181 #[inline]
182 pub fn packed(&self) -> bool {
183 self.pack.is_some()
184 }
185
186 #[inline]
187 pub fn transparent(&self) -> bool {
188 self.flags.contains(ReprFlags::IS_TRANSPARENT)
189 }
190
191 #[inline]
192 pub fn linear(&self) -> bool {
193 self.flags.contains(ReprFlags::IS_LINEAR)
194 }
195
196 pub fn discr_type(&self) -> IntegerType {
204 self.int.unwrap_or(IntegerType::Pointer(true))
205 }
206
207 pub fn inhibit_enum_layout_opt(&self) -> bool {
211 self.c() || self.int.is_some()
212 }
213
214 pub fn inhibit_newtype_abi_optimization(&self) -> bool {
215 self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
216 }
217
218 pub fn inhibit_struct_field_reordering(&self) -> bool {
221 self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
222 }
223
224 pub fn can_randomize_type_layout(&self) -> bool {
227 !self.inhibit_struct_field_reordering() && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
228 }
229
230 pub fn inhibits_union_abi_opt(&self) -> bool {
232 self.c()
233 }
234}
235
236pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
242
243#[derive(#[automatically_derived]
impl ::core::marker::Copy for PointerSpec { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PointerSpec {
#[inline]
fn clone(&self) -> PointerSpec {
let _: ::core::clone::AssertParamIsClone<Size>;
let _: ::core::clone::AssertParamIsClone<Align>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PointerSpec {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "PointerSpec",
"pointer_size", &self.pointer_size, "pointer_align",
&self.pointer_align, "pointer_offset", &self.pointer_offset,
"_is_fat", &&self._is_fat)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PointerSpec {
#[inline]
fn eq(&self, other: &PointerSpec) -> bool {
self._is_fat == other._is_fat &&
self.pointer_size == other.pointer_size &&
self.pointer_align == other.pointer_align &&
self.pointer_offset == other.pointer_offset
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PointerSpec {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Size>;
let _: ::core::cmp::AssertParamIsEq<Align>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq)]
245pub struct PointerSpec {
246 pointer_size: Size,
248 pointer_align: Align,
250 pointer_offset: Size,
252 _is_fat: bool,
255}
256
257#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TargetDataLayout {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["endian", "i1_align", "i8_align", "i16_align", "i32_align",
"i64_align", "i128_align", "f16_align", "f32_align",
"f64_align", "f128_align", "aggregate_align",
"vector_align", "default_address_space",
"default_address_space_pointer_spec", "address_space_info",
"instruction_address_space", "c_enum_min_size"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.endian, &self.i1_align, &self.i8_align, &self.i16_align,
&self.i32_align, &self.i64_align, &self.i128_align,
&self.f16_align, &self.f32_align, &self.f64_align,
&self.f128_align, &self.aggregate_align, &self.vector_align,
&self.default_address_space,
&self.default_address_space_pointer_spec,
&self.address_space_info, &self.instruction_address_space,
&&self.c_enum_min_size];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"TargetDataLayout", names, values)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for TargetDataLayout {
#[inline]
fn eq(&self, other: &TargetDataLayout) -> bool {
self.endian == other.endian && self.i1_align == other.i1_align &&
self.i8_align == other.i8_align &&
self.i16_align == other.i16_align &&
self.i32_align == other.i32_align &&
self.i64_align == other.i64_align &&
self.i128_align == other.i128_align &&
self.f16_align == other.f16_align &&
self.f32_align == other.f32_align &&
self.f64_align == other.f64_align &&
self.f128_align == other.f128_align &&
self.aggregate_align == other.aggregate_align &&
self.vector_align == other.vector_align &&
self.default_address_space == other.default_address_space &&
self.default_address_space_pointer_spec ==
other.default_address_space_pointer_spec &&
self.address_space_info == other.address_space_info &&
self.instruction_address_space ==
other.instruction_address_space &&
self.c_enum_min_size == other.c_enum_min_size
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for TargetDataLayout {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Endian>;
let _: ::core::cmp::AssertParamIsEq<Align>;
let _: ::core::cmp::AssertParamIsEq<Vec<(Size, Align)>>;
let _: ::core::cmp::AssertParamIsEq<AddressSpace>;
let _: ::core::cmp::AssertParamIsEq<PointerSpec>;
let _: ::core::cmp::AssertParamIsEq<Vec<(AddressSpace, PointerSpec)>>;
let _: ::core::cmp::AssertParamIsEq<Integer>;
}
}Eq)]
260pub struct TargetDataLayout {
261 pub endian: Endian,
262 pub i1_align: Align,
263 pub i8_align: Align,
264 pub i16_align: Align,
265 pub i32_align: Align,
266 pub i64_align: Align,
267 pub i128_align: Align,
268 pub f16_align: Align,
269 pub f32_align: Align,
270 pub f64_align: Align,
271 pub f128_align: Align,
272 pub aggregate_align: Align,
273
274 pub vector_align: Vec<(Size, Align)>,
276
277 pub default_address_space: AddressSpace,
278 pub default_address_space_pointer_spec: PointerSpec,
279
280 address_space_info: Vec<(AddressSpace, PointerSpec)>,
287
288 pub instruction_address_space: AddressSpace,
289
290 pub c_enum_min_size: Integer,
294}
295
296impl Default for TargetDataLayout {
297 fn default() -> TargetDataLayout {
299 let align = |bits| Align::from_bits(bits).unwrap();
300 TargetDataLayout {
301 endian: Endian::Big,
302 i1_align: align(8),
303 i8_align: align(8),
304 i16_align: align(16),
305 i32_align: align(32),
306 i64_align: align(32),
307 i128_align: align(32),
308 f16_align: align(16),
309 f32_align: align(32),
310 f64_align: align(64),
311 f128_align: align(128),
312 aggregate_align: align(8),
313 vector_align: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(Size::from_bits(64), align(64)),
(Size::from_bits(128), align(128))]))vec![
314 (Size::from_bits(64), align(64)),
315 (Size::from_bits(128), align(128)),
316 ],
317 default_address_space: AddressSpace::ZERO,
318 default_address_space_pointer_spec: PointerSpec {
319 pointer_size: Size::from_bits(64),
320 pointer_align: align(64),
321 pointer_offset: Size::from_bits(64),
322 _is_fat: false,
323 },
324 address_space_info: ::alloc::vec::Vec::new()vec![],
325 instruction_address_space: AddressSpace::ZERO,
326 c_enum_min_size: Integer::I32,
327 }
328 }
329}
330
331pub enum TargetDataLayoutError<'a> {
332 InvalidAddressSpace { addr_space: &'a str, cause: &'a str, err: ParseIntError },
333 InvalidBits { kind: &'a str, bit: &'a str, cause: &'a str, err: ParseIntError },
334 MissingAlignment { cause: &'a str },
335 InvalidAlignment { cause: &'a str, err: AlignFromBytesError },
336 InconsistentTargetArchitecture { dl: &'a str, target: &'a str },
337 InconsistentTargetPointerWidth { pointer_size: u64, target: u16 },
338 InvalidBitsSize { err: String },
339 UnknownPointerSpecification { err: String },
340}
341
342#[cfg(feature = "nightly")]
343impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutError<'_> {
344 fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
345 match self {
346 TargetDataLayoutError::InvalidAddressSpace { addr_space, err, cause } => {
347 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
348 .with_arg("addr_space", addr_space)
349 .with_arg("cause", cause)
350 .with_arg("err", err)
351 }
352 TargetDataLayoutError::InvalidBits { kind, bit, cause, err } => {
353 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
354 .with_arg("kind", kind)
355 .with_arg("bit", bit)
356 .with_arg("cause", cause)
357 .with_arg("err", err)
358 }
359 TargetDataLayoutError::MissingAlignment { cause } => {
360 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("missing alignment for `{$cause}` in \"data-layout\""))msg!("missing alignment for `{$cause}` in \"data-layout\""))
361 .with_arg("cause", cause)
362 }
363 TargetDataLayoutError::InvalidAlignment { cause, err } => {
364 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))msg!("invalid alignment for `{$cause}` in \"data-layout\": {$err}"))
365 .with_arg("cause", cause)
366 .with_arg("err", err.to_string())
367 }
368 TargetDataLayoutError::InconsistentTargetArchitecture { dl, target } => {
369 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))msg!("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))
370 .with_arg("dl", dl).with_arg("target", target)
371 }
372 TargetDataLayoutError::InconsistentTargetPointerWidth { pointer_size, target } => {
373 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))msg!("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))
374 .with_arg("pointer_size", pointer_size).with_arg("target", target)
375 }
376 TargetDataLayoutError::InvalidBitsSize { err } => {
377 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$err}"))msg!("{$err}")).with_arg("err", err)
378 }
379 TargetDataLayoutError::UnknownPointerSpecification { err } => {
380 Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("unknown pointer specification `{$err}` in datalayout string"))msg!("unknown pointer specification `{$err}` in datalayout string"))
381 .with_arg("err", err)
382 }
383 }
384 }
385}
386
387impl TargetDataLayout {
388 pub fn parse_from_llvm_datalayout_string<'a>(
394 input: &'a str,
395 default_address_space: AddressSpace,
396 ) -> Result<TargetDataLayout, TargetDataLayoutError<'a>> {
397 let parse_address_space = |s: &'a str, cause: &'a str| {
399 s.parse::<u32>().map(AddressSpace).map_err(|err| {
400 TargetDataLayoutError::InvalidAddressSpace { addr_space: s, cause, err }
401 })
402 };
403
404 let parse_bits = |s: &'a str, kind: &'a str, cause: &'a str| {
406 s.parse::<u64>().map_err(|err| TargetDataLayoutError::InvalidBits {
407 kind,
408 bit: s,
409 cause,
410 err,
411 })
412 };
413
414 let parse_size =
416 |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
417
418 let parse_align_str = |s: &'a str, cause: &'a str| {
420 let align_from_bits = |bits| {
421 Align::from_bits(bits)
422 .map_err(|err| TargetDataLayoutError::InvalidAlignment { cause, err })
423 };
424 let abi = parse_bits(s, "alignment", cause)?;
425 Ok(align_from_bits(abi)?)
426 };
427
428 let parse_align_seq = |s: &[&'a str], cause: &'a str| {
431 if s.is_empty() {
432 return Err(TargetDataLayoutError::MissingAlignment { cause });
433 }
434 parse_align_str(s[0], cause)
435 };
436
437 let mut dl = TargetDataLayout::default();
438 dl.default_address_space = default_address_space;
439
440 let mut i128_align_src = 64;
441 for spec in input.split('-') {
442 let spec_parts = spec.split(':').collect::<Vec<_>>();
443
444 match &*spec_parts {
445 ["e"] => dl.endian = Endian::Little,
446 ["E"] => dl.endian = Endian::Big,
447 [p] if p.starts_with('P') => {
448 dl.instruction_address_space = parse_address_space(&p[1..], "P")?
449 }
450 ["a", a @ ..] => dl.aggregate_align = parse_align_seq(a, "a")?,
451 ["f16", a @ ..] => dl.f16_align = parse_align_seq(a, "f16")?,
452 ["f32", a @ ..] => dl.f32_align = parse_align_seq(a, "f32")?,
453 ["f64", a @ ..] => dl.f64_align = parse_align_seq(a, "f64")?,
454 ["f128", a @ ..] => dl.f128_align = parse_align_seq(a, "f128")?,
455 [p, s, a @ ..] if p.starts_with("p") => {
456 let mut p = p.strip_prefix('p').unwrap();
457 let mut _is_fat = false;
458
459 if p.starts_with('f') {
463 p = p.strip_prefix('f').unwrap();
464 _is_fat = true;
465 }
466
467 if p.starts_with(char::is_alphabetic) {
470 return Err(TargetDataLayoutError::UnknownPointerSpecification {
471 err: p.to_string(),
472 });
473 }
474
475 let addr_space = if !p.is_empty() {
476 parse_address_space(p, "p-")?
477 } else {
478 AddressSpace::ZERO
479 };
480
481 let pointer_size = parse_size(s, "p-")?;
482 let pointer_align = parse_align_seq(a, "p-")?;
483 let info = PointerSpec {
484 pointer_offset: pointer_size,
485 pointer_size,
486 pointer_align,
487 _is_fat,
488 };
489 if addr_space == default_address_space {
490 dl.default_address_space_pointer_spec = info;
491 } else {
492 match dl.address_space_info.iter_mut().find(|(a, _)| *a == addr_space) {
493 Some(e) => e.1 = info,
494 None => {
495 dl.address_space_info.push((addr_space, info));
496 }
497 }
498 }
499 }
500 [p, s, a, _pr, i] if p.starts_with("p") => {
501 let mut p = p.strip_prefix('p').unwrap();
502 let mut _is_fat = false;
503
504 if p.starts_with('f') {
508 p = p.strip_prefix('f').unwrap();
509 _is_fat = true;
510 }
511
512 if p.starts_with(char::is_alphabetic) {
515 return Err(TargetDataLayoutError::UnknownPointerSpecification {
516 err: p.to_string(),
517 });
518 }
519
520 let addr_space = if !p.is_empty() {
521 parse_address_space(p, "p")?
522 } else {
523 AddressSpace::ZERO
524 };
525
526 let info = PointerSpec {
527 pointer_size: parse_size(s, "p-")?,
528 pointer_align: parse_align_str(a, "p-")?,
529 pointer_offset: parse_size(i, "p-")?,
530 _is_fat,
531 };
532
533 if addr_space == default_address_space {
534 dl.default_address_space_pointer_spec = info;
535 } else {
536 match dl.address_space_info.iter_mut().find(|(a, _)| *a == addr_space) {
537 Some(e) => e.1 = info,
538 None => {
539 dl.address_space_info.push((addr_space, info));
540 }
541 }
542 }
543 }
544
545 [s, a @ ..] if s.starts_with('i') => {
546 let Ok(bits) = s[1..].parse::<u64>() else {
547 parse_size(&s[1..], "i")?; continue;
549 };
550 let a = parse_align_seq(a, s)?;
551 match bits {
552 1 => dl.i1_align = a,
553 8 => dl.i8_align = a,
554 16 => dl.i16_align = a,
555 32 => dl.i32_align = a,
556 64 => dl.i64_align = a,
557 _ => {}
558 }
559 if bits >= i128_align_src && bits <= 128 {
560 i128_align_src = bits;
563 dl.i128_align = a;
564 }
565 }
566 [s, a @ ..] if s.starts_with('v') => {
567 let v_size = parse_size(&s[1..], "v")?;
568 let a = parse_align_seq(a, s)?;
569 if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
570 v.1 = a;
571 continue;
572 }
573 dl.vector_align.push((v_size, a));
575 }
576 _ => {} }
578 }
579
580 if (dl.instruction_address_space != dl.default_address_space)
583 && dl
584 .address_space_info
585 .iter()
586 .find(|(a, _)| *a == dl.instruction_address_space)
587 .is_none()
588 {
589 dl.address_space_info.push((
590 dl.instruction_address_space,
591 dl.default_address_space_pointer_spec.clone(),
592 ));
593 }
594
595 Ok(dl)
596 }
597
598 #[inline]
609 pub fn obj_size_bound(&self) -> u64 {
610 match self.pointer_size().bits() {
611 16 => 1 << 15,
612 32 => 1 << 31,
613 64 => 1 << 61,
614 bits => {
::core::panicking::panic_fmt(format_args!("obj_size_bound: unknown pointer bit size {0}",
bits));
}panic!("obj_size_bound: unknown pointer bit size {bits}"),
615 }
616 }
617
618 #[inline]
628 pub fn obj_size_bound_in(&self, address_space: AddressSpace) -> u64 {
629 match self.pointer_size_in(address_space).bits() {
630 16 => 1 << 15,
631 32 => 1 << 31,
632 64 => 1 << 61,
633 bits => {
::core::panicking::panic_fmt(format_args!("obj_size_bound: unknown pointer bit size {0}",
bits));
}panic!("obj_size_bound: unknown pointer bit size {bits}"),
634 }
635 }
636
637 #[inline]
638 pub fn ptr_sized_integer(&self) -> Integer {
639 use Integer::*;
640 match self.pointer_offset().bits() {
641 16 => I16,
642 32 => I32,
643 64 => I64,
644 bits => {
::core::panicking::panic_fmt(format_args!("ptr_sized_integer: unknown pointer bit size {0}",
bits));
}panic!("ptr_sized_integer: unknown pointer bit size {bits}"),
645 }
646 }
647
648 #[inline]
649 pub fn ptr_sized_integer_in(&self, address_space: AddressSpace) -> Integer {
650 use Integer::*;
651 match self.pointer_offset_in(address_space).bits() {
652 16 => I16,
653 32 => I32,
654 64 => I64,
655 bits => {
::core::panicking::panic_fmt(format_args!("ptr_sized_integer: unknown pointer bit size {0}",
bits));
}panic!("ptr_sized_integer: unknown pointer bit size {bits}"),
656 }
657 }
658
659 #[inline]
661 fn c_vector_align(&self, vec_size: Size) -> Option<Align> {
662 self.vector_align
663 .iter()
664 .find(|(size, _align)| *size == vec_size)
665 .map(|(_size, align)| *align)
666 }
667
668 #[inline]
678 pub fn rust_vector_align(&self, vec_size: Size) -> Align {
679 self.c_vector_align(vec_size)
680 .unwrap_or(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap())
681 }
682
683 #[inline]
685 pub fn pointer_size(&self) -> Size {
686 self.default_address_space_pointer_spec.pointer_size
687 }
688
689 #[inline]
691 pub fn pointer_size_in(&self, c: AddressSpace) -> Size {
692 if c == self.default_address_space {
693 return self.default_address_space_pointer_spec.pointer_size;
694 }
695
696 if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
697 e.1.pointer_size
698 } else {
699 {
::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
c));
};panic!("Use of unknown address space {c:?}");
700 }
701 }
702
703 #[inline]
705 pub fn pointer_offset(&self) -> Size {
706 self.default_address_space_pointer_spec.pointer_offset
707 }
708
709 #[inline]
711 pub fn pointer_offset_in(&self, c: AddressSpace) -> Size {
712 if c == self.default_address_space {
713 return self.default_address_space_pointer_spec.pointer_offset;
714 }
715
716 if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
717 e.1.pointer_offset
718 } else {
719 {
::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
c));
};panic!("Use of unknown address space {c:?}");
720 }
721 }
722
723 #[inline]
725 pub fn pointer_align(&self) -> AbiAlign {
726 AbiAlign::new(self.default_address_space_pointer_spec.pointer_align)
727 }
728
729 #[inline]
731 pub fn pointer_align_in(&self, c: AddressSpace) -> AbiAlign {
732 AbiAlign::new(if c == self.default_address_space {
733 self.default_address_space_pointer_spec.pointer_align
734 } else if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) {
735 e.1.pointer_align
736 } else {
737 {
::core::panicking::panic_fmt(format_args!("Use of unknown address space {0:?}",
c));
};panic!("Use of unknown address space {c:?}");
738 })
739 }
740}
741
742pub trait HasDataLayout {
743 fn data_layout(&self) -> &TargetDataLayout;
744}
745
746impl HasDataLayout for TargetDataLayout {
747 #[inline]
748 fn data_layout(&self) -> &TargetDataLayout {
749 self
750 }
751}
752
753impl HasDataLayout for &TargetDataLayout {
755 #[inline]
756 fn data_layout(&self) -> &TargetDataLayout {
757 (**self).data_layout()
758 }
759}
760
761#[derive(#[automatically_derived]
impl ::core::marker::Copy for Endian { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Endian {
#[inline]
fn clone(&self) -> Endian { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Endian {
#[inline]
fn eq(&self, other: &Endian) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Endian {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq)]
763pub enum Endian {
764 Little,
765 Big,
766}
767
768impl Endian {
769 pub fn as_str(&self) -> &'static str {
770 match self {
771 Self::Little => "little",
772 Self::Big => "big",
773 }
774 }
775
776 #[cfg(feature = "nightly")]
777 pub fn desc_symbol(&self) -> Symbol {
778 match self {
779 Self::Little => sym::little,
780 Self::Big => sym::big,
781 }
782 }
783}
784
785impl fmt::Debug for Endian {
786 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787 f.write_str(self.as_str())
788 }
789}
790
791impl FromStr for Endian {
792 type Err = String;
793
794 fn from_str(s: &str) -> Result<Self, Self::Err> {
795 match s {
796 "little" => Ok(Self::Little),
797 "big" => Ok(Self::Big),
798 _ => Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown endian: \"{0}\"", s))
})format!(r#"unknown endian: "{s}""#)),
799 }
800 }
801}
802
803#[derive(#[automatically_derived]
impl ::core::marker::Copy for Size { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Size {
#[inline]
fn clone(&self) -> Size {
let _: ::core::clone::AssertParamIsClone<u64>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Size {
#[inline]
fn eq(&self, other: &Size) -> bool { self.raw == other.raw }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Size {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u64>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Size {
#[inline]
fn partial_cmp(&self, other: &Size)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Size {
#[inline]
fn cmp(&self, other: &Size) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.raw, &other.raw)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Size {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.raw, state)
}
}Hash, #[automatically_derived]
impl ::core::default::Default for Size {
#[inline]
fn default() -> Size { Size { raw: ::core::default::Default::default() } }
}Default)]
805#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for Size {
fn encode(&self, __encoder: &mut __E) {
match *self {
Size { raw: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for Size {
fn decode(__decoder: &mut __D) -> Self {
Size { raw: ::rustc_serialize::Decodable::decode(__decoder) }
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Size {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Size { raw: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
806pub struct Size {
807 raw: u64,
808}
809
810#[cfg(feature = "nightly")]
811impl StableOrd for Size {
812 const CAN_USE_UNSTABLE_SORT: bool = true;
813
814 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
817}
818
819impl fmt::Debug for Size {
821 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
822 f.write_fmt(format_args!("Size({0} bytes)", self.bytes()))write!(f, "Size({} bytes)", self.bytes())
823 }
824}
825
826impl Size {
827 pub const ZERO: Size = Size { raw: 0 };
828
829 pub fn from_bits(bits: impl TryInto<u64>) -> Size {
832 let bits = bits.try_into().ok().unwrap();
833 Size { raw: bits.div_ceil(8) }
834 }
835
836 #[inline]
837 pub fn from_bytes(bytes: impl TryInto<u64>) -> Size {
838 let bytes: u64 = bytes.try_into().ok().unwrap();
839 Size { raw: bytes }
840 }
841
842 #[inline]
843 pub fn bytes(self) -> u64 {
844 self.raw
845 }
846
847 #[inline]
848 pub fn bytes_usize(self) -> usize {
849 self.bytes().try_into().unwrap()
850 }
851
852 #[inline]
853 pub fn bits(self) -> u64 {
854 #[cold]
855 fn overflow(bytes: u64) -> ! {
856 {
::core::panicking::panic_fmt(format_args!("Size::bits: {0} bytes in bits doesn\'t fit in u64",
bytes));
}panic!("Size::bits: {bytes} bytes in bits doesn't fit in u64")
857 }
858
859 self.bytes().checked_mul(8).unwrap_or_else(|| overflow(self.bytes()))
860 }
861
862 #[inline]
863 pub fn bits_usize(self) -> usize {
864 self.bits().try_into().unwrap()
865 }
866
867 #[inline]
868 pub fn align_to(self, align: Align) -> Size {
869 let mask = align.bytes() - 1;
870 Size::from_bytes((self.bytes() + mask) & !mask)
871 }
872
873 #[inline]
874 pub fn is_aligned(self, align: Align) -> bool {
875 let mask = align.bytes() - 1;
876 self.bytes() & mask == 0
877 }
878
879 #[inline]
880 pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: &C) -> Option<Size> {
881 let dl = cx.data_layout();
882
883 let bytes = self.bytes().checked_add(offset.bytes())?;
884
885 if bytes < dl.obj_size_bound() { Some(Size::from_bytes(bytes)) } else { None }
886 }
887
888 #[inline]
889 pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: &C) -> Option<Size> {
890 let dl = cx.data_layout();
891
892 let bytes = self.bytes().checked_mul(count)?;
893 if bytes < dl.obj_size_bound() { Some(Size::from_bytes(bytes)) } else { None }
894 }
895
896 #[inline]
899 pub fn sign_extend(self, value: u128) -> i128 {
900 let size = self.bits();
901 if size == 0 {
902 return 0;
904 }
905 let shift = 128 - size;
907 ((value << shift) as i128) >> shift
910 }
911
912 #[inline]
914 pub fn truncate(self, value: u128) -> u128 {
915 let size = self.bits();
916 if size == 0 {
917 return 0;
919 }
920 let shift = 128 - size;
921 (value << shift) >> shift
923 }
924
925 #[inline]
926 pub fn signed_int_min(&self) -> i128 {
927 self.sign_extend(1_u128 << (self.bits() - 1))
928 }
929
930 #[inline]
931 pub fn signed_int_max(&self) -> i128 {
932 i128::MAX >> (128 - self.bits())
933 }
934
935 #[inline]
936 pub fn unsigned_int_max(&self) -> u128 {
937 u128::MAX >> (128 - self.bits())
938 }
939}
940
941impl Add for Size {
945 type Output = Size;
946 #[inline]
947 fn add(self, other: Size) -> Size {
948 Size::from_bytes(self.bytes().checked_add(other.bytes()).unwrap_or_else(|| {
949 {
::core::panicking::panic_fmt(format_args!("Size::add: {0} + {1} doesn\'t fit in u64",
self.bytes(), other.bytes()));
}panic!("Size::add: {} + {} doesn't fit in u64", self.bytes(), other.bytes())
950 }))
951 }
952}
953
954impl Sub for Size {
955 type Output = Size;
956 #[inline]
957 fn sub(self, other: Size) -> Size {
958 Size::from_bytes(self.bytes().checked_sub(other.bytes()).unwrap_or_else(|| {
959 {
::core::panicking::panic_fmt(format_args!("Size::sub: {0} - {1} would result in negative size",
self.bytes(), other.bytes()));
}panic!("Size::sub: {} - {} would result in negative size", self.bytes(), other.bytes())
960 }))
961 }
962}
963
964impl Mul<Size> for u64 {
965 type Output = Size;
966 #[inline]
967 fn mul(self, size: Size) -> Size {
968 size * self
969 }
970}
971
972impl Mul<u64> for Size {
973 type Output = Size;
974 #[inline]
975 fn mul(self, count: u64) -> Size {
976 match self.bytes().checked_mul(count) {
977 Some(bytes) => Size::from_bytes(bytes),
978 None => {
::core::panicking::panic_fmt(format_args!("Size::mul: {0} * {1} doesn\'t fit in u64",
self.bytes(), count));
}panic!("Size::mul: {} * {} doesn't fit in u64", self.bytes(), count),
979 }
980 }
981}
982
983impl AddAssign for Size {
984 #[inline]
985 fn add_assign(&mut self, other: Size) {
986 *self = *self + other;
987 }
988}
989
990#[cfg(feature = "nightly")]
991impl Step for Size {
992 #[inline]
993 fn steps_between(start: &Self, end: &Self) -> (usize, Option<usize>) {
994 u64::steps_between(&start.bytes(), &end.bytes())
995 }
996
997 #[inline]
998 fn forward_checked(start: Self, count: usize) -> Option<Self> {
999 u64::forward_checked(start.bytes(), count).map(Self::from_bytes)
1000 }
1001
1002 #[inline]
1003 #[cfg(not(bootstrap))]
1004 fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
1005 let (s, o) = u64::forward_overflowing(start.bytes(), count);
1006 (Self::from_bytes(s), o)
1007 }
1008
1009 #[inline]
1010 fn forward(start: Self, count: usize) -> Self {
1011 Self::from_bytes(u64::forward(start.bytes(), count))
1012 }
1013
1014 #[inline]
1015 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
1016 Self::from_bytes(unsafe { u64::forward_unchecked(start.bytes(), count) })
1017 }
1018
1019 #[inline]
1020 fn backward_checked(start: Self, count: usize) -> Option<Self> {
1021 u64::backward_checked(start.bytes(), count).map(Self::from_bytes)
1022 }
1023
1024 #[inline]
1025 #[cfg(not(bootstrap))]
1026 fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
1027 let (s, o) = u64::backward_overflowing(start.bytes(), count);
1028 (Self::from_bytes(s), o)
1029 }
1030
1031 #[inline]
1032 fn backward(start: Self, count: usize) -> Self {
1033 Self::from_bytes(u64::backward(start.bytes(), count))
1034 }
1035
1036 #[inline]
1037 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
1038 Self::from_bytes(unsafe { u64::backward_unchecked(start.bytes(), count) })
1039 }
1040}
1041
1042#[derive(#[automatically_derived]
impl ::core::marker::Copy for Align { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Align {
#[inline]
fn clone(&self) -> Align {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Align {
#[inline]
fn eq(&self, other: &Align) -> bool { self.pow2 == other.pow2 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Align {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Align {
#[inline]
fn partial_cmp(&self, other: &Align)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Align {
#[inline]
fn cmp(&self, other: &Align) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.pow2, &other.pow2)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Align {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.pow2, state)
}
}Hash)]
1044#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for Align {
fn encode(&self, __encoder: &mut __E) {
match *self {
Align { pow2: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for Align {
fn decode(__decoder: &mut __D) -> Self {
Align {
pow2: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Align {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Align { pow2: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1045pub struct Align {
1046 pow2: u8,
1047}
1048
1049impl fmt::Debug for Align {
1051 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1052 f.write_fmt(format_args!("Align({0} bytes)", self.bytes()))write!(f, "Align({} bytes)", self.bytes())
1053 }
1054}
1055
1056#[derive(#[automatically_derived]
impl ::core::clone::Clone for AlignFromBytesError {
#[inline]
fn clone(&self) -> AlignFromBytesError {
let _: ::core::clone::AssertParamIsClone<u64>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AlignFromBytesError { }Copy)]
1057pub enum AlignFromBytesError {
1058 NotPowerOfTwo(u64),
1059 TooLarge(u64),
1060}
1061
1062impl fmt::Debug for AlignFromBytesError {
1063 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1064 fmt::Display::fmt(self, f)
1065 }
1066}
1067
1068impl fmt::Display for AlignFromBytesError {
1069 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1070 match self {
1071 AlignFromBytesError::NotPowerOfTwo(align) => f.write_fmt(format_args!("{0} is not a power of 2", align))write!(f, "{align} is not a power of 2"),
1072 AlignFromBytesError::TooLarge(align) => f.write_fmt(format_args!("{0} is too large", align))write!(f, "{align} is too large"),
1073 }
1074 }
1075}
1076
1077impl Align {
1078 pub const ONE: Align = Align { pow2: 0 };
1079 pub const EIGHT: Align = Align { pow2: 3 };
1080 pub const MAX: Align = Align { pow2: 29 };
1082
1083 #[inline]
1085 pub fn max_for_target(tdl: &TargetDataLayout) -> Align {
1086 let pointer_bits = u8::try_from(tdl.pointer_size().bits()).unwrap();
1087 min(Align { pow2: pointer_bits - 1 }, Align::MAX)
1088 }
1089
1090 #[inline]
1091 pub fn from_bits(bits: u64) -> Result<Align, AlignFromBytesError> {
1092 Align::from_bytes(Size::from_bits(bits).bytes())
1093 }
1094
1095 #[inline]
1096 pub const fn from_bytes(align: u64) -> Result<Align, AlignFromBytesError> {
1097 if align == 0 {
1099 return Ok(Align::ONE);
1100 }
1101
1102 #[cold]
1103 const fn not_power_of_2(align: u64) -> AlignFromBytesError {
1104 AlignFromBytesError::NotPowerOfTwo(align)
1105 }
1106
1107 #[cold]
1108 const fn too_large(align: u64) -> AlignFromBytesError {
1109 AlignFromBytesError::TooLarge(align)
1110 }
1111
1112 let tz = align.trailing_zeros();
1113 if align != (1 << tz) {
1114 return Err(not_power_of_2(align));
1115 }
1116
1117 let pow2 = tz as u8;
1118 if pow2 > Self::MAX.pow2 {
1119 return Err(too_large(align));
1120 }
1121
1122 Ok(Align { pow2 })
1123 }
1124
1125 #[inline]
1126 pub const fn bytes(self) -> u64 {
1127 1 << self.pow2
1128 }
1129
1130 #[inline]
1131 pub fn bytes_usize(self) -> usize {
1132 self.bytes().try_into().unwrap()
1133 }
1134
1135 #[inline]
1136 pub const fn bits(self) -> u64 {
1137 self.bytes() * 8
1138 }
1139
1140 #[inline]
1141 pub fn bits_usize(self) -> usize {
1142 self.bits().try_into().unwrap()
1143 }
1144
1145 #[inline]
1150 pub fn max_aligned_factor(size: Size) -> Align {
1151 Align { pow2: size.bytes().trailing_zeros() as u8 }
1152 }
1153
1154 #[inline]
1156 pub fn restrict_for_offset(self, size: Size) -> Align {
1157 self.min(Align::max_aligned_factor(size))
1158 }
1159}
1160
1161#[derive(#[automatically_derived]
impl ::core::marker::Copy for AbiAlign { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AbiAlign {
#[inline]
fn clone(&self) -> AbiAlign {
let _: ::core::clone::AssertParamIsClone<Align>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AbiAlign {
#[inline]
fn eq(&self, other: &AbiAlign) -> bool { self.abi == other.abi }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AbiAlign {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Align>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for AbiAlign {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.abi, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AbiAlign {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "AbiAlign",
"abi", &&self.abi)
}
}Debug)]
1171#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for AbiAlign {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
AbiAlign { abi: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1172pub struct AbiAlign {
1173 pub abi: Align,
1174}
1175
1176impl AbiAlign {
1177 #[inline]
1178 pub fn new(align: Align) -> AbiAlign {
1179 AbiAlign { abi: align }
1180 }
1181
1182 #[inline]
1183 pub fn min(self, other: AbiAlign) -> AbiAlign {
1184 AbiAlign { abi: self.abi.min(other.abi) }
1185 }
1186
1187 #[inline]
1188 pub fn max(self, other: AbiAlign) -> AbiAlign {
1189 AbiAlign { abi: self.abi.max(other.abi) }
1190 }
1191}
1192
1193impl Deref for AbiAlign {
1194 type Target = Align;
1195
1196 fn deref(&self) -> &Self::Target {
1197 &self.abi
1198 }
1199}
1200
1201#[derive(#[automatically_derived]
impl ::core::marker::Copy for Integer { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Integer {
#[inline]
fn clone(&self) -> Integer { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Integer {
#[inline]
fn eq(&self, other: &Integer) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Integer {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Integer {
#[inline]
fn partial_cmp(&self, other: &Integer)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Integer {
#[inline]
fn cmp(&self, other: &Integer) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Integer {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Integer {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Integer::I8 => "I8",
Integer::I16 => "I16",
Integer::I32 => "I32",
Integer::I64 => "I64",
Integer::I128 => "I128",
})
}
}Debug)]
1203#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for Integer {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Integer::I8 => { 0usize }
Integer::I16 => { 1usize }
Integer::I32 => { 2usize }
Integer::I64 => { 3usize }
Integer::I128 => { 4usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Integer::I8 => {}
Integer::I16 => {}
Integer::I32 => {}
Integer::I64 => {}
Integer::I128 => {}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for Integer {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Integer::I8 }
1usize => { Integer::I16 }
2usize => { Integer::I32 }
3usize => { Integer::I64 }
4usize => { Integer::I128 }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Integer`, expected 0..5, actual {0}",
n));
}
}
}
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Integer {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Integer::I8 => {}
Integer::I16 => {}
Integer::I32 => {}
Integer::I64 => {}
Integer::I128 => {}
}
}
}
};StableHash))]
1204pub enum Integer {
1205 I8,
1206 I16,
1207 I32,
1208 I64,
1209 I128,
1210}
1211
1212impl Integer {
1213 pub fn int_ty_str(self) -> &'static str {
1214 use Integer::*;
1215 match self {
1216 I8 => "i8",
1217 I16 => "i16",
1218 I32 => "i32",
1219 I64 => "i64",
1220 I128 => "i128",
1221 }
1222 }
1223
1224 pub fn uint_ty_str(self) -> &'static str {
1225 use Integer::*;
1226 match self {
1227 I8 => "u8",
1228 I16 => "u16",
1229 I32 => "u32",
1230 I64 => "u64",
1231 I128 => "u128",
1232 }
1233 }
1234
1235 #[inline]
1236 pub fn size(self) -> Size {
1237 use Integer::*;
1238 match self {
1239 I8 => Size::from_bytes(1),
1240 I16 => Size::from_bytes(2),
1241 I32 => Size::from_bytes(4),
1242 I64 => Size::from_bytes(8),
1243 I128 => Size::from_bytes(16),
1244 }
1245 }
1246
1247 pub fn from_attr<C: HasDataLayout>(cx: &C, ity: IntegerType) -> Integer {
1249 let dl = cx.data_layout();
1250
1251 match ity {
1252 IntegerType::Pointer(_) => dl.ptr_sized_integer(),
1253 IntegerType::Fixed(x, _) => x,
1254 }
1255 }
1256
1257 pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1258 use Integer::*;
1259 let dl = cx.data_layout();
1260
1261 AbiAlign::new(match self {
1262 I8 => dl.i8_align,
1263 I16 => dl.i16_align,
1264 I32 => dl.i32_align,
1265 I64 => dl.i64_align,
1266 I128 => dl.i128_align,
1267 })
1268 }
1269
1270 #[inline]
1272 pub fn signed_max(self) -> i128 {
1273 use Integer::*;
1274 match self {
1275 I8 => i8::MAX as i128,
1276 I16 => i16::MAX as i128,
1277 I32 => i32::MAX as i128,
1278 I64 => i64::MAX as i128,
1279 I128 => i128::MAX,
1280 }
1281 }
1282
1283 #[inline]
1285 pub fn signed_min(self) -> i128 {
1286 use Integer::*;
1287 match self {
1288 I8 => i8::MIN as i128,
1289 I16 => i16::MIN as i128,
1290 I32 => i32::MIN as i128,
1291 I64 => i64::MIN as i128,
1292 I128 => i128::MIN,
1293 }
1294 }
1295
1296 #[inline]
1298 pub fn fit_signed(x: i128) -> Integer {
1299 use Integer::*;
1300 match x {
1301 -0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8,
1302 -0x0000_0000_0000_8000..=0x0000_0000_0000_7fff => I16,
1303 -0x0000_0000_8000_0000..=0x0000_0000_7fff_ffff => I32,
1304 -0x8000_0000_0000_0000..=0x7fff_ffff_ffff_ffff => I64,
1305 _ => I128,
1306 }
1307 }
1308
1309 #[inline]
1311 pub fn fit_unsigned(x: u128) -> Integer {
1312 use Integer::*;
1313 match x {
1314 0..=0x0000_0000_0000_00ff => I8,
1315 0..=0x0000_0000_0000_ffff => I16,
1316 0..=0x0000_0000_ffff_ffff => I32,
1317 0..=0xffff_ffff_ffff_ffff => I64,
1318 _ => I128,
1319 }
1320 }
1321
1322 pub fn for_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Option<Integer> {
1324 use Integer::*;
1325 let dl = cx.data_layout();
1326
1327 [I8, I16, I32, I64, I128].into_iter().find(|&candidate| {
1328 wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes()
1329 })
1330 }
1331
1332 pub fn approximate_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Integer {
1334 use Integer::*;
1335 let dl = cx.data_layout();
1336
1337 for candidate in [I64, I32, I16] {
1339 if wanted >= candidate.align(dl).abi && wanted.bytes() >= candidate.size().bytes() {
1340 return candidate;
1341 }
1342 }
1343 I8
1344 }
1345
1346 #[inline]
1349 pub fn from_size(size: Size) -> Result<Self, String> {
1350 match size.bits() {
1351 8 => Ok(Integer::I8),
1352 16 => Ok(Integer::I16),
1353 32 => Ok(Integer::I32),
1354 64 => Ok(Integer::I64),
1355 128 => Ok(Integer::I128),
1356 _ => Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("rust does not support integers with {0} bits",
size.bits()))
})format!("rust does not support integers with {} bits", size.bits())),
1357 }
1358 }
1359}
1360
1361#[derive(#[automatically_derived]
impl ::core::marker::Copy for Float { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Float {
#[inline]
fn clone(&self) -> Float { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Float {
#[inline]
fn eq(&self, other: &Float) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Float {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Float {
#[inline]
fn partial_cmp(&self, other: &Float)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Float {
#[inline]
fn cmp(&self, other: &Float) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Float {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Float {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Float::F16 => "F16",
Float::F32 => "F32",
Float::F64 => "F64",
Float::F128 => "F128",
})
}
}Debug)]
1363#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Float {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Float::F16 => {}
Float::F32 => {}
Float::F64 => {}
Float::F128 => {}
}
}
}
};StableHash))]
1364pub enum Float {
1365 F16,
1366 F32,
1367 F64,
1368 F128,
1369}
1370
1371impl Float {
1372 pub fn size(self) -> Size {
1373 use Float::*;
1374
1375 match self {
1376 F16 => Size::from_bits(16),
1377 F32 => Size::from_bits(32),
1378 F64 => Size::from_bits(64),
1379 F128 => Size::from_bits(128),
1380 }
1381 }
1382
1383 pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1384 use Float::*;
1385 let dl = cx.data_layout();
1386
1387 AbiAlign::new(match self {
1388 F16 => dl.f16_align,
1389 F32 => dl.f32_align,
1390 F64 => dl.f64_align,
1391 F128 => dl.f128_align,
1392 })
1393 }
1394
1395 pub fn ty_str(self) -> &'static str {
1396 use Float::*;
1397
1398 match self {
1399 F16 => "f16",
1400 F32 => "f32",
1401 F64 => "f64",
1402 F128 => "f128",
1403 }
1404 }
1405}
1406
1407#[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)]
1409#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Primitive {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Primitive::Int(ref __binding_0, ref __binding_1) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
Primitive::Float(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
Primitive::Pointer(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1410pub enum Primitive {
1411 Int(Integer, bool),
1419 Float(Float),
1420 Pointer(AddressSpace),
1421}
1422
1423impl fmt::Debug for Primitive {
1424 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1425 let name = match *self {
1426 Primitive::Int(integer, is_signed) => {
1427 if is_signed {
1428 integer.int_ty_str()
1429 } else {
1430 integer.uint_ty_str()
1431 }
1432 }
1433 Primitive::Float(float) => float.ty_str(),
1434 Primitive::Pointer(addr_space) => {
1435 if addr_space == AddressSpace::ZERO {
1436 "pointer"
1437 } else {
1438 return f.write_fmt(format_args!("pointer({0:?})", addr_space))write!(f, "pointer({addr_space:?})");
1439 }
1440 }
1441 };
1442 f.write_str(name)
1443 }
1444}
1445
1446impl Primitive {
1447 pub fn size<C: HasDataLayout>(self, cx: &C) -> Size {
1448 use Primitive::*;
1449 let dl = cx.data_layout();
1450
1451 match self {
1452 Int(i, _) => i.size(),
1453 Float(f) => f.size(),
1454 Pointer(a) => dl.pointer_size_in(a),
1455 }
1456 }
1457
1458 pub fn default_align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
1463 use Primitive::*;
1464 let dl = cx.data_layout();
1465
1466 match self {
1467 Int(i, _) => i.align(dl),
1468 Float(f) => f.align(dl),
1469 Pointer(a) => dl.pointer_align_in(a),
1470 }
1471 }
1472}
1473
1474#[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)]
1484#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
WrappingRange {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
WrappingRange { start: ref __binding_0, end: ref __binding_1
} => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1485pub struct WrappingRange {
1486 pub start: u128,
1487 pub end: u128,
1488}
1489
1490impl WrappingRange {
1491 fn debug_as(&self, size: Size, is_signed: bool) -> impl fmt::Debug {
1492 let range = *self;
1493 fmt::from_fn(move |f| {
1494 if range == WrappingRange::full(size) {
1495 f.write_str("..")
1503 } else if is_signed {
1504 let start = size.sign_extend(range.start);
1505 let end = size.sign_extend(range.end);
1506 if start > end {
1507 f.write_fmt(format_args!("(..={0}) | ({1}..)", end, start))write!(f, "(..={}) | ({}..)", end, start)
1508 } else {
1509 f.write_fmt(format_args!("{0}..={1}", start, end))write!(f, "{}..={}", start, end)
1510 }
1511 } else {
1512 f.write_fmt(format_args!("{0:?}", range))write!(f, "{:?}", range)
1513 }
1514 })
1515 }
1516
1517 pub fn full(size: Size) -> Self {
1518 Self { start: 0, end: size.unsigned_int_max() }
1519 }
1520
1521 #[inline(always)]
1523 pub fn contains(&self, v: u128) -> bool {
1524 if self.start <= self.end {
1525 self.start <= v && v <= self.end
1526 } else {
1527 self.start <= v || v <= self.end
1528 }
1529 }
1530
1531 #[inline(always)]
1534 pub fn contains_range(&self, other: Self, size: Size) -> bool {
1535 if self.is_full_for(size) {
1536 true
1537 } else {
1538 let trunc = |x| size.truncate(x);
1539
1540 let delta = self.start;
1541 let max = trunc(self.end.wrapping_sub(delta));
1542
1543 let other_start = trunc(other.start.wrapping_sub(delta));
1544 let other_end = trunc(other.end.wrapping_sub(delta));
1545
1546 (other_start <= other_end) && (other_end <= max)
1550 }
1551 }
1552
1553 #[inline(always)]
1555 fn with_start(mut self, start: u128) -> Self {
1556 self.start = start;
1557 self
1558 }
1559
1560 #[inline(always)]
1562 fn with_end(mut self, end: u128) -> Self {
1563 self.end = end;
1564 self
1565 }
1566
1567 #[inline]
1573 fn is_full_for(&self, size: Size) -> bool {
1574 let max_value = size.unsigned_int_max();
1575 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);
1576 self.start == (self.end.wrapping_add(1) & max_value)
1577 }
1578
1579 #[inline]
1585 pub fn no_unsigned_wraparound(&self, size: Size) -> Result<bool, RangeFull> {
1586 if self.is_full_for(size) { Err(..) } else { Ok(self.start <= self.end) }
1587 }
1588
1589 #[inline]
1598 pub fn no_signed_wraparound(&self, size: Size) -> Result<bool, RangeFull> {
1599 if self.is_full_for(size) {
1600 Err(..)
1601 } else {
1602 let start: i128 = size.sign_extend(self.start);
1603 let end: i128 = size.sign_extend(self.end);
1604 Ok(start <= end)
1605 }
1606 }
1607}
1608
1609impl fmt::Debug for WrappingRange {
1610 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1611 if self.start > self.end {
1612 fmt.write_fmt(format_args!("(..={0}) | ({1}..)", self.end, self.start))write!(fmt, "(..={}) | ({}..)", self.end, self.start)?;
1613 } else {
1614 fmt.write_fmt(format_args!("{0}..={1}", self.start, self.end))write!(fmt, "{}..={}", self.start, self.end)?;
1615 }
1616 Ok(())
1617 }
1618}
1619
1620#[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)]
1622#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Scalar {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Scalar::Initialized {
value: ref __binding_0, valid_range: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
Scalar::Union { value: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1623pub enum Scalar {
1624 Initialized {
1625 value: Primitive,
1626
1627 valid_range: WrappingRange,
1631 },
1632 Union {
1633 value: Primitive,
1639 },
1640}
1641
1642impl fmt::Debug for Scalar {
1643 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1644 match self {
1645 Scalar::Initialized { value, valid_range } => {
1646 let (size, is_signed) = match *value {
1647 Primitive::Int(integer, is_signed) => (integer.size(), is_signed),
1648 Primitive::Float(float) => (float.size(), false),
1649 Primitive::Pointer(_) => (Size::from_bits(128), false),
1650 };
1651 f.write_fmt(format_args!("{1:?} is {0:?}",
valid_range.debug_as(size, is_signed), value))write!(f, "{value:?} is {:?}", valid_range.debug_as(size, is_signed))
1652 }
1653 Scalar::Union { value } => {
1654 f.write_fmt(format_args!("union {0:?}", value))write!(f, "union {value:?}")
1655 }
1656 }
1657 }
1658}
1659
1660impl Scalar {
1661 #[inline]
1662 pub fn is_bool(&self) -> bool {
1663 use Integer::*;
1664 #[allow(non_exhaustive_omitted_patterns)] match self {
Scalar::Initialized {
value: Primitive::Int(I8, false),
valid_range: WrappingRange { start: 0, end: 1 } } => true,
_ => false,
}matches!(
1665 self,
1666 Scalar::Initialized {
1667 value: Primitive::Int(I8, false),
1668 valid_range: WrappingRange { start: 0, end: 1 }
1669 }
1670 )
1671 }
1672
1673 pub fn primitive(&self) -> Primitive {
1676 match *self {
1677 Scalar::Initialized { value, .. } | Scalar::Union { value } => value,
1678 }
1679 }
1680
1681 pub fn default_align(self, cx: &impl HasDataLayout) -> AbiAlign {
1686 self.primitive().default_align(cx)
1687 }
1688
1689 pub fn size(self, cx: &impl HasDataLayout) -> Size {
1690 self.primitive().size(cx)
1691 }
1692
1693 #[inline]
1694 pub fn to_union(&self) -> Self {
1695 Self::Union { value: self.primitive() }
1696 }
1697
1698 #[inline]
1699 pub fn valid_range(&self, cx: &impl HasDataLayout) -> WrappingRange {
1700 match *self {
1701 Scalar::Initialized { valid_range, .. } => valid_range,
1702 Scalar::Union { value } => WrappingRange::full(value.size(cx)),
1703 }
1704 }
1705
1706 #[inline]
1707 pub fn valid_range_mut(&mut self) -> &mut WrappingRange {
1710 match self {
1711 Scalar::Initialized { valid_range, .. } => valid_range,
1712 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"),
1713 }
1714 }
1715
1716 #[inline]
1719 pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
1720 match *self {
1721 Scalar::Initialized { valid_range, .. } => valid_range.is_full_for(self.size(cx)),
1722 Scalar::Union { .. } => true,
1723 }
1724 }
1725
1726 #[inline]
1728 pub fn is_uninit_valid(&self) -> bool {
1729 match *self {
1730 Scalar::Initialized { .. } => false,
1731 Scalar::Union { .. } => true,
1732 }
1733 }
1734
1735 #[inline]
1737 pub fn is_signed(&self) -> bool {
1738 match self.primitive() {
1739 Primitive::Int(_, signed) => signed,
1740 _ => false,
1741 }
1742 }
1743}
1744
1745#[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)]
1748#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<FieldIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
for FieldsShape<FieldIdx> where
FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
FieldsShape::Primitive => {}
FieldsShape::Union(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
FieldsShape::Array {
stride: ref __binding_0, count: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
FieldsShape::Arbitrary {
offsets: ref __binding_0, in_memory_order: ref __binding_1 }
=> {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1749pub enum FieldsShape<FieldIdx: Idx> {
1750 Primitive,
1752
1753 Union(NonZeroUsize),
1755
1756 Array { stride: Size, count: u64 },
1758
1759 Arbitrary {
1767 offsets: IndexVec<FieldIdx, Size>,
1772
1773 in_memory_order: IndexVec<u32, FieldIdx>,
1781 },
1782}
1783
1784impl<FieldIdx: Idx> FieldsShape<FieldIdx> {
1785 #[inline]
1786 pub fn count(&self) -> usize {
1787 match *self {
1788 FieldsShape::Primitive => 0,
1789 FieldsShape::Union(count) => count.get(),
1790 FieldsShape::Array { count, .. } => count.try_into().unwrap(),
1791 FieldsShape::Arbitrary { ref offsets, .. } => offsets.len(),
1792 }
1793 }
1794
1795 #[inline]
1796 pub fn offset(&self, i: usize) -> Size {
1797 match *self {
1798 FieldsShape::Primitive => {
1799 {
::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")
1800 }
1801 FieldsShape::Union(count) => {
1802 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");
1803 Size::ZERO
1804 }
1805 FieldsShape::Array { stride, count } => {
1806 let i = u64::try_from(i).unwrap();
1807 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");
1808 stride * i
1809 }
1810 FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::new(i)],
1811 }
1812 }
1813
1814 #[inline]
1816 pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator<Item = usize> {
1817 let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() };
1821
1822 (0..pseudofield_count).map(move |i| match self {
1823 FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
1824 FieldsShape::Arbitrary { in_memory_order, .. } => in_memory_order[i as u32].index(),
1825 })
1826 }
1827}
1828
1829#[derive(#[automatically_derived]
impl ::core::marker::Copy for AddressSpace { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AddressSpace {
#[inline]
fn clone(&self) -> AddressSpace {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AddressSpace {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "AddressSpace",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for AddressSpace {
#[inline]
fn eq(&self, other: &AddressSpace) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AddressSpace {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for AddressSpace {
#[inline]
fn partial_cmp(&self, other: &AddressSpace)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for AddressSpace {
#[inline]
fn cmp(&self, other: &AddressSpace) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for AddressSpace {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash)]
1833#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for AddressSpace
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
AddressSpace(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1834pub struct AddressSpace(pub u32);
1835
1836impl AddressSpace {
1837 pub const ZERO: Self = AddressSpace(0);
1839 pub const GPU_WORKGROUP: Self = AddressSpace(3);
1842}
1843
1844#[derive(#[automatically_derived]
impl ::core::clone::Clone for NumScalableVectors {
#[inline]
fn clone(&self) -> NumScalableVectors {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NumScalableVectors { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for NumScalableVectors {
#[inline]
fn eq(&self, other: &NumScalableVectors) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NumScalableVectors {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for NumScalableVectors {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for NumScalableVectors {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"NumScalableVectors", &&self.0)
}
}Debug)]
1846#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
NumScalableVectors {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
NumScalableVectors(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1847pub struct NumScalableVectors(pub u8);
1848
1849impl NumScalableVectors {
1850 pub fn for_non_tuple() -> Self {
1852 NumScalableVectors(1)
1853 }
1854
1855 pub fn from_field_count(count: usize) -> Option<Self> {
1859 match count {
1860 2..8 => Some(NumScalableVectors(count as u8)),
1861 _ => None,
1862 }
1863 }
1864}
1865
1866#[cfg(feature = "nightly")]
1867impl IntoDiagArg for NumScalableVectors {
1868 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1869 DiagArgValue::Str(std::borrow::Cow::Borrowed(match self.0 {
1870 0 => {
::core::panicking::panic_fmt(format_args!("`NumScalableVectors(0)` is illformed"));
}panic!("`NumScalableVectors(0)` is illformed"),
1871 1 => "one",
1872 2 => "two",
1873 3 => "three",
1874 4 => "four",
1875 5 => "five",
1876 6 => "six",
1877 7 => "seven",
1878 8 => "eight",
1879 _ => {
::core::panicking::panic_fmt(format_args!("`NumScalableVectors(N)` for N>8 is illformed"));
}panic!("`NumScalableVectors(N)` for N>8 is illformed"),
1880 }))
1881 }
1882}
1883
1884#[derive(#[automatically_derived]
impl ::core::clone::Clone for BackendRepr {
#[inline]
fn clone(&self) -> BackendRepr {
let _: ::core::clone::AssertParamIsClone<Scalar>;
let _: ::core::clone::AssertParamIsClone<Size>;
let _: ::core::clone::AssertParamIsClone<u64>;
let _: ::core::clone::AssertParamIsClone<NumScalableVectors>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BackendRepr { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for BackendRepr {
#[inline]
fn eq(&self, other: &BackendRepr) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(BackendRepr::Scalar(__self_0), BackendRepr::Scalar(__arg1_0))
=> __self_0 == __arg1_0,
(BackendRepr::ScalarPair {
a: __self_0, b: __self_1, b_offset: __self_2 },
BackendRepr::ScalarPair {
a: __arg1_0, b: __arg1_1, b_offset: __arg1_2 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1 &&
__self_2 == __arg1_2,
(BackendRepr::SimdScalableVector {
element: __self_0,
count: __self_1,
number_of_vectors: __self_2 },
BackendRepr::SimdScalableVector {
element: __arg1_0,
count: __arg1_1,
number_of_vectors: __arg1_2 }) =>
__self_1 == __arg1_1 && __self_0 == __arg1_0 &&
__self_2 == __arg1_2,
(BackendRepr::SimdVector { element: __self_0, count: __self_1
}, BackendRepr::SimdVector {
element: __arg1_0, count: __arg1_1 }) =>
__self_1 == __arg1_1 && __self_0 == __arg1_0,
(BackendRepr::Memory { sized: __self_0 },
BackendRepr::Memory { sized: __arg1_0 }) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BackendRepr {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Scalar>;
let _: ::core::cmp::AssertParamIsEq<Size>;
let _: ::core::cmp::AssertParamIsEq<u64>;
let _: ::core::cmp::AssertParamIsEq<NumScalableVectors>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for BackendRepr {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
BackendRepr::Scalar(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
BackendRepr::ScalarPair {
a: __self_0, b: __self_1, b_offset: __self_2 } => {
::core::hash::Hash::hash(__self_0, state);
::core::hash::Hash::hash(__self_1, state);
::core::hash::Hash::hash(__self_2, state)
}
BackendRepr::SimdScalableVector {
element: __self_0,
count: __self_1,
number_of_vectors: __self_2 } => {
::core::hash::Hash::hash(__self_0, state);
::core::hash::Hash::hash(__self_1, state);
::core::hash::Hash::hash(__self_2, state)
}
BackendRepr::SimdVector { element: __self_0, count: __self_1 } =>
{
::core::hash::Hash::hash(__self_0, state);
::core::hash::Hash::hash(__self_1, state)
}
BackendRepr::Memory { sized: __self_0 } =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for BackendRepr {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
BackendRepr::Scalar(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Scalar",
&__self_0),
BackendRepr::ScalarPair {
a: __self_0, b: __self_1, b_offset: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ScalarPair", "a", __self_0, "b", __self_1, "b_offset",
&__self_2),
BackendRepr::SimdScalableVector {
element: __self_0,
count: __self_1,
number_of_vectors: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"SimdScalableVector", "element", __self_0, "count",
__self_1, "number_of_vectors", &__self_2),
BackendRepr::SimdVector { element: __self_0, count: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"SimdVector", "element", __self_0, "count", &__self_1),
BackendRepr::Memory { sized: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Memory", "sized", &__self_0),
}
}
}Debug)]
1895#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for BackendRepr
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
BackendRepr::Scalar(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
BackendRepr::ScalarPair {
a: ref __binding_0,
b: ref __binding_1,
b_offset: ref __binding_2 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
}
BackendRepr::SimdScalableVector {
element: ref __binding_0,
count: ref __binding_1,
number_of_vectors: ref __binding_2 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
}
BackendRepr::SimdVector {
element: ref __binding_0, count: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
BackendRepr::Memory { sized: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
1896pub enum BackendRepr {
1897 Scalar(Scalar),
1898 ScalarPair {
1907 a: Scalar,
1908 b: Scalar,
1909 b_offset: Size,
1910 },
1911 SimdScalableVector {
1912 element: Scalar,
1913 count: u64,
1914 number_of_vectors: NumScalableVectors,
1915 },
1916 SimdVector {
1917 element: Scalar,
1918 count: u64,
1919 },
1920 Memory {
1922 sized: bool,
1924 },
1925}
1926
1927impl BackendRepr {
1928 #[inline]
1930 pub fn is_unsized(&self) -> bool {
1931 match *self {
1932 BackendRepr::Scalar(_)
1933 | BackendRepr::ScalarPair { .. }
1934 | BackendRepr::SimdScalableVector { .. }
1940 | BackendRepr::SimdVector { .. } => false,
1941 BackendRepr::Memory { sized } => !sized,
1942 }
1943 }
1944
1945 #[inline]
1946 pub fn is_sized(&self) -> bool {
1947 !self.is_unsized()
1948 }
1949
1950 #[inline]
1953 pub fn is_signed(&self) -> bool {
1954 match self {
1955 BackendRepr::Scalar(scal) => scal.is_signed(),
1956 _ => {
::core::panicking::panic_fmt(format_args!("`is_signed` on non-scalar ABI {0:?}",
self));
}panic!("`is_signed` on non-scalar ABI {self:?}"),
1957 }
1958 }
1959
1960 #[inline]
1964 pub fn is_scalar(&self) -> bool {
1965 #[allow(non_exhaustive_omitted_patterns)] match *self {
BackendRepr::Scalar(_) => true,
_ => false,
}matches!(*self, BackendRepr::Scalar(_))
1966 }
1967
1968 #[inline]
1970 pub fn is_scalar_or_simd(&self) -> bool {
1971 #[allow(non_exhaustive_omitted_patterns)] match *self {
BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } |
BackendRepr::SimdScalableVector { .. } => true,
_ => false,
}matches!(
1972 *self,
1973 BackendRepr::Scalar(_)
1974 | BackendRepr::SimdVector { .. }
1975 | BackendRepr::SimdScalableVector { .. }
1976 )
1977 }
1978
1979 #[inline]
1981 pub fn is_bool(&self) -> bool {
1982 #[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())
1983 }
1984
1985 pub fn scalar_platform_align<C: HasDataLayout>(&self, cx: &C) -> Option<Align> {
1993 match *self {
1994 BackendRepr::Scalar(s) => Some(s.default_align(cx).abi),
1995 BackendRepr::ScalarPair { a: s1, b: s2, b_offset: _ } => {
1996 Some(s1.default_align(cx).max(s2.default_align(cx)).abi)
1997 }
1998 BackendRepr::SimdVector { .. }
2000 | BackendRepr::Memory { .. }
2001 | BackendRepr::SimdScalableVector { .. } => None,
2002 }
2003 }
2004
2005 pub fn scalar_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
2009 match *self {
2010 BackendRepr::Scalar(s) => Some(s.size(cx)),
2012 BackendRepr::ScalarPair { a: _, b: s2, b_offset: field2_offset } => {
2014 let size = (field2_offset + s2.size(cx)).align_to(
2015 self.scalar_platform_align(cx)
2016 .unwrap(),
2018 );
2019 Some(size)
2020 }
2021 BackendRepr::SimdVector { .. }
2023 | BackendRepr::Memory { .. }
2024 | BackendRepr::SimdScalableVector { .. } => None,
2025 }
2026 }
2027
2028 pub fn to_union(&self) -> Self {
2030 match *self {
2031 BackendRepr::Scalar(s) => BackendRepr::Scalar(s.to_union()),
2032 BackendRepr::ScalarPair { a: s1, b: s2, b_offset } => {
2033 BackendRepr::ScalarPair { a: s1.to_union(), b: s2.to_union(), b_offset }
2034 }
2035 BackendRepr::SimdVector { element, count } => {
2036 BackendRepr::SimdVector { element: element.to_union(), count }
2037 }
2038 BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true },
2039 BackendRepr::SimdScalableVector { element, count, number_of_vectors } => {
2040 BackendRepr::SimdScalableVector {
2041 element: element.to_union(),
2042 count,
2043 number_of_vectors,
2044 }
2045 }
2046 }
2047 }
2048
2049 pub fn eq_up_to_validity(&self, other: &Self) -> bool {
2050 match (self, other) {
2051 (BackendRepr::Scalar(l), BackendRepr::Scalar(r)) => l.primitive() == r.primitive(),
2054 (
2055 BackendRepr::SimdVector { element: element_l, count: count_l },
2056 BackendRepr::SimdVector { element: element_r, count: count_r },
2057 ) => element_l.primitive() == element_r.primitive() && count_l == count_r,
2058 (
2059 BackendRepr::ScalarPair { a: l1, b: l2, b_offset: l_offset },
2060 BackendRepr::ScalarPair { a: r1, b: r2, b_offset: r_offset },
2061 ) => {
2062 l1.primitive() == r1.primitive()
2063 && l2.primitive() == r2.primitive()
2064 && l_offset == r_offset
2065 }
2066 _ => self == other,
2068 }
2069 }
2070}
2071
2072#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx,
VariantIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
Variants<FieldIdx, VariantIdx> {
#[inline]
fn eq(&self, other: &Variants<FieldIdx, VariantIdx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Variants::Single { index: __self_0 }, Variants::Single {
index: __arg1_0 }) => __self_0 == __arg1_0,
(Variants::Multiple {
tag: __self_0,
tag_encoding: __self_1,
tag_field: __self_2,
variants: __self_3 }, Variants::Multiple {
tag: __arg1_0,
tag_encoding: __arg1_1,
tag_field: __arg1_2,
variants: __arg1_3 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1 &&
__self_2 == __arg1_2 && __self_3 == __arg1_3,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx, VariantIdx: ::core::cmp::Eq + Idx>
::core::cmp::Eq for Variants<FieldIdx, VariantIdx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
let _: ::core::cmp::AssertParamIsEq<Scalar>;
let _: ::core::cmp::AssertParamIsEq<TagEncoding<VariantIdx>>;
let _: ::core::cmp::AssertParamIsEq<FieldIdx>;
let _:
::core::cmp::AssertParamIsEq<IndexVec<VariantIdx,
VariantLayout<FieldIdx>>>;
}
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx, VariantIdx: ::core::hash::Hash + Idx>
::core::hash::Hash for Variants<FieldIdx, VariantIdx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Variants::Single { index: __self_0 } =>
::core::hash::Hash::hash(__self_0, state),
Variants::Multiple {
tag: __self_0,
tag_encoding: __self_1,
tag_field: __self_2,
variants: __self_3 } => {
::core::hash::Hash::hash(__self_0, state);
::core::hash::Hash::hash(__self_1, state);
::core::hash::Hash::hash(__self_2, state);
::core::hash::Hash::hash(__self_3, state)
}
_ => {}
}
}
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx, VariantIdx: ::core::clone::Clone +
Idx> ::core::clone::Clone for Variants<FieldIdx, VariantIdx> {
#[inline]
fn clone(&self) -> Variants<FieldIdx, VariantIdx> {
match self {
Variants::Empty => Variants::Empty,
Variants::Single { index: __self_0 } =>
Variants::Single {
index: ::core::clone::Clone::clone(__self_0),
},
Variants::Multiple {
tag: __self_0,
tag_encoding: __self_1,
tag_field: __self_2,
variants: __self_3 } =>
Variants::Multiple {
tag: ::core::clone::Clone::clone(__self_0),
tag_encoding: ::core::clone::Clone::clone(__self_1),
tag_field: ::core::clone::Clone::clone(__self_2),
variants: ::core::clone::Clone::clone(__self_3),
},
}
}
}Clone, #[automatically_derived]
impl<FieldIdx: ::core::fmt::Debug + Idx, VariantIdx: ::core::fmt::Debug + Idx>
::core::fmt::Debug for Variants<FieldIdx, VariantIdx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Variants::Empty => ::core::fmt::Formatter::write_str(f, "Empty"),
Variants::Single { index: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Single", "index", &__self_0),
Variants::Multiple {
tag: __self_0,
tag_encoding: __self_1,
tag_field: __self_2,
variants: __self_3 } =>
::core::fmt::Formatter::debug_struct_field4_finish(f,
"Multiple", "tag", __self_0, "tag_encoding", __self_1,
"tag_field", __self_2, "variants", &__self_3),
}
}
}Debug)]
2074#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<FieldIdx: Idx, VariantIdx: Idx>
::rustc_data_structures::stable_hash::StableHash for
Variants<FieldIdx, VariantIdx> where
VariantIdx: ::rustc_data_structures::stable_hash::StableHash,
FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Variants::Empty => {}
Variants::Single { index: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
Variants::Multiple {
tag: ref __binding_0,
tag_encoding: ref __binding_1,
tag_field: ref __binding_2,
variants: ref __binding_3 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
2075pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
2076 Empty,
2078
2079 Single {
2081 index: VariantIdx,
2083 },
2084
2085 Multiple {
2092 tag: Scalar,
2093 tag_encoding: TagEncoding<VariantIdx>,
2094 tag_field: FieldIdx,
2095 variants: IndexVec<VariantIdx, VariantLayout<FieldIdx>>,
2096 },
2097}
2098
2099#[derive(#[automatically_derived]
impl<VariantIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
TagEncoding<VariantIdx> {
#[inline]
fn eq(&self, other: &TagEncoding<VariantIdx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(TagEncoding::Niche {
untagged_variant: __self_0,
niche_variants: __self_1,
niche_start: __self_2 }, TagEncoding::Niche {
untagged_variant: __arg1_0,
niche_variants: __arg1_1,
niche_start: __arg1_2 }) =>
__self_2 == __arg1_2 && __self_0 == __arg1_0 &&
__self_1 == __arg1_1,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl<VariantIdx: ::core::cmp::Eq + Idx> ::core::cmp::Eq for
TagEncoding<VariantIdx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<VariantIdx>;
let _: ::core::cmp::AssertParamIsEq<RangeInclusive<VariantIdx>>;
let _: ::core::cmp::AssertParamIsEq<u128>;
}
}Eq, #[automatically_derived]
impl<VariantIdx: ::core::hash::Hash + Idx> ::core::hash::Hash for
TagEncoding<VariantIdx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
TagEncoding::Niche {
untagged_variant: __self_0,
niche_variants: __self_1,
niche_start: __self_2 } => {
::core::hash::Hash::hash(__self_0, state);
::core::hash::Hash::hash(__self_1, state);
::core::hash::Hash::hash(__self_2, state)
}
_ => {}
}
}
}Hash, #[automatically_derived]
impl<VariantIdx: ::core::marker::Copy + Idx> ::core::marker::Copy for
TagEncoding<VariantIdx> {
}Copy, #[automatically_derived]
impl<VariantIdx: ::core::clone::Clone + Idx> ::core::clone::Clone for
TagEncoding<VariantIdx> {
#[inline]
fn clone(&self) -> TagEncoding<VariantIdx> {
match self {
TagEncoding::Direct => TagEncoding::Direct,
TagEncoding::Niche {
untagged_variant: __self_0,
niche_variants: __self_1,
niche_start: __self_2 } =>
TagEncoding::Niche {
untagged_variant: ::core::clone::Clone::clone(__self_0),
niche_variants: ::core::clone::Clone::clone(__self_1),
niche_start: ::core::clone::Clone::clone(__self_2),
},
}
}
}Clone, #[automatically_derived]
impl<VariantIdx: ::core::fmt::Debug + Idx> ::core::fmt::Debug for
TagEncoding<VariantIdx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
TagEncoding::Direct =>
::core::fmt::Formatter::write_str(f, "Direct"),
TagEncoding::Niche {
untagged_variant: __self_0,
niche_variants: __self_1,
niche_start: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f, "Niche",
"untagged_variant", __self_0, "niche_variants", __self_1,
"niche_start", &__self_2),
}
}
}Debug)]
2101#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<VariantIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
for TagEncoding<VariantIdx> where
VariantIdx: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
TagEncoding::Direct => {}
TagEncoding::Niche {
untagged_variant: ref __binding_0,
niche_variants: ref __binding_1,
niche_start: ref __binding_2 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
2102pub enum TagEncoding<VariantIdx: Idx> {
2103 Direct,
2106
2107 Niche {
2131 untagged_variant: VariantIdx,
2132 niche_variants: RangeInclusive<VariantIdx>,
2135 niche_start: u128,
2138 },
2139}
2140
2141#[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)]
2142#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Niche {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Niche {
offset: ref __binding_0,
value: ref __binding_1,
valid_range: ref __binding_2 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
2143pub struct Niche {
2144 pub offset: Size,
2145 pub value: Primitive,
2146 pub valid_range: WrappingRange,
2147}
2148
2149impl Niche {
2150 pub fn from_scalar<C: HasDataLayout>(cx: &C, offset: Size, scalar: Scalar) -> Option<Self> {
2151 let Scalar::Initialized { value, valid_range } = scalar else { return None };
2152 let niche = Niche { offset, value, valid_range };
2153 if niche.available(cx) > 0 { Some(niche) } else { None }
2154 }
2155
2156 pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
2157 let Self { value, valid_range: v, .. } = *self;
2158 let size = value.size(cx);
2159 if !(size.bits() <= 128) {
::core::panicking::panic("assertion failed: size.bits() <= 128")
};assert!(size.bits() <= 128);
2160 let max_value = size.unsigned_int_max();
2161
2162 let niche = v.end.wrapping_add(1)..v.start;
2164 niche.end.wrapping_sub(niche.start) & max_value
2165 }
2166
2167 pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
2168 if !(count > 0) { ::core::panicking::panic("assertion failed: count > 0") };assert!(count > 0);
2169
2170 let Self { value, valid_range: v, .. } = *self;
2171 let size = value.size(cx);
2172 if !(size.bits() <= 128) {
::core::panicking::panic("assertion failed: size.bits() <= 128")
};assert!(size.bits() <= 128);
2173 let max_value = size.unsigned_int_max();
2174
2175 let available = v.start.wrapping_sub(v.end).wrapping_sub(1) & max_value;
2176 if count > available {
2177 return None;
2178 }
2179
2180 let move_start = |v: WrappingRange| {
2194 let start = v.start.wrapping_sub(count) & max_value;
2195 Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) }))
2196 };
2197 let move_end = |v: WrappingRange| {
2198 let start = v.end.wrapping_add(1) & max_value;
2199 let end = v.end.wrapping_add(count) & max_value;
2200 Some((start, Scalar::Initialized { value, valid_range: v.with_end(end) }))
2201 };
2202 let distance_end_zero = max_value - v.end;
2203 if count == 1 && v != (WrappingRange { start: 0, end: 1 }) {
2206 let next_up = size.sign_extend(v.end.wrapping_add(1)).unsigned_abs();
2211 let next_down = size.sign_extend(v.start.wrapping_sub(1)).unsigned_abs();
2212 if next_down <= next_up { move_start(v) } else { move_end(v) }
2213 } else if v.start > v.end {
2214 move_end(v)
2216 } else if v.start <= distance_end_zero {
2217 if count <= v.start {
2218 move_start(v)
2219 } else {
2220 move_end(v)
2222 }
2223 } else {
2224 let end = v.end.wrapping_add(count) & max_value;
2225 let overshot_zero = (1..=v.end).contains(&end);
2226 if overshot_zero {
2227 move_start(v)
2229 } else {
2230 move_end(v)
2231 }
2232 }
2233 }
2234}
2235
2236#[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)]
2238#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<FieldIdx: Idx, VariantIdx: Idx>
::rustc_data_structures::stable_hash::StableHash for
LayoutData<FieldIdx, VariantIdx> where
FieldIdx: ::rustc_data_structures::stable_hash::StableHash,
VariantIdx: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
LayoutData {
fields: ref __binding_0,
variants: ref __binding_1,
backend_repr: ref __binding_2,
largest_niche: ref __binding_3,
uninhabited: ref __binding_4,
align: ref __binding_5,
size: ref __binding_6,
max_repr_align: ref __binding_7,
unadjusted_abi_align: ref __binding_8,
randomization_seed: ref __binding_9 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
{ __binding_5.stable_hash(__hcx, __hasher); }
{ __binding_6.stable_hash(__hcx, __hasher); }
{ __binding_7.stable_hash(__hcx, __hasher); }
{ __binding_8.stable_hash(__hcx, __hasher); }
{ __binding_9.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
2239pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
2240 pub fields: FieldsShape<FieldIdx>,
2242
2243 pub variants: Variants<FieldIdx, VariantIdx>,
2251
2252 pub backend_repr: BackendRepr,
2260
2261 pub largest_niche: Option<Niche>,
2264 pub uninhabited: bool,
2269
2270 pub align: AbiAlign,
2271 pub size: Size,
2272
2273 pub max_repr_align: Option<Align>,
2277
2278 pub unadjusted_abi_align: Align,
2282
2283 pub randomization_seed: Hash64,
2294}
2295
2296impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
2297 pub fn is_aggregate(&self) -> bool {
2299 match self.backend_repr {
2300 BackendRepr::Scalar(_)
2301 | BackendRepr::SimdVector { .. }
2302 | BackendRepr::SimdScalableVector { .. } => false,
2303 BackendRepr::ScalarPair { .. } | BackendRepr::Memory { .. } => true,
2304 }
2305 }
2306
2307 pub fn is_uninhabited(&self) -> bool {
2309 self.uninhabited
2310 }
2311}
2312
2313impl<FieldIdx: Idx, VariantIdx: Idx> fmt::Debug for LayoutData<FieldIdx, VariantIdx>
2314where
2315 FieldsShape<FieldIdx>: fmt::Debug,
2316 Variants<FieldIdx, VariantIdx>: fmt::Debug,
2317{
2318 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2319 let LayoutData {
2323 size,
2324 align,
2325 backend_repr,
2326 fields,
2327 largest_niche,
2328 uninhabited,
2329 variants,
2330 max_repr_align,
2331 unadjusted_abi_align,
2332 randomization_seed,
2333 } = self;
2334 f.debug_struct("Layout")
2335 .field("size", size)
2336 .field("align", align)
2337 .field("backend_repr", backend_repr)
2338 .field("fields", fields)
2339 .field("largest_niche", largest_niche)
2340 .field("uninhabited", uninhabited)
2341 .field("variants", variants)
2342 .field("max_repr_align", max_repr_align)
2343 .field("unadjusted_abi_align", unadjusted_abi_align)
2344 .field("randomization_seed", randomization_seed)
2345 .finish()
2346 }
2347}
2348
2349#[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)]
2350pub enum PointerKind {
2351 SharedRef { frozen: bool },
2353 MutableRef { unpin: bool },
2355 Box { unpin: bool, global: bool },
2358}
2359
2360#[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)]
2366pub struct PointeeInfo {
2367 pub safe: Option<PointerKind>,
2369 pub size: Size,
2376 pub align: Align,
2378}
2379
2380impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
2381 #[inline]
2383 pub fn is_unsized(&self) -> bool {
2384 self.backend_repr.is_unsized()
2385 }
2386
2387 #[inline]
2388 pub fn is_sized(&self) -> bool {
2389 self.backend_repr.is_sized()
2390 }
2391
2392 pub fn is_1zst(&self) -> bool {
2394 self.is_sized() && self.size.bytes() == 0 && self.align.bytes() == 1
2395 }
2396
2397 pub fn is_scalable_vector(&self) -> bool {
2399 #[allow(non_exhaustive_omitted_patterns)] match self.backend_repr {
BackendRepr::SimdScalableVector { .. } => true,
_ => false,
}matches!(self.backend_repr, BackendRepr::SimdScalableVector { .. })
2400 }
2401
2402 pub fn scalable_vector_element_count(&self) -> Option<u64> {
2404 match self.backend_repr {
2405 BackendRepr::SimdScalableVector { count, .. } => Some(count),
2406 _ => None,
2407 }
2408 }
2409
2410 pub fn is_zst(&self) -> bool {
2415 match self.backend_repr {
2416 BackendRepr::Scalar(_)
2417 | BackendRepr::ScalarPair { .. }
2418 | BackendRepr::SimdScalableVector { .. }
2419 | BackendRepr::SimdVector { .. } => false,
2420 BackendRepr::Memory { sized } => sized && self.size.bytes() == 0,
2421 }
2422 }
2423
2424 #[inline]
2433 pub fn is_ssa_standalone(&self) -> bool {
2434 match self.backend_repr {
2435 BackendRepr::Memory { .. } => self.is_zst(),
2436 BackendRepr::Scalar(..)
2437 | BackendRepr::ScalarPair { .. }
2438 | BackendRepr::SimdVector { .. }
2439 | BackendRepr::SimdScalableVector { .. } => true,
2440 }
2441 }
2442
2443 pub fn eq_abi(&self, other: &Self) -> bool {
2449 self.size == other.size
2453 && self.is_sized() == other.is_sized()
2454 && self.backend_repr.eq_up_to_validity(&other.backend_repr)
2455 && self.backend_repr.is_bool() == other.backend_repr.is_bool()
2456 && self.align.abi == other.align.abi
2457 && self.max_repr_align == other.max_repr_align
2458 && self.unadjusted_abi_align == other.unadjusted_abi_align
2459 }
2460}
2461
2462#[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)]
2463pub enum StructKind {
2464 AlwaysSized,
2466 MaybeUnsized,
2468 Prefixed(Size, Align),
2470}
2471
2472#[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)]
2473pub enum AbiFromStrErr {
2474 Unknown,
2476 NoExplicitUnwind,
2478}
2479
2480#[derive(#[automatically_derived]
impl<FieldIdx: ::core::cmp::PartialEq + Idx> ::core::cmp::PartialEq for
VariantLayout<FieldIdx> {
#[inline]
fn eq(&self, other: &VariantLayout<FieldIdx>) -> bool {
self.uninhabited == other.uninhabited && self.size == other.size &&
self.backend_repr == other.backend_repr &&
self.field_offsets == other.field_offsets &&
self.fields_in_memory_order == other.fields_in_memory_order &&
self.largest_niche == other.largest_niche
}
}PartialEq, #[automatically_derived]
impl<FieldIdx: ::core::cmp::Eq + Idx> ::core::cmp::Eq for
VariantLayout<FieldIdx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Size>;
let _: ::core::cmp::AssertParamIsEq<BackendRepr>;
let _: ::core::cmp::AssertParamIsEq<IndexVec<FieldIdx, Size>>;
let _: ::core::cmp::AssertParamIsEq<IndexVec<u32, FieldIdx>>;
let _: ::core::cmp::AssertParamIsEq<Option<Niche>>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl<FieldIdx: ::core::hash::Hash + Idx> ::core::hash::Hash for
VariantLayout<FieldIdx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.size, state);
::core::hash::Hash::hash(&self.backend_repr, state);
::core::hash::Hash::hash(&self.field_offsets, state);
::core::hash::Hash::hash(&self.fields_in_memory_order, state);
::core::hash::Hash::hash(&self.largest_niche, state);
::core::hash::Hash::hash(&self.uninhabited, state)
}
}Hash, #[automatically_derived]
impl<FieldIdx: ::core::clone::Clone + Idx> ::core::clone::Clone for
VariantLayout<FieldIdx> {
#[inline]
fn clone(&self) -> VariantLayout<FieldIdx> {
VariantLayout {
size: ::core::clone::Clone::clone(&self.size),
backend_repr: ::core::clone::Clone::clone(&self.backend_repr),
field_offsets: ::core::clone::Clone::clone(&self.field_offsets),
fields_in_memory_order: ::core::clone::Clone::clone(&self.fields_in_memory_order),
largest_niche: ::core::clone::Clone::clone(&self.largest_niche),
uninhabited: ::core::clone::Clone::clone(&self.uninhabited),
}
}
}Clone, #[automatically_derived]
impl<FieldIdx: ::core::fmt::Debug + Idx> ::core::fmt::Debug for
VariantLayout<FieldIdx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["size", "backend_repr", "field_offsets",
"fields_in_memory_order", "largest_niche", "uninhabited"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.size, &self.backend_repr, &self.field_offsets,
&self.fields_in_memory_order, &self.largest_niche,
&&self.uninhabited];
::core::fmt::Formatter::debug_struct_fields_finish(f, "VariantLayout",
names, values)
}
}Debug)]
2482#[cfg_attr(feature = "nightly", derive(const _: () =
{
impl<FieldIdx: Idx> ::rustc_data_structures::stable_hash::StableHash
for VariantLayout<FieldIdx> where
FieldIdx: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
VariantLayout {
size: ref __binding_0,
backend_repr: ref __binding_1,
field_offsets: ref __binding_2,
fields_in_memory_order: ref __binding_3,
largest_niche: ref __binding_4,
uninhabited: ref __binding_5 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
{ __binding_5.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash))]
2483pub struct VariantLayout<FieldIdx: Idx> {
2484 pub size: Size,
2485 pub backend_repr: BackendRepr,
2486 pub field_offsets: IndexVec<FieldIdx, Size>,
2487 fields_in_memory_order: IndexVec<u32, FieldIdx>,
2488 largest_niche: Option<Niche>,
2489 uninhabited: bool,
2490}
2491
2492impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
2493 pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self {
2494 let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else {
2495 {
::core::panicking::panic_fmt(format_args!("Layout of fields should be Arbitrary for variants"));
};panic!("Layout of fields should be Arbitrary for variants");
2496 };
2497
2498 Self {
2499 size: layout.size,
2500 backend_repr: layout.backend_repr,
2501 field_offsets: offsets,
2502 fields_in_memory_order: in_memory_order,
2503 largest_niche: layout.largest_niche,
2504 uninhabited: layout.uninhabited,
2505 }
2506 }
2507
2508 pub fn is_uninhabited(&self) -> bool {
2509 self.uninhabited
2510 }
2511
2512 pub fn has_fields(&self) -> bool {
2513 self.field_offsets.len() > 0
2514 }
2515}