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 #[derive(HashStable_Generic)]
24 pub struct VariantIdx {}
27 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
28 #[rustc_pass_by_value]
29 pub struct Layout<'a>(pub Interned<'a, LayoutS<VariantIdx>>);
31 impl<'a> fmt::Debug for Layout<'a> {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 // See comment on `<LayoutS as Debug>::fmt` above.
39 pub fn fields(self) -> &'a FieldsShape {
43 pub fn variants(self) -> &'a Variants<VariantIdx> {
47 pub fn abi(self) -> Abi {
51 pub fn largest_niche(self) -> Option<Niche> {
52 self.0.0.largest_niche
55 pub fn align(self) -> AbiAndPrefAlign {
59 pub fn size(self) -> Size {
64 /// The layout of a type, alongside the type itself.
65 /// Provides various type traversal APIs (e.g., recursing into fields).
67 /// Note that the layout is NOT guaranteed to always be identical
68 /// to that obtained from `layout_of(ty)`, as we need to produce
69 /// layouts for which Rust types do not exist, such as enum variants
70 /// or synthetic fields of enums (i.e., discriminants) and fat pointers.
71 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)]
72 pub struct TyAndLayout<'a, Ty> {
74 pub layout: Layout<'a>,
77 impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
78 type Target = &'a LayoutS<VariantIdx>;
79 fn deref(&self) -> &&'a LayoutS<VariantIdx> {
84 /// Trait that needs to be implemented by the higher-level type representation
85 /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
86 pub trait TyAbiInterface<'a, C>: Sized {
87 fn ty_and_layout_for_variant(
88 this: TyAndLayout<'a, Self>,
90 variant_index: VariantIdx,
91 ) -> TyAndLayout<'a, Self>;
92 fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
93 fn ty_and_layout_pointee_info_at(
94 this: TyAndLayout<'a, Self>,
97 ) -> Option<PointeeInfo>;
98 fn is_adt(this: TyAndLayout<'a, Self>) -> bool;
99 fn is_never(this: TyAndLayout<'a, Self>) -> bool;
100 fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
101 fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
104 impl<'a, Ty> TyAndLayout<'a, Ty> {
105 pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
107 Ty: TyAbiInterface<'a, C>,
109 Ty::ty_and_layout_for_variant(self, cx, variant_index)
112 pub fn field<C>(self, cx: &C, i: usize) -> Self
114 Ty: TyAbiInterface<'a, C>,
116 Ty::ty_and_layout_field(self, cx, i)
119 pub fn pointee_info_at<C>(self, cx: &C, offset: Size) -> Option<PointeeInfo>
121 Ty: TyAbiInterface<'a, C>,
123 Ty::ty_and_layout_pointee_info_at(self, cx, offset)
126 pub fn is_single_fp_element<C>(self, cx: &C) -> bool
128 Ty: TyAbiInterface<'a, C>,
132 Abi::Scalar(scalar) => matches!(scalar.primitive(), F32 | F64),
133 Abi::Aggregate { .. } => {
134 if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
135 self.field(cx, 0).is_single_fp_element(cx)
144 pub fn is_adt<C>(self) -> bool
146 Ty: TyAbiInterface<'a, C>,
151 pub fn is_never<C>(self) -> bool
153 Ty: TyAbiInterface<'a, C>,
158 pub fn is_tuple<C>(self) -> bool
160 Ty: TyAbiInterface<'a, C>,
165 pub fn is_unit<C>(self) -> bool
167 Ty: TyAbiInterface<'a, C>,
173 impl<'a, Ty> TyAndLayout<'a, Ty> {
174 /// Returns `true` if the layout corresponds to an unsized type.
175 pub fn is_unsized(&self) -> bool {
176 self.abi.is_unsized()
180 pub fn is_sized(&self) -> bool {
184 /// Returns `true` if the type is a ZST and not unsized.
185 pub fn is_zst(&self) -> bool {
187 Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } => false,
188 Abi::Uninhabited => self.size.bytes() == 0,
189 Abi::Aggregate { sized } => sized && self.size.bytes() == 0,