1use std::range::{RangeFrom, RangeToInclusive};
2
3use rustc_abi as abi;
4use rustc_abi::Integer::{I8, I32};
5use rustc_abi::Primitive::{self, Float, Int, Pointer};
6use rustc_abi::{
7 AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout,
8 LayoutCalculatorError, LayoutData, Niche, NicheOptimizations, ReprOptions, Scalar, Size,
9 StructKind, TagEncoding, VariantIdx, Variants, WrappingRange,
10};
11use rustc_attr_ir::find_attr;
12use rustc_attr_ir::lang_items::LangItem;
13use rustc_hashes::Hash64;
14use rustc_hir::def_id::DefId;
15use rustc_index::{Idx as _, IndexVec};
16use rustc_middle::query::Providers;
17use rustc_middle::traits::ObligationCause;
18use rustc_middle::ty::layout::{
19 FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, SimdLayoutError, TyAndLayout,
20};
21use rustc_middle::ty::print::with_no_trimmed_paths;
22use rustc_middle::ty::{
23 self, AdtDef, CoroutineArgsExt, EarlyBinder, PseudoCanonicalInput, Ty, TyCtxt,
24 TypeVisitableExt, Unnormalized,
25};
26use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
27use rustc_span::{Symbol, bug, sym};
28use rustc_structures::Limit;
29use tracing::{debug, instrument};
30
31use crate::diagnostics::NonPrimitiveSimdType;
32
33mod invariant;
34
35pub(crate) fn provide(providers: &mut Providers) {
36 *providers = Providers { layout_of, ..*providers };
37}
38
39{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("layout_of",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(39u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set_all(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>> =
loop {};
return __tracing_attr_fake_return;
}
{
let PseudoCanonicalInput {
typing_env: original_typing_env, value: original_ty } =
query;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:45",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(45u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("original_ty")
}> =
::tracing::__macro_support::FieldName::new("original_ty");
NAME.as_str()
}], ::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(&::tracing::field::debug(&original_ty)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let typing_env =
original_typing_env.with_post_analysis_normalized(tcx);
let unnormalized_ty =
if typing_env != original_typing_env {
ty::set_aliases_to_non_rigid(tcx, original_ty)
} else { ty::Unnormalized::new_wip(original_ty) };
let normalized_ty =
match tcx.try_normalize_erasing_regions(typing_env,
unnormalized_ty) {
Ok(t) => t,
Err(normalization_error) => {
return Err(tcx.arena.alloc(LayoutError::NormalizationFailure(unnormalized_ty.skip_normalization(),
normalization_error)));
}
};
if normalized_ty != original_ty {
return tcx.layout_of(typing_env.as_query_input(normalized_ty));
}
match typing_env.typing_mode() {
ty::TypingMode::Codegen => {
let with_postanalysis =
ty::TypingEnv::new(typing_env.param_env,
ty::TypingMode::PostAnalysis);
let res =
tcx.layout_of(with_postanalysis.as_query_input(normalized_ty));
match res {
Err(LayoutError::TooGeneric(_)) => {}
_ => return res,
};
}
ty::TypingMode::Coherence | ty::TypingMode::Typeck { .. } |
ty::TypingMode::PostTypeckUntilBorrowck { .. } |
ty::TypingMode::PostBorrowck { .. } |
ty::TypingMode::Reflection |
ty::TypingMode::ErasedNotCoherence(_) |
ty::TypingMode::PostAnalysis => {}
}
let cx = LayoutCx::new(tcx, typing_env);
let layout = layout_of_uncached(&cx, normalized_ty)?;
let layout = TyAndLayout { ty: normalized_ty, layout };
if cx.tcx().sess.opts.unstable_opts.print_type_sizes {
record_layout_for_printing(&cx, layout);
}
invariant::layout_sanity_check(&cx, &layout);
Ok(layout)
}
}
}#[instrument(skip(tcx, query), level = "debug")]
40fn layout_of<'tcx>(
41 tcx: TyCtxt<'tcx>,
42 query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
43) -> Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>> {
44 let PseudoCanonicalInput { typing_env: original_typing_env, value: original_ty } = query;
45 debug!(?original_ty);
46
47 let typing_env = original_typing_env.with_post_analysis_normalized(tcx);
51 let unnormalized_ty = if typing_env != original_typing_env {
54 ty::set_aliases_to_non_rigid(tcx, original_ty)
55 } else {
56 ty::Unnormalized::new_wip(original_ty)
57 };
58
59 let normalized_ty = match tcx.try_normalize_erasing_regions(typing_env, unnormalized_ty) {
64 Ok(t) => t,
65 Err(normalization_error) => {
66 return Err(tcx.arena.alloc(LayoutError::NormalizationFailure(
67 unnormalized_ty.skip_normalization(),
68 normalization_error,
69 )));
70 }
71 };
72
73 if normalized_ty != original_ty {
74 return tcx.layout_of(typing_env.as_query_input(normalized_ty));
76 }
77
78 match typing_env.typing_mode() {
79 ty::TypingMode::Codegen => {
80 let with_postanalysis =
81 ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis);
82 let res = tcx.layout_of(with_postanalysis.as_query_input(normalized_ty));
83 match res {
84 Err(LayoutError::TooGeneric(_)) => {}
85 _ => return res,
86 };
87 }
88 ty::TypingMode::Coherence
89 | ty::TypingMode::Typeck { .. }
90 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
91 | ty::TypingMode::PostBorrowck { .. }
92 | ty::TypingMode::Reflection
93 | ty::TypingMode::ErasedNotCoherence(_)
94 | ty::TypingMode::PostAnalysis => {}
95 }
96
97 let cx = LayoutCx::new(tcx, typing_env);
98
99 let layout = layout_of_uncached(&cx, normalized_ty)?;
100 let layout = TyAndLayout { ty: normalized_ty, layout };
101
102 if cx.tcx().sess.opts.unstable_opts.print_type_sizes {
105 record_layout_for_printing(&cx, layout);
106 }
107
108 invariant::layout_sanity_check(&cx, &layout);
109
110 Ok(layout)
111}
112
113fn error<'tcx>(cx: &LayoutCx<'tcx>, err: LayoutError<'tcx>) -> &'tcx LayoutError<'tcx> {
114 cx.tcx().arena.alloc(err)
115}
116
117fn map_error<'tcx>(
118 cx: &LayoutCx<'tcx>,
119 ty: Ty<'tcx>,
120 err: LayoutCalculatorError<TyAndLayout<'tcx>>,
121) -> &'tcx LayoutError<'tcx> {
122 let err = match err {
123 LayoutCalculatorError::SizeOverflow => {
124 LayoutError::SizeOverflow(ty)
127 }
128 LayoutCalculatorError::UnexpectedUnsized(field) => {
129 if !field.layout.is_unsized() {
{
::core::panicking::panic_fmt(format_args!("invalid layout error {0:#?}",
err));
}
};assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
132 if cx.typing_env.param_env.is_empty() {
133 cx.tcx().dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("encountered unexpected unsized field in layout of {0:?}: {1:#?}",
ty, field))
})format!(
134 "encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
135 ));
136 }
137 LayoutError::Unknown(ty)
138 }
139 LayoutCalculatorError::EmptyUnion => {
140 let guar =
142 cx.tcx().dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("computed layout of empty union: {0:?}",
ty))
})format!("computed layout of empty union: {ty:?}"));
143 LayoutError::ReferencesError(guar)
144 }
145 LayoutCalculatorError::ReprConflict => {
146 let guar = cx
148 .tcx()
149 .dcx()
150 .delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("computed impossible repr (packed enum?): {0:?}",
ty))
})format!("computed impossible repr (packed enum?): {ty:?}"));
151 LayoutError::ReferencesError(guar)
152 }
153 LayoutCalculatorError::ZeroLengthSimdType => {
154 LayoutError::InvalidSimd { ty, kind: SimdLayoutError::ZeroLength }
156 }
157 LayoutCalculatorError::OversizedSimdType { max_lanes } => {
158 LayoutError::InvalidSimd { ty, kind: SimdLayoutError::TooManyLanes(Limit(max_lanes)) }
160 }
161 LayoutCalculatorError::NonPrimitiveSimdType(field) => {
162 cx.tcx().dcx().emit_fatal(NonPrimitiveSimdType { ty, e_ty: field.ty })
165 }
166 };
167 error(cx, err)
168}
169
170fn extract_const_value<'tcx>(
171 cx: &LayoutCx<'tcx>,
172 ty: Ty<'tcx>,
173 ct: ty::Const<'tcx>,
174) -> Result<ty::Value<'tcx>, &'tcx LayoutError<'tcx>> {
175 match ct.kind() {
176 ty::ConstKind::Value(cv) => Ok(cv),
177 ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => {
178 if !ct.has_param() {
179 ::rustc_span::macros::bug_impl(None,
format_args!("failed to normalize const, but it is not generic: {0:?}",
ct), Location::caller());bug!("failed to normalize const, but it is not generic: {ct:?}");
180 }
181 Err(error(cx, LayoutError::TooGeneric(ty)))
182 }
183 ty::ConstKind::Alias(_, _) => {
184 let err = if ct.has_param() {
185 LayoutError::TooGeneric(ty)
186 } else {
187 LayoutError::Unknown(ty)
193 };
194 Err(error(cx, err))
195 }
196 ty::ConstKind::Infer(_)
197 | ty::ConstKind::Bound(..)
198 | ty::ConstKind::Placeholder(_)
199 | ty::ConstKind::Error(_) => {
200 ::rustc_span::macros::bug_impl(None,
format_args!("layout_of: unexpected const: {0:?}", ct),
Location::caller());bug!("layout_of: unexpected const: {ct:?}");
203 }
204 }
205}
206
207fn layout_of_uncached<'tcx>(
208 cx: &LayoutCx<'tcx>,
209 ty: Ty<'tcx>,
210) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
211 if let Err(guar) = ty.error_reported() {
215 return Err(error(cx, LayoutError::ReferencesError(guar)));
216 }
217
218 let tcx = cx.tcx();
219
220 let dl = cx.data_layout();
224 let map_layout = |result: Result<_, _>| match result {
225 Ok(layout) => Ok(tcx.mk_layout(layout)),
226 Err(err) => Err(map_error(cx, ty, err)),
227 };
228 let scalar_unit = |value: Primitive| {
229 let size = value.size(dl);
230 if !(size.bits() <= 128) {
::core::panicking::panic("assertion failed: size.bits() <= 128")
};assert!(size.bits() <= 128);
231 Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
232 };
233 let scalar = |value: Primitive| tcx.mk_layout(LayoutData::scalar(cx, scalar_unit(value)));
234
235 let univariant = |tys: &[Ty<'tcx>], kind| {
236 let fields = tys.iter().map(|ty| cx.layout_of(*ty)).try_collect::<IndexVec<_, _>>()?;
237 let repr = ReprOptions::default();
238 map_layout(cx.calc.layout_of_univariant(&fields, &repr, kind))
239 };
240 if true {
if !!ty.has_non_region_infer() {
::core::panicking::panic("assertion failed: !ty.has_non_region_infer()")
};
};debug_assert!(!ty.has_non_region_infer());
241
242 Ok(match *ty.kind() {
243 ty::Pat(ty, pat) => {
244 let layout = cx.layout_of(ty)?.layout;
245 let mut layout = LayoutData::clone(&layout.0);
246 match *pat {
247 ty::PatternKind::Range { start, end } => {
248 if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr {
249 scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
250 .try_to_bits(tcx, cx.typing_env)
251 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
252
253 scalar.valid_range_mut().end = extract_const_value(cx, ty, end)?
254 .try_to_bits(tcx, cx.typing_env)
255 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
256
257 if scalar.is_signed() {
263 let range = scalar.valid_range_mut();
264 let start = layout.size.sign_extend(range.start);
265 let end = layout.size.sign_extend(range.end);
266 if end < start {
267 let guar = tcx.dcx().err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("pattern type ranges cannot wrap: {0}..={1}",
start, end))
})format!(
268 "pattern type ranges cannot wrap: {start}..={end}"
269 ));
270
271 return Err(error(cx, LayoutError::ReferencesError(guar)));
272 }
273 } else {
274 let range = scalar.valid_range_mut();
275 if range.end < range.start {
276 let guar = tcx.dcx().err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("pattern type ranges cannot wrap: {0}..={1}",
range.start, range.end))
})format!(
277 "pattern type ranges cannot wrap: {}..={}",
278 range.start, range.end
279 ));
280
281 return Err(error(cx, LayoutError::ReferencesError(guar)));
282 }
283 };
284
285 let niche = Niche {
286 offset: Size::ZERO,
287 value: scalar.primitive(),
288 valid_range: scalar.valid_range(cx),
289 };
290
291 layout.largest_niche = Some(niche);
292 } else {
293 ::rustc_span::macros::bug_impl(None,
format_args!("pattern type with range but not scalar layout: {0:?}, {1:?}",
ty, layout), Location::caller())bug!("pattern type with range but not scalar layout: {ty:?}, {layout:?}")
294 }
295 }
296 ty::PatternKind::NotNull => {
297 if let BackendRepr::Scalar(scalar)
298 | BackendRepr::ScalarPair { a: scalar, b: _, b_offset: _ } =
299 &mut layout.backend_repr
300 {
301 scalar.valid_range_mut().start = 1;
302 let niche = Niche {
303 offset: Size::ZERO,
304 value: scalar.primitive(),
305 valid_range: scalar.valid_range(cx),
306 };
307
308 layout.largest_niche = Some(niche);
309 } else {
310 ::rustc_span::macros::bug_impl(None,
format_args!("pattern type with `!null` pattern but not scalar/pair layout: {0:?}, {1:?}",
ty, layout), Location::caller())bug!(
311 "pattern type with `!null` pattern but not scalar/pair layout: {ty:?}, {layout:?}"
312 )
313 }
314 }
315
316 ty::PatternKind::Or(variants) => match *variants[0] {
317 ty::PatternKind::Range { .. } => {
318 if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr {
319 let variants: Result<Vec<_>, _> = variants
320 .iter()
321 .map(|pat| match *pat {
322 ty::PatternKind::Range { start, end } => Ok((
323 extract_const_value(cx, ty, start)
324 .unwrap()
325 .try_to_bits(tcx, cx.typing_env)
326 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
327 extract_const_value(cx, ty, end)
328 .unwrap()
329 .try_to_bits(tcx, cx.typing_env)
330 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
331 )),
332 ty::PatternKind::NotNull | ty::PatternKind::Or(_) => {
333 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("mixed or patterns are not allowed")));
}unreachable!("mixed or patterns are not allowed")
334 }
335 })
336 .collect();
337 let mut variants = variants?;
338 if !scalar.is_signed() {
339 let guar = tcx.dcx().err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("only signed integer base types are allowed for or-pattern pattern types at present"))
})format!(
340 "only signed integer base types are allowed for or-pattern pattern types at present"
341 ));
342
343 return Err(error(cx, LayoutError::ReferencesError(guar)));
344 }
345 variants.sort();
346 if variants.len() != 2 {
347 let guar = tcx
348 .dcx()
349 .err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the only or-pattern types allowed are two range patterns that are directly connected at their overflow site"))
})format!("the only or-pattern types allowed are two range patterns that are directly connected at their overflow site"));
350
351 return Err(error(cx, LayoutError::ReferencesError(guar)));
352 }
353
354 let mut first = variants[0];
356 let mut second = variants[1];
357 if second.0
358 == layout.size.truncate(layout.size.signed_int_min() as u128)
359 {
360 (second, first) = (first, second);
361 }
362
363 if layout.size.sign_extend(first.1) >= layout.size.sign_extend(second.0)
364 {
365 let guar = tcx.dcx().err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("only non-overlapping pattern type ranges are allowed at present"))
})format!(
366 "only non-overlapping pattern type ranges are allowed at present"
367 ));
368
369 return Err(error(cx, LayoutError::ReferencesError(guar)));
370 }
371 if layout.size.signed_int_max() as u128 != second.1 {
372 let guar = tcx.dcx().err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("one pattern needs to end at `{1}::MAX`, but was {0} instead",
second.1, ty))
})format!(
373 "one pattern needs to end at `{ty}::MAX`, but was {} instead",
374 second.1
375 ));
376
377 return Err(error(cx, LayoutError::ReferencesError(guar)));
378 }
379
380 scalar.valid_range_mut().start = second.0;
382 scalar.valid_range_mut().end = first.1;
383
384 let niche = Niche {
385 offset: Size::ZERO,
386 value: scalar.primitive(),
387 valid_range: scalar.valid_range(cx),
388 };
389
390 layout.largest_niche = Some(niche);
391 } else {
392 ::rustc_span::macros::bug_impl(None,
format_args!("pattern type with range but not scalar layout: {0:?}, {1:?}",
ty, layout), Location::caller())bug!(
393 "pattern type with range but not scalar layout: {ty:?}, {layout:?}"
394 )
395 }
396 }
397 ty::PatternKind::NotNull => ::rustc_span::macros::bug_impl(None,
format_args!("or patterns can\'t contain `!null` patterns"),
Location::caller())bug!("or patterns can't contain `!null` patterns"),
398 ty::PatternKind::Or(..) => ::rustc_span::macros::bug_impl(None,
format_args!("patterns cannot have nested or patterns"),
Location::caller())bug!("patterns cannot have nested or patterns"),
399 },
400 }
401 layout.fields = FieldsShape::Arbitrary {
406 offsets: [Size::ZERO].into_iter().collect(),
407 in_memory_order: [FieldIdx::new(0)].into_iter().collect(),
408 };
409 tcx.mk_layout(layout)
410 }
411
412 ty::Bool => tcx.mk_layout(LayoutData::scalar(
414 cx,
415 Scalar::Initialized {
416 value: Int(I8, false),
417 valid_range: WrappingRange { start: 0, end: 1 },
418 },
419 )),
420 ty::Char => tcx.mk_layout(LayoutData::scalar(
421 cx,
422 Scalar::Initialized {
423 value: Int(I32, false),
424 valid_range: WrappingRange { start: 0, end: 0x10FFFF },
425 },
426 )),
427 ty::Int(ity) => scalar(Int(abi::Integer::from_int_ty(dl, ity), true)),
428 ty::Uint(ity) => scalar(Int(abi::Integer::from_uint_ty(dl, ity), false)),
429 ty::Float(fty) => scalar(Float(abi::Float::from_float_ty(fty))),
430 ty::FnPtr(..) => {
431 let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
432 ptr.valid_range_mut().start = 1;
433 tcx.mk_layout(LayoutData::scalar(cx, ptr))
434 }
435
436 ty::Never => tcx.mk_layout(LayoutData::never_type(cx)),
438
439 ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
441 let mut data_ptr = scalar_unit(Pointer(AddressSpace::ZERO));
442 if !ty.is_raw_ptr() {
443 data_ptr.valid_range_mut().start = 1;
444 }
445
446 if pointee.is_sized(tcx, cx.typing_env) {
447 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
448 }
449
450 let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
451 let pointee_metadata =
452 Ty::new_projection(tcx, ty::IsRigid::No, metadata_def_id, [pointee]);
453 let metadata_ty = match tcx.try_normalize_erasing_regions(
454 cx.typing_env,
455 Unnormalized::new_wip(pointee_metadata),
456 ) {
457 Ok(metadata_ty) => metadata_ty,
458 Err(mut err) => {
459 match tcx.try_normalize_erasing_regions(
468 cx.typing_env,
469 Unnormalized::new_wip(tcx.struct_tail_raw(
470 pointee,
471 &ObligationCause::dummy(),
472 |ty| ty.skip_norm_wip(),
473 || {},
474 )),
475 ) {
476 Ok(_) => {}
477 Err(better_err) => {
478 err = better_err;
479 }
480 }
481 return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
482 }
483 };
484
485 let metadata_layout = cx.layout_of(metadata_ty)?;
486 if metadata_layout.is_1zst() {
488 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
489 }
490
491 let BackendRepr::Scalar(metadata) = metadata_layout.backend_repr else {
492 return Err(error(cx, LayoutError::Unknown(pointee)));
493 };
494
495 metadata
496 } else {
497 let unsized_part = tcx.struct_tail_for_codegen(pointee, cx.typing_env);
498
499 match unsized_part.kind() {
500 ty::Foreign(..) => {
501 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
502 }
503 ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
504 ty::Dynamic(..) => {
505 let mut vtable = scalar_unit(Pointer(AddressSpace::ZERO));
506 vtable.valid_range_mut().start = 1;
507 vtable
508 }
509 _ => {
510 return Err(error(cx, LayoutError::Unknown(pointee)));
511 }
512 }
513 };
514
515 tcx.mk_layout(LayoutData::scalar_pair(cx, data_ptr, metadata))
517 }
518
519 ty::Array(element, count) => {
521 let count = extract_const_value(cx, ty, count)?
522 .try_to_target_usize(tcx)
523 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
524
525 let element = cx.layout_of(element)?;
526 map_layout(cx.calc.layout_of_array_like(&element, Some(count)))?
527 }
528 ty::Slice(element) => {
529 let element = cx.layout_of(element)?;
530 map_layout(cx.calc.layout_of_array_like(&element, None).map(|mut layout| {
531 layout.randomization_seed = Hash64::new(0x2dcba99c39784102);
533 layout
534 }))?
535 }
536 ty::Str => {
537 let element = scalar(Int(I8, false));
538 map_layout(cx.calc.layout_of_array_like(&element, None).map(|mut layout| {
539 layout.randomization_seed = Hash64::new(0xc1325f37d127be22);
541 layout
542 }))?
543 }
544
545 ty::FnDef(..) | ty::Dynamic(_, _) | ty::Foreign(..) => {
547 let sized = #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::FnDef(..) => true,
_ => false,
}matches!(ty.kind(), ty::FnDef(..));
548 tcx.mk_layout(LayoutData::unit(cx, sized))
549 }
550
551 ty::Coroutine(def_id, args) => {
552 match cx.typing_env.typing_mode() {
553 ty::TypingMode::Codegen => {}
554 ty::TypingMode::Coherence
555 | ty::TypingMode::Typeck { .. }
556 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
557 | ty::TypingMode::PostBorrowck { .. }
558 | ty::TypingMode::Reflection
559 | ty::TypingMode::ErasedNotCoherence(_)
560 | ty::TypingMode::PostAnalysis => {
561 return Err(error(cx, LayoutError::TooGeneric(ty)));
562 }
563 }
564
565 use rustc_middle::ty::layout::PrimitiveExt as _;
566
567 let info = tcx.coroutine_layout(def_id, args)?;
568
569 let local_layouts = info
570 .field_tys
571 .iter()
572 .map(|local| {
573 let field_ty = EarlyBinder::bind(tcx, local.ty);
574 let uninit_ty =
575 Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args).skip_norm_wip());
576 cx.spanned_layout_of(uninit_ty, local.source_info.span)
577 })
578 .try_collect::<IndexVec<_, _>>()?;
579
580 let prefix_layouts = args
581 .as_coroutine()
582 .upvar_tys()
583 .iter()
584 .map(|ty| cx.layout_of(ty))
585 .try_collect::<IndexVec<_, _>>()?;
586
587 let layout = cx
588 .calc
589 .layout_of_coroutine(
590 &local_layouts,
591 prefix_layouts,
592 &info.variant_fields,
593 &info.storage_conflicts,
594 |tag| TyAndLayout {
595 ty: tag.primitive().to_ty(tcx),
596 layout: tcx.mk_layout(LayoutData::scalar(cx, tag)),
597 },
598 )
599 .map(|mut layout| {
600 layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash();
602 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:602",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(602u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("coroutine layout ({0:?}): {1:#?}",
ty, layout) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("coroutine layout ({:?}): {:#?}", ty, layout);
603 layout
604 });
605 map_layout(layout)?
606 }
607
608 ty::Closure(_, args) => univariant(args.as_closure().upvar_tys(), StructKind::AlwaysSized)?,
609
610 ty::CoroutineClosure(_, args) => {
611 univariant(args.as_coroutine_closure().upvar_tys(), StructKind::AlwaysSized)?
612 }
613
614 ty::Tuple(tys) => {
615 let kind =
616 if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
617
618 univariant(tys, kind)?
619 }
620
621 ty::Adt(def, _args) if def.repr().scalable() => {
631 let Some((element_count, element_ty, number_of_vectors)) =
632 ty.scalable_vector_parts(tcx)
633 else {
634 let guar = tcx
635 .dcx()
636 .delayed_bug("`#[rustc_scalable_vector]` was applied to an invalid type");
637 return Err(error(cx, LayoutError::ReferencesError(guar)));
638 };
639
640 let element_layout = cx.layout_of(element_ty)?;
641 map_layout(cx.calc.layout_of_scalable_vector_type(
642 element_layout,
643 element_count as u64,
644 number_of_vectors,
645 ))?
646 }
647
648 ty::Adt(def, args) if def.repr().simd() => {
650 let Some(ty::Array(e_ty, e_len)) = def
656 .is_struct()
657 .then(|| &def.variant(FIRST_VARIANT).fields)
658 .filter(|fields| fields.len() == 1)
659 .map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).skip_norm_wip().kind())
660 else {
661 let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT");
663 return Err(error(cx, LayoutError::ReferencesError(guar)));
664 };
665
666 let e_len = extract_const_value(cx, ty, e_len)?
667 .try_to_target_usize(tcx)
668 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
669
670 let e_ly = cx.layout_of(e_ty)?;
671
672 if let Some(limit) = {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def.did(), &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcSimdMonomorphizeLaneLimit(limit))
=> {
break 'done Some(limit);
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(
674 tcx, def.did(),
675 RustcSimdMonomorphizeLaneLimit(limit) => limit
676 ) {
677 if !limit.value_within_limit(e_len as usize) {
678 return Err(map_error(
679 &cx,
680 ty,
681 rustc_abi::LayoutCalculatorError::OversizedSimdType { max_lanes: limit.0 },
682 ));
683 }
684 }
685
686 map_layout(cx.calc.layout_of_simd_type(e_ly, e_len, def.repr().packed()))?
687 }
688
689 ty::Adt(def, args) => {
691 let variants = def
693 .variants()
694 .iter()
695 .map(|v| {
696 v.fields
697 .iter()
698 .map(|field| cx.layout_of(field.ty(tcx, args).skip_norm_wip()))
699 .try_collect::<IndexVec<_, _>>()
700 })
701 .try_collect::<IndexVec<VariantIdx, _>>()?;
702
703 if def.is_union() {
704 if def.repr().pack.is_some() && def.repr().align.is_some() {
705 let guar = tcx.dcx().span_delayed_bug(
706 tcx.def_span(def.did()),
707 "union cannot be packed and aligned",
708 );
709 return Err(error(cx, LayoutError::ReferencesError(guar)));
710 }
711
712 return map_layout(cx.calc.layout_of_union(&def.repr(), &variants));
713 }
714
715 let niche_optimizations = match def.is_unsafe_cell() || def.is_unsafe_pinned() {
717 true => NicheOptimizations::Disabled,
718 false => NicheOptimizations::Enabled,
719 };
720
721 let discr_range_of_repr = |min: RangeFrom<i128>, max: RangeToInclusive<u128>| {
722 abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min.start, max.last)
723 };
724
725 if def.is_enum() {
727 for v in def.variants() {
728 if let ty::VariantDiscr::Explicit(def_id) = v.discr
729 && let Some(local_did) = def_id.as_local()
730 && let Some(guar) = tcx.typeck(local_did).tainted_by_errors
731 {
732 return Err(error(cx, LayoutError::ReferencesError(guar)));
733 }
734 }
735 }
736
737 let discriminants_iter = || {
738 def.is_enum()
739 .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val)))
740 .into_flat_iter()
741 };
742
743 let maybe_unsized = def.is_struct()
744 && def.non_enum_variant().tail_opt().is_some_and(|last_field| {
745 let typing_env = ty::TypingEnv::new(
746 tcx.param_env_normalized_for_post_analysis(def.did()),
747 cx.typing_env.typing_mode(),
748 );
749 !tcx.type_of(last_field.did)
750 .instantiate_identity()
751 .skip_norm_wip()
752 .is_sized(tcx, typing_env)
753 });
754
755 let mut layout = cx
756 .calc
757 .layout_of_struct_or_enum(
758 &def.repr(),
759 &variants,
760 def.is_enum(),
761 niche_optimizations,
762 discr_range_of_repr,
763 discriminants_iter(),
764 !maybe_unsized,
765 )
766 .map_err(|err| map_error(cx, ty, err))?;
767
768 if !maybe_unsized && layout.is_unsized() {
769 ::rustc_span::macros::bug_impl(None,
format_args!("got unsized layout for type that cannot be unsized {0:?}: {1:#?}",
ty, layout), Location::caller());bug!("got unsized layout for type that cannot be unsized {ty:?}: {layout:#?}");
770 }
771
772 if truecfg!(debug_assertions)
774 && maybe_unsized
775 && def
776 .non_enum_variant()
777 .tail()
778 .ty(tcx, args)
779 .skip_norm_wip()
780 .is_sized(tcx, cx.typing_env)
781 {
782 let mut variants = variants;
783 let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();
784 *variants[FIRST_VARIANT].raw.last_mut().unwrap() = tail_replacement;
785
786 let Ok(unsized_layout) = cx.calc.layout_of_struct_or_enum(
787 &def.repr(),
788 &variants,
789 def.is_enum(),
790 niche_optimizations,
791 discr_range_of_repr,
792 discriminants_iter(),
793 !maybe_unsized,
794 ) else {
795 ::rustc_span::macros::bug_impl(None,
format_args!("failed to compute unsized layout of {0:?}", ty),
Location::caller());bug!("failed to compute unsized layout of {ty:?}");
796 };
797
798 let FieldsShape::Arbitrary { offsets: sized_offsets, .. } = &layout.fields else {
799 ::rustc_span::macros::bug_impl(None,
format_args!("unexpected FieldsShape for sized layout of {1:?}: {0:?}",
layout.fields, ty), Location::caller());bug!("unexpected FieldsShape for sized layout of {ty:?}: {:?}", layout.fields);
800 };
801 let FieldsShape::Arbitrary { offsets: unsized_offsets, .. } =
802 &unsized_layout.fields
803 else {
804 ::rustc_span::macros::bug_impl(None,
format_args!("unexpected FieldsShape for unsized layout of {1:?}: {0:?}",
unsized_layout.fields, ty), Location::caller());bug!(
805 "unexpected FieldsShape for unsized layout of {ty:?}: {:?}",
806 unsized_layout.fields
807 );
808 };
809
810 let (sized_tail, sized_fields) = sized_offsets.raw.split_last().unwrap();
811 let (unsized_tail, unsized_fields) = unsized_offsets.raw.split_last().unwrap();
812
813 if sized_fields != unsized_fields {
814 ::rustc_span::macros::bug_impl(None,
format_args!("unsizing {0:?} changed field order!\n{1:?}\n{2:?}", ty,
layout, unsized_layout), Location::caller());bug!("unsizing {ty:?} changed field order!\n{layout:?}\n{unsized_layout:?}");
815 }
816
817 if sized_tail < unsized_tail {
818 ::rustc_span::macros::bug_impl(None,
format_args!("unsizing {0:?} moved tail backwards!\n{1:?}\n{2:?}", ty,
layout, unsized_layout), Location::caller());bug!("unsizing {ty:?} moved tail backwards!\n{layout:?}\n{unsized_layout:?}");
819 }
820 }
821
822 if tcx.is_lang_item(def.did(), LangItem::F16B) {
823 let bfloat = scalar_unit(Primitive::Float(abi::Float::F16B));
824 {
match (&layout.size, &abi::Float::F16B.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!(layout.size, abi::Float::F16B.size());
825 layout.align = abi::Float::F16B.align(cx);
826 layout.backend_repr = BackendRepr::Scalar(bfloat);
827 }
828
829 if tcx.is_lang_item(def.did(), LangItem::PpcF128) {
830 let ppcf128 = scalar_unit(Primitive::Float(abi::Float::PpcF128));
831 {
match (&layout.size, &abi::Float::PpcF128.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!(layout.size, abi::Float::PpcF128.size());
832 layout.align = abi::Float::PpcF128.align(cx);
833 layout.backend_repr = BackendRepr::Scalar(ppcf128);
834 }
835
836 tcx.mk_layout(layout)
837 }
838
839 ty::UnsafeBinder(bound_ty) => {
840 let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
841 cx.layout_of(ty)?.layout
842 }
843
844 ty::Param(_) | ty::Placeholder(..) => {
846 return Err(error(cx, LayoutError::TooGeneric(ty)));
847 }
848
849 ty::Alias(..) => {
850 let err = if ty.has_param() || !cx.typing_env.param_env.is_empty() {
861 LayoutError::TooGeneric(ty)
862 } else {
863 LayoutError::ReferencesError(cx.tcx().dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unexpected rigid alias in layout_of after normalization: {0:?}",
ty))
})format!(
864 "unexpected rigid alias in layout_of after normalization: {ty:?}"
865 )))
866 };
867 return Err(error(cx, err));
868 }
869
870 ty::Bound(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => {
871 ::rustc_span::macros::bug_impl(None,
format_args!("layout_of: unexpected type `{0}`", ty), Location::caller())bug!("layout_of: unexpected type `{ty}`")
873 }
874 })
875}
876
877fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) {
878 if layout.ty.has_non_region_param() || !cx.typing_env.param_env.is_empty() {
882 return;
883 }
884
885 let record = |kind, packed, opt_discr_size, variants| {
887 let type_desc = {
let _guard = NoTrimmedGuard::new();
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}", layout.ty))
})
}with_no_trimmed_paths!(format!("{}", layout.ty));
888 cx.tcx().sess.code_stats.record_type_size(
889 kind,
890 type_desc,
891 layout.align.abi,
892 layout.size,
893 packed,
894 opt_discr_size,
895 variants,
896 );
897 };
898
899 match *layout.ty.kind() {
900 ty::Adt(adt_def, _) => {
901 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:901",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(901u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size t: `{0:?}` process adt",
layout.ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` process adt", layout.ty);
902 let adt_kind = adt_def.adt_kind();
903 let adt_packed = adt_def.repr().pack.is_some();
904 let (variant_infos, opt_discr_size) = variant_info_for_adt(cx, layout, adt_def);
905 record(adt_kind.into(), adt_packed, opt_discr_size, variant_infos);
906 }
907
908 ty::Coroutine(def_id, args) => {
909 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:909",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(909u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size t: `{0:?}` record coroutine",
layout.ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` record coroutine", layout.ty);
910 let (variant_infos, opt_discr_size) =
912 variant_info_for_coroutine(cx, layout, def_id, args);
913 record(DataTypeKind::Coroutine, false, opt_discr_size, variant_infos);
914 }
915
916 ty::Closure(..) => {
917 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:917",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(917u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size t: `{0:?}` record closure",
layout.ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` record closure", layout.ty);
918 record(DataTypeKind::Closure, false, None, ::alloc::vec::Vec::new()vec![]);
919 }
920
921 _ => {
922 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:922",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(922u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size t: `{0:?}` skip non-nominal",
layout.ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
923 }
924 };
925}
926
927fn variant_info_for_adt<'tcx>(
928 cx: &LayoutCx<'tcx>,
929 layout: TyAndLayout<'tcx>,
930 adt_def: AdtDef<'tcx>,
931) -> (Vec<VariantInfo>, Option<Size>) {
932 let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
933 let mut min_size = Size::ZERO;
934 let field_info: Vec<_> = flds
935 .iter()
936 .enumerate()
937 .map(|(i, &name)| {
938 let field_layout = layout.field(cx, i);
939 let offset = layout.fields.offset(i);
940 min_size = min_size.max(offset + field_layout.size);
941 FieldInfo {
942 kind: FieldKind::AdtField,
943 name,
944 offset: offset.bytes(),
945 size: field_layout.size.bytes(),
946 align: field_layout.align.bytes(),
947 type_name: None,
948 }
949 })
950 .collect();
951
952 VariantInfo {
953 name: n,
954 kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact },
955 align: layout.align.bytes(),
956 size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
957 fields: field_info,
958 }
959 };
960
961 match layout.variants {
962 Variants::Empty => (::alloc::vec::Vec::new()vec![], None),
963
964 Variants::Single { index } => {
965 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:965",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(965u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size `{0:#?}` variant {1}",
layout, adt_def.variant(index).name) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name);
966 let variant_def = &adt_def.variant(index);
967 let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
968 (::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[build_variant_info(Some(variant_def.name), &fields, layout)]))vec![build_variant_info(Some(variant_def.name), &fields, layout)], None)
969 }
970
971 Variants::Multiple { tag, ref tag_encoding, .. } => {
972 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs:972",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/822182db4c4a1827256881d8c7aa685f0bcf2b11/compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(972u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::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!("print-type-size `{0:#?}` adt general variants def {1}",
layout.ty, adt_def.variants().len()) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
973 "print-type-size `{:#?}` adt general variants def {}",
974 layout.ty,
975 adt_def.variants().len()
976 );
977 let variant_infos: Vec<_> = adt_def
978 .variants()
979 .iter_enumerated()
980 .map(|(i, variant_def)| {
981 let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
982 build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i))
983 })
984 .collect();
985
986 (
987 variant_infos,
988 match tag_encoding {
989 TagEncoding::Direct => Some(tag.size(cx)),
990 _ => None,
991 },
992 )
993 }
994 }
995}
996
997fn variant_info_for_coroutine<'tcx>(
998 cx: &LayoutCx<'tcx>,
999 layout: TyAndLayout<'tcx>,
1000 def_id: DefId,
1001 args: ty::GenericArgsRef<'tcx>,
1002) -> (Vec<VariantInfo>, Option<Size>) {
1003 use itertools::Itertools;
1004
1005 let Variants::Multiple { tag, ref tag_encoding, tag_field, .. } = layout.variants else {
1006 return (::alloc::vec::Vec::new()vec![], None);
1007 };
1008
1009 let coroutine = cx.tcx().coroutine_layout(def_id, args).unwrap();
1010 let upvar_names = cx.tcx().closure_saved_names_of_captured_variables(def_id);
1011
1012 let mut upvars_size = Size::ZERO;
1013 let upvar_fields: Vec<_> = args
1014 .as_coroutine()
1015 .upvar_tys()
1016 .iter()
1017 .zip_eq(upvar_names)
1018 .enumerate()
1019 .map(|(field_idx, (_, name))| {
1020 let field_layout = layout.field(cx, field_idx);
1021 let offset = layout.fields.offset(field_idx);
1022 upvars_size = upvars_size.max(offset + field_layout.size);
1023 FieldInfo {
1024 kind: FieldKind::Upvar,
1025 name: *name,
1026 offset: offset.bytes(),
1027 size: field_layout.size.bytes(),
1028 align: field_layout.align.bytes(),
1029 type_name: None,
1030 }
1031 })
1032 .collect();
1033
1034 let mut variant_infos: Vec<_> = coroutine
1035 .variant_fields
1036 .iter_enumerated()
1037 .map(|(variant_idx, variant_def)| {
1038 let variant_layout = layout.for_variant(cx, variant_idx);
1039 let mut variant_size = Size::ZERO;
1040 let fields = variant_def
1041 .iter()
1042 .enumerate()
1043 .map(|(field_idx, local)| {
1044 let field_name = coroutine.field_tys[*local].debuginfo_name;
1045 let field_layout = variant_layout.field(cx, field_idx);
1046 let offset = variant_layout.fields.offset(field_idx);
1047 variant_size = variant_size.max(offset + field_layout.size);
1049 FieldInfo {
1050 kind: FieldKind::CoroutineLocal,
1051 name: field_name.unwrap_or_else(|| {
1052 Symbol::intern(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!(".coroutine_field{0}",
local.as_usize()))
})format!(".coroutine_field{}", local.as_usize()))
1053 }),
1054 offset: offset.bytes(),
1055 size: field_layout.size.bytes(),
1056 align: field_layout.align.bytes(),
1057 type_name: (field_name.is_none() || field_name == Some(sym::__awaitee))
1060 .then(|| Symbol::intern(&field_layout.ty.to_string())),
1061 }
1062 })
1063 .chain(upvar_fields.iter().copied())
1064 .collect();
1065
1066 if variant_size == Size::ZERO {
1068 variant_size = upvars_size;
1069 }
1070
1071 if layout.fields.offset(tag_field.as_usize()) >= variant_size {
1087 variant_size += match tag_encoding {
1088 TagEncoding::Direct => tag.size(cx),
1089 _ => Size::ZERO,
1090 };
1091 }
1092
1093 VariantInfo {
1094 name: Some(Symbol::intern(&ty::CoroutineArgs::variant_name(variant_idx))),
1095 kind: SizeKind::Exact,
1096 size: variant_size.bytes(),
1097 align: variant_layout.align.bytes(),
1098 fields,
1099 }
1100 })
1101 .collect();
1102
1103 let end_states = variant_infos.drain(1..=2);
1108 let end_states: Vec<_> = end_states.collect();
1109 variant_infos.extend(end_states);
1110
1111 (
1112 variant_infos,
1113 match tag_encoding {
1114 TagEncoding::Direct => Some(tag.size(cx)),
1115 _ => None,
1116 },
1117 )
1118}