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 ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
54 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 fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, 'tcx>) -> Type<'ll> {
224 if let BackendRepr::Scalar(scalar) = self.backend_repr {
228 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 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 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 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 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 if immediate && scalar.is_bool() {
329 return cx.type_i1();
330 }
331
332 self.scalar_llvm_type_at(cx, scalar)
333 }
334}