Skip to main content

rustc_codegen_llvm/
type_of.rs

1use std::fmt::Write;
2
3use rustc_abi::Primitive::{self, Float, Int, Pointer};
4use rustc_abi::{Align, BackendRepr, FieldsShape, Scalar, Size, Variants};
5use rustc_codegen_ssa::traits::*;
6use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
7use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
8use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt};
9use rustc_span::{DUMMY_SP, Span, bug};
10use tracing::debug;
11
12use crate::common::*;
13use crate::llvm::Type;
14
15fn uncached_llvm_type<'ll, 'tcx>(
16    cx: &CodegenCx<'ll, 'tcx>,
17    layout: TyAndLayout<'tcx>,
18    defer: &mut Option<(Type<'ll>, TyAndLayout<'tcx>)>,
19) -> Type<'ll> {
20    match layout.backend_repr {
21        BackendRepr::Scalar(_) => ::rustc_span::macros::bug_impl(None, format_args!("handled elsewhere"),
    Location::caller())bug!("handled elsewhere"),
22        BackendRepr::SimdVector { element, count } => {
23            let element = layout.scalar_llvm_type_at(cx, element);
24            return cx.type_vector(element, count.as_u64());
25        }
26        BackendRepr::SimdScalableVector { ref element, count, number_of_vectors } => {
27            let element = if element.is_bool() {
28                cx.type_i1()
29            } else {
30                layout.scalar_llvm_type_at(cx, *element)
31            };
32
33            let vector_type = cx.type_scalable_vector(element, count.as_u64());
34            return match number_of_vectors.0 {
35                1 => vector_type,
36                2 => cx.type_struct(&[vector_type; 2]),
37                3 => cx.type_struct(&[vector_type; 3]),
38                4 => cx.type_struct(&[vector_type; 4]),
39                5 => cx.type_struct(&[vector_type; 5]),
40                6 => cx.type_struct(&[vector_type; 6]),
41                7 => cx.type_struct(&[vector_type; 7]),
42                8 => cx.type_struct(&[vector_type; 8]),
43                _ => ::rustc_span::macros::bug_impl(None,
    format_args!("`#[rustc_scalable_vector]` tuple struct with too many fields"),
    Location::caller())bug!("`#[rustc_scalable_vector]` tuple struct with too many fields"),
44            };
45        }
46        BackendRepr::Memory { .. } | BackendRepr::ScalarPair { .. } => {}
47    }
48
49    let name = match layout.ty.kind() {
50        // FIXME(eddyb) producing readable type names for trait objects can result
51        // in problematically distinct types due to HRTB and subtyping (see #47638).
52        // ty::Dynamic(..) |
53        ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
54            // For performance reasons we use names only when emitting LLVM IR.
55            if !cx.sess().fewer_names() =>
56        {
57            let mut name = {
    let _guard = NoVisibleGuard::new();
    { let _guard = NoTrimmedGuard::new(); layout.ty.to_string() }
}with_no_visible_paths!(with_no_trimmed_paths!(layout.ty.to_string()));
58            if let (&ty::Adt(def, _), &Variants::Single { index }) =
59                (layout.ty.kind(), &layout.variants)
60            {
61                if def.is_enum() {
62                    (&mut name).write_fmt(format_args!("::{0}", def.variant(index).name))write!(&mut name, "::{}", def.variant(index).name).unwrap();
63                }
64            }
65            if let (&ty::Coroutine(_, _), &Variants::Single { index }) =
66                (layout.ty.kind(), &layout.variants)
67            {
68                (&mut name).write_fmt(format_args!("::{0}",
        ty::CoroutineArgs::variant_name(index)))write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap();
69            }
70            Some(name)
71        }
72        _ => None,
73    };
74
75    match layout.fields {
76        FieldsShape::Primitive | FieldsShape::Union(_) => {
77            let fill = cx.type_padding_filler(layout.size, layout.align);
78            match name {
79                None => cx.type_struct(&[fill]),
80                Some(ref name) => {
81                    let llty = cx.type_named_struct(name);
82                    cx.set_struct_body(llty, &[fill]);
83                    llty
84                }
85            }
86        }
87        FieldsShape::Array { count, .. } => {
88            let element_ty = layout.field(cx, 0);
89            if let BackendRepr::Scalar(scalar) = element_ty.backend_repr
90                && scalar.primitive() == Primitive::Float(rustc_abi::Float::X87F80)
91            {
92                cx.type_padding_filler(element_ty.size * count, element_ty.align)
93            } else {
94                cx.type_array(element_ty.llvm_type(cx), count)
95            }
96        }
97        FieldsShape::Arbitrary { .. } => match name {
98            None => {
99                let (llfields, packed) = struct_llfields(cx, layout);
100                if packed { cx.type_packed_struct(&llfields) } else { cx.type_struct(&llfields) }
101            }
102            Some(ref name) => {
103                let llty = cx.type_named_struct(name);
104                *defer = Some((llty, layout));
105                llty
106            }
107        },
108    }
109}
110
111fn struct_llfields<'ll, 'tcx>(
112    cx: &CodegenCx<'ll, 'tcx>,
113    layout: TyAndLayout<'tcx>,
114) -> (Vec<Type<'ll>>, bool) {
115    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:115",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(115u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("struct_llfields: {0:#?}",
                                                    layout) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("struct_llfields: {:#?}", layout);
116    let field_count = layout.fields.count();
117
118    let mut packed = false;
119    let mut offset = Size::ZERO;
120    let mut prev_effective_align = layout.align;
121    let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
122    for i in layout.fields.index_by_increasing_offset() {
123        let target_offset = layout.fields.offset(i);
124        let field = layout.field(cx, i);
125        let effective_field_align =
126            layout.align.min(field.align).restrict_for_offset(target_offset);
127        packed |= effective_field_align < field.align;
128
129        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:129",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(129u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("struct_llfields: {0}: {1:?} offset: {2:?} target_offset: {3:?} effective_field_align: {4}",
                                                    i, field, offset, target_offset,
                                                    effective_field_align.bytes()) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
130            "struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \
131                effective_field_align: {}",
132            i,
133            field,
134            offset,
135            target_offset,
136            effective_field_align.bytes()
137        );
138        if !(target_offset >= offset) {
    ::core::panicking::panic("assertion failed: target_offset >= offset")
};assert!(target_offset >= offset);
139        let padding = target_offset - offset;
140        if padding != Size::ZERO {
141            let padding_align = prev_effective_align.min(effective_field_align);
142            {
    match (&(offset.align_to(padding_align) + padding), &target_offset) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(offset.align_to(padding_align) + padding, target_offset);
143            result.push(cx.type_padding_filler(padding, padding_align));
144            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:144",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(144u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("    padding before: {0:?}",
                                                    padding) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("    padding before: {:?}", padding);
145        }
146
147        if let BackendRepr::Scalar(scalar) = field.backend_repr
148            && scalar.primitive() == Primitive::Float(rustc_abi::Float::X87F80)
149        {
150            result.push(cx.type_padding_filler(field.size, field.align));
151        } else {
152            result.push(field.llvm_type(cx));
153        }
154
155        offset = target_offset + field.size;
156        prev_effective_align = effective_field_align;
157    }
158    if layout.is_sized() && field_count > 0 {
159        if offset > layout.size {
160            ::rustc_span::macros::bug_impl(None,
    format_args!("layout: {0:#?} stride: {1:?} offset: {2:?}", layout,
        layout.size, offset), Location::caller());bug!("layout: {:#?} stride: {:?} offset: {:?}", layout, layout.size, offset);
161        }
162        let padding = layout.size - offset;
163        if padding != Size::ZERO {
164            let padding_align = prev_effective_align;
165            {
    match (&(offset.align_to(padding_align) + padding), &layout.size) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(offset.align_to(padding_align) + padding, layout.size);
166            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:166",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(166u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("struct_llfields: pad_bytes: {0:?} offset: {1:?} stride: {2:?}",
                                                    padding, offset, layout.size) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
167                "struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
168                padding, offset, layout.size
169            );
170            result.push(cx.type_padding_filler(padding, padding_align));
171        }
172    } else {
173        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:173",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(173u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("struct_llfields: offset: {0:?} stride: {1:?}",
                                                    offset, layout.size) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
174    }
175    (result, packed)
176}
177
178impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
179    pub(crate) fn align_of(&self, ty: Ty<'tcx>) -> Align {
180        self.layout_of(ty).align
181    }
182
183    pub(crate) fn size_of(&self, ty: Ty<'tcx>) -> Size {
184        self.layout_of(ty).size
185    }
186
187    pub(crate) fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) {
188        self.spanned_size_and_align_of(ty, DUMMY_SP)
189    }
190
191    pub(crate) fn spanned_size_and_align_of(&self, ty: Ty<'tcx>, span: Span) -> (Size, Align) {
192        let layout = self.spanned_layout_of(ty, span);
193        (layout.size, layout.align)
194    }
195}
196
197pub(crate) trait LayoutLlvmExt<'tcx> {
198    fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>) -> Type<'ll>;
199    fn immediate_llvm_type<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>) -> Type<'ll>;
200    fn scalar_llvm_type_at<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>, scalar: Scalar) -> Type<'ll>;
201    fn scalar_pair_element_llvm_type<'ll>(
202        &self,
203        cx: &CodegenCx<'ll, 'tcx>,
204        index: usize,
205        immediate: bool,
206    ) -> Type<'ll>;
207}
208
209impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
210    /// Gets the LLVM type corresponding to a Rust type, i.e., `rustc_middle::ty::Ty`.
211    ///
212    /// For sized types, this is the in-memory type that is used for stores and loads.
213    /// The type used for immediates may be different, see [`Self::immediate_llvm_type`].
214    ///
215    /// Unsized types, however, are represented by a "minimal unit", e.g.
216    /// `[T]` becomes `T`, while `str` and `Trait` turn into `i8` - this
217    /// is useful for indexing slices, as `&[T]`'s data pointer is `T*`.
218    ///
219    /// If the type is an unsized struct, the regular layout is generated,
220    /// with the innermost trailing unsized field using the "minimal unit"
221    /// of that field's type - this is useful for taking the address of
222    /// that field and ensuring the struct has the right alignment.
223    fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>) -> Type<'ll> {
224        // This must produce the same result for `repr(transparent)` wrappers as for the inner type!
225        // In other words, this should generally not look at the type at all, but only at the
226        // layout.
227        if let BackendRepr::Scalar(scalar) = self.backend_repr {
228            // Use a different cache for scalars because pointers to DSTs
229            // can be either wide or thin (data pointers of wide pointers).
230            if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
231                return llty;
232            }
233            let llty = self.scalar_llvm_type_at(cx, scalar);
234            cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
235            return llty;
236        }
237
238        // Check the cache.
239        let variant_index = match self.variants {
240            Variants::Single { index } => Some(index),
241            _ => None,
242        };
243        if let Some(llty) = cx.type_lowering.borrow().get(&(self.ty, variant_index)).copied() {
244            return llty;
245        }
246
247        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:247",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(247u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("llvm_type({0:#?})",
                                                    self) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("llvm_type({:#?})", self);
248
249        if !!self.ty.has_escaping_bound_vars() {
    {
        ::core::panicking::panic_fmt(format_args!("{0:?} has escaping bound vars",
                self.ty));
    }
};assert!(!self.ty.has_escaping_bound_vars(), "{:?} has escaping bound vars", self.ty);
250
251        // Make sure lifetimes are erased, to avoid generating distinct LLVM
252        // types for Rust types that only differ in the choice of lifetimes.
253        let normal_ty = cx.tcx.erase_and_anonymize_regions(self.ty);
254
255        let mut defer = None;
256        let llty = if self.ty != normal_ty {
257            let mut layout = cx.layout_of(normal_ty);
258            if let Some(v) = variant_index {
259                layout = layout.for_variant(cx, v);
260            }
261            layout.llvm_type(cx)
262        } else {
263            uncached_llvm_type(cx, *self, &mut defer)
264        };
265        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs:265",
                        "rustc_codegen_llvm::type_of", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_codegen_llvm/src/type_of.rs"),
                        ::tracing_core::__macro_support::Option::Some(265u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_codegen_llvm::type_of"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("--> mapped {0:#?} to llty={1:?}",
                                                    self, llty) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("--> mapped {:#?} to llty={:?}", self, llty);
266
267        cx.type_lowering.borrow_mut().insert((self.ty, variant_index), llty);
268
269        if let Some((llty, layout)) = defer {
270            let (llfields, packed) = struct_llfields(cx, layout);
271            if packed {
272                cx.set_struct_body_packed(llty, &llfields)
273            } else {
274                cx.set_struct_body(llty, &llfields)
275            }
276        }
277        llty
278    }
279
280    fn immediate_llvm_type<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>) -> Type<'ll> {
281        match self.backend_repr {
282            BackendRepr::Scalar(scalar) => {
283                if scalar.is_bool() {
284                    return cx.type_i1();
285                }
286            }
287            BackendRepr::ScalarPair { .. } => {
288                // An immediate pair always contains just the two elements, without any padding
289                // filler, as it should never be stored to memory.
290                return cx.type_struct(&[
291                    self.scalar_pair_element_llvm_type(cx, 0, true),
292                    self.scalar_pair_element_llvm_type(cx, 1, true),
293                ]);
294            }
295            _ => {}
296        };
297        self.llvm_type(cx)
298    }
299
300    fn scalar_llvm_type_at<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>, scalar: Scalar) -> Type<'ll> {
301        match scalar.primitive() {
302            Int(i, _) => cx.type_from_integer(i),
303            Float(f) => cx.type_from_float(f),
304            Pointer(address_space) => cx.type_ptr_ext(address_space),
305        }
306    }
307
308    fn scalar_pair_element_llvm_type<'ll>(
309        &self,
310        cx: &CodegenCx<'ll, 'tcx>,
311        index: usize,
312        immediate: bool,
313    ) -> Type<'ll> {
314        // This must produce the same result for `repr(transparent)` wrappers as for the inner type!
315        // In other words, this should generally not look at the type at all, but only at the
316        // layout.
317        let BackendRepr::ScalarPair { a, b, b_offset: _ } = self.backend_repr else {
318            ::rustc_span::macros::bug_impl(None,
    format_args!("TyAndLayout::scalar_pair_element_llty({0:?}): not applicable",
        self), Location::caller());bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self);
319        };
320        let scalar = [a, b][index];
321
322        // Make sure to return the same type `immediate_llvm_type` would when
323        // dealing with an immediate pair. This means that `(bool, bool)` is
324        // effectively represented as `{i8, i8}` in memory and two `i1`s as an
325        // immediate, just like `bool` is typically `i8` in memory and only `i1`
326        // when immediate. We need to load/store `bool` as `i8` to avoid
327        // crippling LLVM optimizations or triggering other LLVM bugs with `i1`.
328        if immediate && scalar.is_bool() {
329            return cx.type_i1();
330        }
331
332        self.scalar_llvm_type_at(cx, scalar)
333    }
334}