4 use crate::json::{Json, ToJson};
9 use rustc_data_structures::intern::Interned;
10 use rustc_macros::HashStable_Generic;
16 impl ToJson for Endian {
17 fn to_json(&self) -> Json {
18 self.as_str().to_json()
22 rustc_index::newtype_index! {
23 pub struct VariantIdx {
24 derive [HashStable_Generic]
28 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
29 #[rustc_pass_by_value]
30 pub struct Layout<'a>(pub Interned<'a, LayoutS<VariantIdx>>);
32 impl<'a> fmt::Debug for Layout<'a> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 // See comment on `<LayoutS as Debug>::fmt` above.
40 pub fn fields(self) -> &'a FieldsShape {
44 pub fn variants(self) -> &'a Variants<VariantIdx> {
48 pub fn abi(self) -> Abi {
52 pub fn largest_niche(self) -> Option<Niche> {
53 self.0.0.largest_niche
56 pub fn align(self) -> AbiAndPrefAlign {
60 pub fn size(self) -> Size {
65 /// The layout of a type, alongside the type itself.
66 /// Provides various type traversal APIs (e.g., recursing into fields).
68 /// Note that the layout is NOT guaranteed to always be identical
69 /// to that obtained from `layout_of(ty)`, as we need to produce
70 /// layouts for which Rust types do not exist, such as enum variants
71 /// or synthetic fields of enums (i.e., discriminants) and fat pointers.
72 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)]
73 pub struct TyAndLayout<'a, Ty> {
75 pub layout: Layout<'a>,
78 impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
79 type Target = &'a LayoutS<VariantIdx>;
80 fn deref(&self) -> &&'a LayoutS<VariantIdx> {
85 /// Trait that needs to be implemented by the higher-level type representation
86 /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
87 pub trait TyAbiInterface<'a, C>: Sized {
88 fn ty_and_layout_for_variant(
89 this: TyAndLayout<'a, Self>,
91 variant_index: VariantIdx,
92 ) -> TyAndLayout<'a, Self>;
93 fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
94 fn ty_and_layout_pointee_info_at(
95 this: TyAndLayout<'a, Self>,
98 ) -> Option<PointeeInfo>;
99 fn is_adt(this: TyAndLayout<'a, Self>) -> bool;
100 fn is_never(this: TyAndLayout<'a, Self>) -> bool;
101 fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
102 fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
105 impl<'a, Ty> TyAndLayout<'a, Ty> {
106 pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
108 Ty: TyAbiInterface<'a, C>,
110 Ty::ty_and_layout_for_variant(self, cx, variant_index)
113 pub fn field<C>(self, cx: &C, i: usize) -> Self
115 Ty: TyAbiInterface<'a, C>,
117 Ty::ty_and_layout_field(self, cx, i)
120 pub fn pointee_info_at<C>(self, cx: &C, offset: Size) -> Option<PointeeInfo>
122 Ty: TyAbiInterface<'a, C>,
124 Ty::ty_and_layout_pointee_info_at(self, cx, offset)
127 pub fn is_single_fp_element<C>(self, cx: &C) -> bool
129 Ty: TyAbiInterface<'a, C>,
133 Abi::Scalar(scalar) => scalar.primitive().is_float(),
134 Abi::Aggregate { .. } => {
135 if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
136 self.field(cx, 0).is_single_fp_element(cx)
145 pub fn is_adt<C>(self) -> bool
147 Ty: TyAbiInterface<'a, C>,
152 pub fn is_never<C>(self) -> bool
154 Ty: TyAbiInterface<'a, C>,
159 pub fn is_tuple<C>(self) -> bool
161 Ty: TyAbiInterface<'a, C>,
166 pub fn is_unit<C>(self) -> bool
168 Ty: TyAbiInterface<'a, C>,
174 impl<'a, Ty> TyAndLayout<'a, Ty> {
175 /// Returns `true` if the layout corresponds to an unsized type.
176 pub fn is_unsized(&self) -> bool {
177 self.abi.is_unsized()
181 pub fn is_sized(&self) -> bool {
185 /// Returns `true` if the type is a ZST and not unsized.
186 pub fn is_zst(&self) -> bool {
188 Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } => false,
189 Abi::Uninhabited => self.size.bytes() == 0,
190 Abi::Aggregate { sized } => sized && self.size.bytes() == 0,