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