1use hir::def_id::DefId;
2use rustc_abi as abi;
3use rustc_abi::Integer::{I8, I32};
4use rustc_abi::Primitive::{self, Float, Int, Pointer};
5use rustc_abi::{
6 AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout,
7 LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding,
8 VariantIdx, Variants, WrappingRange,
9};
10use rustc_hashes::Hash64;
11use rustc_hir as hir;
12use rustc_hir::find_attr;
13use rustc_index::{Idx as _, IndexVec};
14use rustc_middle::bug;
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, sym};
27use tracing::{debug, instrument};
28
29use crate::diagnostics::NonPrimitiveSimdType;
30
31mod invariant;
32
33pub(crate) fn provide(providers: &mut Providers) {
34 *providers = Providers { layout_of, ..*providers };
35}
36
37#[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("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(37u32),
::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(&[]) })
} 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 compiler/rustc_ty_utils/src/layout.rs:43",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(43u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::layout"),
::tracing_core::field::FieldSet::new(&["original_ty"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&original_ty)
as &dyn 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::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")]
38fn layout_of<'tcx>(
39 tcx: TyCtxt<'tcx>,
40 query: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
41) -> Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>> {
42 let PseudoCanonicalInput { typing_env: original_typing_env, value: original_ty } = query;
43 debug!(?original_ty);
44
45 let typing_env = original_typing_env.with_post_analysis_normalized(tcx);
49 let unnormalized_ty = if typing_env != original_typing_env {
52 ty::set_aliases_to_non_rigid(tcx, original_ty)
53 } else {
54 ty::Unnormalized::new_wip(original_ty)
55 };
56
57 let normalized_ty = match tcx.try_normalize_erasing_regions(typing_env, unnormalized_ty) {
62 Ok(t) => t,
63 Err(normalization_error) => {
64 return Err(tcx.arena.alloc(LayoutError::NormalizationFailure(
65 unnormalized_ty.skip_normalization(),
66 normalization_error,
67 )));
68 }
69 };
70
71 if normalized_ty != original_ty {
72 return tcx.layout_of(typing_env.as_query_input(normalized_ty));
74 }
75
76 match typing_env.typing_mode() {
77 ty::TypingMode::Codegen => {
78 let with_postanalysis =
79 ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis);
80 let res = tcx.layout_of(with_postanalysis.as_query_input(normalized_ty));
81 match res {
82 Err(LayoutError::TooGeneric(_)) => {}
83 _ => return res,
84 };
85 }
86 ty::TypingMode::Coherence
87 | ty::TypingMode::Typeck { .. }
88 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
89 | ty::TypingMode::PostBorrowck { .. }
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.caller_bounds().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(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_middle::util::bug::bug_fmt(format_args!("failed to normalize const, but it is not generic: {0:?}",
ct));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_middle::util::bug::bug_fmt(format_args!("layout_of: unexpected const: {0:?}",
ct));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.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_middle::util::bug::bug_fmt(format_args!("pattern type with range but not scalar layout: {0:?}, {1:?}",
ty, layout))bug!("pattern type with range but not scalar layout: {ty:?}, {layout:?}")
291 }
292 }
293 ty::PatternKind::NotNull => {
294 if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
295 &mut layout.backend_repr
296 {
297 scalar.valid_range_mut().start = 1;
298 let niche = Niche {
299 offset: Size::ZERO,
300 value: scalar.primitive(),
301 valid_range: scalar.valid_range(cx),
302 };
303
304 layout.largest_niche = Some(niche);
305 } else {
306 ::rustc_middle::util::bug::bug_fmt(format_args!("pattern type with `!null` pattern but not scalar/pair layout: {0:?}, {1:?}",
ty, layout))bug!(
307 "pattern type with `!null` pattern but not scalar/pair layout: {ty:?}, {layout:?}"
308 )
309 }
310 }
311
312 ty::PatternKind::Or(variants) => match *variants[0] {
313 ty::PatternKind::Range { .. } => {
314 if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr {
315 let variants: Result<Vec<_>, _> = variants
316 .iter()
317 .map(|pat| match *pat {
318 ty::PatternKind::Range { start, end } => Ok((
319 extract_const_value(cx, ty, start)
320 .unwrap()
321 .try_to_bits(tcx, cx.typing_env)
322 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
323 extract_const_value(cx, ty, end)
324 .unwrap()
325 .try_to_bits(tcx, cx.typing_env)
326 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
327 )),
328 ty::PatternKind::NotNull | ty::PatternKind::Or(_) => {
329 {
::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")
330 }
331 })
332 .collect();
333 let mut variants = variants?;
334 if !scalar.is_signed() {
335 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!(
336 "only signed integer base types are allowed for or-pattern pattern types at present"
337 ));
338
339 return Err(error(cx, LayoutError::ReferencesError(guar)));
340 }
341 variants.sort();
342 if variants.len() != 2 {
343 let guar = tcx
344 .dcx()
345 .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"));
346
347 return Err(error(cx, LayoutError::ReferencesError(guar)));
348 }
349
350 let mut first = variants[0];
352 let mut second = variants[1];
353 if second.0
354 == layout.size.truncate(layout.size.signed_int_min() as u128)
355 {
356 (second, first) = (first, second);
357 }
358
359 if layout.size.sign_extend(first.1) >= layout.size.sign_extend(second.0)
360 {
361 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!(
362 "only non-overlapping pattern type ranges are allowed at present"
363 ));
364
365 return Err(error(cx, LayoutError::ReferencesError(guar)));
366 }
367 if layout.size.signed_int_max() as u128 != second.1 {
368 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!(
369 "one pattern needs to end at `{ty}::MAX`, but was {} instead",
370 second.1
371 ));
372
373 return Err(error(cx, LayoutError::ReferencesError(guar)));
374 }
375
376 scalar.valid_range_mut().start = second.0;
378 scalar.valid_range_mut().end = first.1;
379
380 let niche = Niche {
381 offset: Size::ZERO,
382 value: scalar.primitive(),
383 valid_range: scalar.valid_range(cx),
384 };
385
386 layout.largest_niche = Some(niche);
387 } else {
388 ::rustc_middle::util::bug::bug_fmt(format_args!("pattern type with range but not scalar layout: {0:?}, {1:?}",
ty, layout))bug!(
389 "pattern type with range but not scalar layout: {ty:?}, {layout:?}"
390 )
391 }
392 }
393 ty::PatternKind::NotNull => ::rustc_middle::util::bug::bug_fmt(format_args!("or patterns can\'t contain `!null` patterns"))bug!("or patterns can't contain `!null` patterns"),
394 ty::PatternKind::Or(..) => ::rustc_middle::util::bug::bug_fmt(format_args!("patterns cannot have nested or patterns"))bug!("patterns cannot have nested or patterns"),
395 },
396 }
397 layout.fields = FieldsShape::Arbitrary {
402 offsets: [Size::ZERO].into_iter().collect(),
403 in_memory_order: [FieldIdx::new(0)].into_iter().collect(),
404 };
405 tcx.mk_layout(layout)
406 }
407
408 ty::Bool => tcx.mk_layout(LayoutData::scalar(
410 cx,
411 Scalar::Initialized {
412 value: Int(I8, false),
413 valid_range: WrappingRange { start: 0, end: 1 },
414 },
415 )),
416 ty::Char => tcx.mk_layout(LayoutData::scalar(
417 cx,
418 Scalar::Initialized {
419 value: Int(I32, false),
420 valid_range: WrappingRange { start: 0, end: 0x10FFFF },
421 },
422 )),
423 ty::Int(ity) => scalar(Int(abi::Integer::from_int_ty(dl, ity), true)),
424 ty::Uint(ity) => scalar(Int(abi::Integer::from_uint_ty(dl, ity), false)),
425 ty::Float(fty) => scalar(Float(abi::Float::from_float_ty(fty))),
426 ty::FnPtr(..) => {
427 let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
428 ptr.valid_range_mut().start = 1;
429 tcx.mk_layout(LayoutData::scalar(cx, ptr))
430 }
431
432 ty::Never => tcx.mk_layout(LayoutData::never_type(cx)),
434
435 ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
437 let mut data_ptr = scalar_unit(Pointer(AddressSpace::ZERO));
438 if !ty.is_raw_ptr() {
439 data_ptr.valid_range_mut().start = 1;
440 }
441
442 if pointee.is_sized(tcx, cx.typing_env) {
443 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
444 }
445
446 let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
447 let pointee_metadata =
448 Ty::new_projection(tcx, ty::IsRigid::No, metadata_def_id, [pointee]);
449 let metadata_ty = match tcx.try_normalize_erasing_regions(
450 cx.typing_env,
451 Unnormalized::new_wip(pointee_metadata),
452 ) {
453 Ok(metadata_ty) => metadata_ty,
454 Err(mut err) => {
455 match tcx.try_normalize_erasing_regions(
464 cx.typing_env,
465 Unnormalized::new_wip(tcx.struct_tail_raw(
466 pointee,
467 &ObligationCause::dummy(),
468 |ty| ty.skip_norm_wip(),
469 || {},
470 )),
471 ) {
472 Ok(_) => {}
473 Err(better_err) => {
474 err = better_err;
475 }
476 }
477 return Err(error(cx, LayoutError::NormalizationFailure(pointee, err)));
478 }
479 };
480
481 let metadata_layout = cx.layout_of(metadata_ty)?;
482 if metadata_layout.is_1zst() {
484 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
485 }
486
487 let BackendRepr::Scalar(metadata) = metadata_layout.backend_repr else {
488 return Err(error(cx, LayoutError::Unknown(pointee)));
489 };
490
491 metadata
492 } else {
493 let unsized_part = tcx.struct_tail_for_codegen(pointee, cx.typing_env);
494
495 match unsized_part.kind() {
496 ty::Foreign(..) => {
497 return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr)));
498 }
499 ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
500 ty::Dynamic(..) => {
501 let mut vtable = scalar_unit(Pointer(AddressSpace::ZERO));
502 vtable.valid_range_mut().start = 1;
503 vtable
504 }
505 _ => {
506 return Err(error(cx, LayoutError::Unknown(pointee)));
507 }
508 }
509 };
510
511 tcx.mk_layout(LayoutData::scalar_pair(cx, data_ptr, metadata))
513 }
514
515 ty::Array(element, count) => {
517 let count = extract_const_value(cx, ty, count)?
518 .try_to_target_usize(tcx)
519 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
520
521 let element = cx.layout_of(element)?;
522 map_layout(cx.calc.array_like(&element, Some(count)))?
523 }
524 ty::Slice(element) => {
525 let element = cx.layout_of(element)?;
526 map_layout(cx.calc.array_like(&element, None).map(|mut layout| {
527 layout.randomization_seed = Hash64::new(0x2dcba99c39784102);
529 layout
530 }))?
531 }
532 ty::Str => {
533 let element = scalar(Int(I8, false));
534 map_layout(cx.calc.array_like(&element, None).map(|mut layout| {
535 layout.randomization_seed = Hash64::new(0xc1325f37d127be22);
537 layout
538 }))?
539 }
540
541 ty::FnDef(..) | ty::Dynamic(_, _) | ty::Foreign(..) => {
543 let sized = #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::FnDef(..) => true,
_ => false,
}matches!(ty.kind(), ty::FnDef(..));
544 tcx.mk_layout(LayoutData::unit(cx, sized))
545 }
546
547 ty::Coroutine(def_id, args) => {
548 match cx.typing_env.typing_mode() {
549 ty::TypingMode::Codegen => {}
550 ty::TypingMode::Coherence
551 | ty::TypingMode::Typeck { .. }
552 | ty::TypingMode::PostTypeckUntilBorrowck { .. }
553 | ty::TypingMode::PostBorrowck { .. }
554 | ty::TypingMode::ErasedNotCoherence(_)
555 | ty::TypingMode::PostAnalysis => {
556 return Err(error(cx, LayoutError::TooGeneric(ty)));
557 }
558 }
559
560 use rustc_middle::ty::layout::PrimitiveExt as _;
561
562 let info = tcx.coroutine_layout(def_id, args)?;
563
564 let local_layouts = info
565 .field_tys
566 .iter()
567 .map(|local| {
568 let field_ty = EarlyBinder::bind(tcx, local.ty);
569 let uninit_ty =
570 Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args).skip_norm_wip());
571 cx.spanned_layout_of(uninit_ty, local.source_info.span)
572 })
573 .try_collect::<IndexVec<_, _>>()?;
574
575 let prefix_layouts = args
576 .as_coroutine()
577 .prefix_tys()
578 .iter()
579 .map(|ty| cx.layout_of(ty))
580 .try_collect::<IndexVec<_, _>>()?;
581
582 let layout = cx
583 .calc
584 .coroutine(
585 &local_layouts,
586 prefix_layouts,
587 &info.variant_fields,
588 &info.storage_conflicts,
589 |tag| TyAndLayout {
590 ty: tag.primitive().to_ty(tcx),
591 layout: tcx.mk_layout(LayoutData::scalar(cx, tag)),
592 },
593 )
594 .map(|mut layout| {
595 layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash();
597 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:597",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(597u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("coroutine layout ({0:?}): {1:#?}",
ty, layout) as &dyn Value))])
});
} else { ; }
};debug!("coroutine layout ({:?}): {:#?}", ty, layout);
598 layout
599 });
600 map_layout(layout)?
601 }
602
603 ty::Closure(_, args) => univariant(args.as_closure().upvar_tys(), StructKind::AlwaysSized)?,
604
605 ty::CoroutineClosure(_, args) => {
606 univariant(args.as_coroutine_closure().upvar_tys(), StructKind::AlwaysSized)?
607 }
608
609 ty::Tuple(tys) => {
610 let kind =
611 if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
612
613 univariant(tys, kind)?
614 }
615
616 ty::Adt(def, _args) if def.repr().scalable() => {
626 let Some((element_count, element_ty, number_of_vectors)) =
627 ty.scalable_vector_parts(tcx)
628 else {
629 let guar = tcx
630 .dcx()
631 .delayed_bug("`#[rustc_scalable_vector]` was applied to an invalid type");
632 return Err(error(cx, LayoutError::ReferencesError(guar)));
633 };
634
635 let element_layout = cx.layout_of(element_ty)?;
636 map_layout(cx.calc.scalable_vector_type(
637 element_layout,
638 element_count as u64,
639 number_of_vectors,
640 ))?
641 }
642
643 ty::Adt(def, args) if def.repr().simd() => {
645 let Some(ty::Array(e_ty, e_len)) = def
651 .is_struct()
652 .then(|| &def.variant(FIRST_VARIANT).fields)
653 .filter(|fields| fields.len() == 1)
654 .map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).skip_norm_wip().kind())
655 else {
656 let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT");
658 return Err(error(cx, LayoutError::ReferencesError(guar)));
659 };
660
661 let e_len = extract_const_value(cx, ty, e_len)?
662 .try_to_target_usize(tcx)
663 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
664
665 let e_ly = cx.layout_of(e_ty)?;
666
667 if let Some(limit) = {
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def.did(), &tcx)
{
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(RustcSimdMonomorphizeLaneLimit(limit))
=> {
break 'done Some(limit);
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(
669 tcx, def.did(),
670 RustcSimdMonomorphizeLaneLimit(limit) => limit
671 ) {
672 if !limit.value_within_limit(e_len as usize) {
673 return Err(map_error(
674 &cx,
675 ty,
676 rustc_abi::LayoutCalculatorError::OversizedSimdType {
677 max_lanes: limit.0 as u64,
678 },
679 ));
680 }
681 }
682
683 map_layout(cx.calc.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 is_special_no_niche = def.is_unsafe_cell() || def.is_unsafe_pinned();
714
715 let discr_range_of_repr =
716 |min, max| abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min, max);
717
718 let discriminants_iter = || {
719 def.is_enum()
720 .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
721 .into_iter()
722 .flatten()
723 };
724
725 let maybe_unsized = def.is_struct()
726 && def.non_enum_variant().tail_opt().is_some_and(|last_field| {
727 let typing_env = ty::TypingEnv::new(
728 tcx.param_env_normalized_for_post_analysis(def.did()),
729 cx.typing_env.typing_mode(),
730 );
731 !tcx.type_of(last_field.did)
732 .instantiate_identity()
733 .skip_norm_wip()
734 .is_sized(tcx, typing_env)
735 });
736
737 let layout = cx
738 .calc
739 .layout_of_struct_or_enum(
740 &def.repr(),
741 &variants,
742 def.is_enum(),
743 is_special_no_niche,
744 discr_range_of_repr,
745 discriminants_iter(),
746 !maybe_unsized,
747 )
748 .map_err(|err| map_error(cx, ty, err))?;
749
750 if !maybe_unsized && layout.is_unsized() {
751 ::rustc_middle::util::bug::bug_fmt(format_args!("got unsized layout for type that cannot be unsized {0:?}: {1:#?}",
ty, layout));bug!("got unsized layout for type that cannot be unsized {ty:?}: {layout:#?}");
752 }
753
754 if truecfg!(debug_assertions)
756 && maybe_unsized
757 && def
758 .non_enum_variant()
759 .tail()
760 .ty(tcx, args)
761 .skip_norm_wip()
762 .is_sized(tcx, cx.typing_env)
763 {
764 let mut variants = variants;
765 let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();
766 *variants[FIRST_VARIANT].raw.last_mut().unwrap() = tail_replacement;
767
768 let Ok(unsized_layout) = cx.calc.layout_of_struct_or_enum(
769 &def.repr(),
770 &variants,
771 def.is_enum(),
772 is_special_no_niche,
773 discr_range_of_repr,
774 discriminants_iter(),
775 !maybe_unsized,
776 ) else {
777 ::rustc_middle::util::bug::bug_fmt(format_args!("failed to compute unsized layout of {0:?}",
ty));bug!("failed to compute unsized layout of {ty:?}");
778 };
779
780 let FieldsShape::Arbitrary { offsets: sized_offsets, .. } = &layout.fields else {
781 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected FieldsShape for sized layout of {1:?}: {0:?}",
layout.fields, ty));bug!("unexpected FieldsShape for sized layout of {ty:?}: {:?}", layout.fields);
782 };
783 let FieldsShape::Arbitrary { offsets: unsized_offsets, .. } =
784 &unsized_layout.fields
785 else {
786 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected FieldsShape for unsized layout of {1:?}: {0:?}",
unsized_layout.fields, ty));bug!(
787 "unexpected FieldsShape for unsized layout of {ty:?}: {:?}",
788 unsized_layout.fields
789 );
790 };
791
792 let (sized_tail, sized_fields) = sized_offsets.raw.split_last().unwrap();
793 let (unsized_tail, unsized_fields) = unsized_offsets.raw.split_last().unwrap();
794
795 if sized_fields != unsized_fields {
796 ::rustc_middle::util::bug::bug_fmt(format_args!("unsizing {0:?} changed field order!\n{1:?}\n{2:?}",
ty, layout, unsized_layout));bug!("unsizing {ty:?} changed field order!\n{layout:?}\n{unsized_layout:?}");
797 }
798
799 if sized_tail < unsized_tail {
800 ::rustc_middle::util::bug::bug_fmt(format_args!("unsizing {0:?} moved tail backwards!\n{1:?}\n{2:?}",
ty, layout, unsized_layout));bug!("unsizing {ty:?} moved tail backwards!\n{layout:?}\n{unsized_layout:?}");
801 }
802 }
803
804 tcx.mk_layout(layout)
805 }
806
807 ty::UnsafeBinder(bound_ty) => {
808 let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
809 cx.layout_of(ty)?.layout
810 }
811
812 ty::Param(_) | ty::Placeholder(..) => {
814 return Err(error(cx, LayoutError::TooGeneric(ty)));
815 }
816
817 ty::Alias(..) => {
818 let err = if ty.has_param() || !cx.typing_env.param_env.caller_bounds().is_empty() {
829 LayoutError::TooGeneric(ty)
830 } else {
831 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!(
832 "unexpected rigid alias in layout_of after normalization: {ty:?}"
833 )))
834 };
835 return Err(error(cx, err));
836 }
837
838 ty::Bound(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => {
839 ::rustc_middle::util::bug::bug_fmt(format_args!("layout_of: unexpected type `{0}`",
ty))bug!("layout_of: unexpected type `{ty}`")
841 }
842 })
843}
844
845fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) {
846 if layout.ty.has_non_region_param() || !cx.typing_env.param_env.caller_bounds().is_empty() {
850 return;
851 }
852
853 let record = |kind, packed, opt_discr_size, variants| {
855 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));
856 cx.tcx().sess.code_stats.record_type_size(
857 kind,
858 type_desc,
859 layout.align.abi,
860 layout.size,
861 packed,
862 opt_discr_size,
863 variants,
864 );
865 };
866
867 match *layout.ty.kind() {
868 ty::Adt(adt_def, _) => {
869 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:869",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(869u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size t: `{0:?}` process adt",
layout.ty) as &dyn Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` process adt", layout.ty);
870 let adt_kind = adt_def.adt_kind();
871 let adt_packed = adt_def.repr().pack.is_some();
872 let (variant_infos, opt_discr_size) = variant_info_for_adt(cx, layout, adt_def);
873 record(adt_kind.into(), adt_packed, opt_discr_size, variant_infos);
874 }
875
876 ty::Coroutine(def_id, args) => {
877 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:877",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(877u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size t: `{0:?}` record coroutine",
layout.ty) as &dyn Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` record coroutine", layout.ty);
878 let (variant_infos, opt_discr_size) =
880 variant_info_for_coroutine(cx, layout, def_id, args);
881 record(DataTypeKind::Coroutine, false, opt_discr_size, variant_infos);
882 }
883
884 ty::Closure(..) => {
885 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:885",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(885u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size t: `{0:?}` record closure",
layout.ty) as &dyn Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` record closure", layout.ty);
886 record(DataTypeKind::Closure, false, None, ::alloc::vec::Vec::new()vec![]);
887 }
888
889 _ => {
890 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:890",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(890u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size t: `{0:?}` skip non-nominal",
layout.ty) as &dyn Value))])
});
} else { ; }
};debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
891 }
892 };
893}
894
895fn variant_info_for_adt<'tcx>(
896 cx: &LayoutCx<'tcx>,
897 layout: TyAndLayout<'tcx>,
898 adt_def: AdtDef<'tcx>,
899) -> (Vec<VariantInfo>, Option<Size>) {
900 let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| {
901 let mut min_size = Size::ZERO;
902 let field_info: Vec<_> = flds
903 .iter()
904 .enumerate()
905 .map(|(i, &name)| {
906 let field_layout = layout.field(cx, i);
907 let offset = layout.fields.offset(i);
908 min_size = min_size.max(offset + field_layout.size);
909 FieldInfo {
910 kind: FieldKind::AdtField,
911 name,
912 offset: offset.bytes(),
913 size: field_layout.size.bytes(),
914 align: field_layout.align.bytes(),
915 type_name: None,
916 }
917 })
918 .collect();
919
920 VariantInfo {
921 name: n,
922 kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact },
923 align: layout.align.bytes(),
924 size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() },
925 fields: field_info,
926 }
927 };
928
929 match layout.variants {
930 Variants::Empty => (::alloc::vec::Vec::new()vec![], None),
931
932 Variants::Single { index } => {
933 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:933",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(933u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size `{0:#?}` variant {1}",
layout, adt_def.variant(index).name) as &dyn Value))])
});
} else { ; }
};debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name);
934 let variant_def = &adt_def.variant(index);
935 let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
936 (::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)
937 }
938
939 Variants::Multiple { tag, ref tag_encoding, .. } => {
940 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/layout.rs:940",
"rustc_ty_utils::layout", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/layout.rs"),
::tracing_core::__macro_support::Option::Some(940u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("print-type-size `{0:#?}` adt general variants def {1}",
layout.ty, adt_def.variants().len()) as &dyn Value))])
});
} else { ; }
};debug!(
941 "print-type-size `{:#?}` adt general variants def {}",
942 layout.ty,
943 adt_def.variants().len()
944 );
945 let variant_infos: Vec<_> = adt_def
946 .variants()
947 .iter_enumerated()
948 .map(|(i, variant_def)| {
949 let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect();
950 build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i))
951 })
952 .collect();
953
954 (
955 variant_infos,
956 match tag_encoding {
957 TagEncoding::Direct => Some(tag.size(cx)),
958 _ => None,
959 },
960 )
961 }
962 }
963}
964
965fn variant_info_for_coroutine<'tcx>(
966 cx: &LayoutCx<'tcx>,
967 layout: TyAndLayout<'tcx>,
968 def_id: DefId,
969 args: ty::GenericArgsRef<'tcx>,
970) -> (Vec<VariantInfo>, Option<Size>) {
971 use itertools::Itertools;
972
973 let Variants::Multiple { tag, ref tag_encoding, tag_field, .. } = layout.variants else {
974 return (::alloc::vec::Vec::new()vec![], None);
975 };
976
977 let coroutine = cx.tcx().coroutine_layout(def_id, args).unwrap();
978 let upvar_names = cx.tcx().closure_saved_names_of_captured_variables(def_id);
979
980 let mut upvars_size = Size::ZERO;
981 let upvar_fields: Vec<_> = args
982 .as_coroutine()
983 .upvar_tys()
984 .iter()
985 .zip_eq(upvar_names)
986 .enumerate()
987 .map(|(field_idx, (_, name))| {
988 let field_layout = layout.field(cx, field_idx);
989 let offset = layout.fields.offset(field_idx);
990 upvars_size = upvars_size.max(offset + field_layout.size);
991 FieldInfo {
992 kind: FieldKind::Upvar,
993 name: *name,
994 offset: offset.bytes(),
995 size: field_layout.size.bytes(),
996 align: field_layout.align.bytes(),
997 type_name: None,
998 }
999 })
1000 .collect();
1001
1002 let mut variant_infos: Vec<_> = coroutine
1003 .variant_fields
1004 .iter_enumerated()
1005 .map(|(variant_idx, variant_def)| {
1006 let variant_layout = layout.for_variant(cx, variant_idx);
1007 let mut variant_size = Size::ZERO;
1008 let fields = variant_def
1009 .iter()
1010 .enumerate()
1011 .map(|(field_idx, local)| {
1012 let field_name = coroutine.field_tys[*local].debuginfo_name;
1013 let field_layout = variant_layout.field(cx, field_idx);
1014 let offset = variant_layout.fields.offset(field_idx);
1015 variant_size = variant_size.max(offset + field_layout.size);
1017 FieldInfo {
1018 kind: FieldKind::CoroutineLocal,
1019 name: field_name.unwrap_or_else(|| {
1020 Symbol::intern(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!(".coroutine_field{0}",
local.as_usize()))
})format!(".coroutine_field{}", local.as_usize()))
1021 }),
1022 offset: offset.bytes(),
1023 size: field_layout.size.bytes(),
1024 align: field_layout.align.bytes(),
1025 type_name: (field_name.is_none() || field_name == Some(sym::__awaitee))
1028 .then(|| Symbol::intern(&field_layout.ty.to_string())),
1029 }
1030 })
1031 .chain(upvar_fields.iter().copied())
1032 .collect();
1033
1034 if variant_size == Size::ZERO {
1036 variant_size = upvars_size;
1037 }
1038
1039 if layout.fields.offset(tag_field.as_usize()) >= variant_size {
1055 variant_size += match tag_encoding {
1056 TagEncoding::Direct => tag.size(cx),
1057 _ => Size::ZERO,
1058 };
1059 }
1060
1061 VariantInfo {
1062 name: Some(Symbol::intern(&ty::CoroutineArgs::variant_name(variant_idx))),
1063 kind: SizeKind::Exact,
1064 size: variant_size.bytes(),
1065 align: variant_layout.align.bytes(),
1066 fields,
1067 }
1068 })
1069 .collect();
1070
1071 let end_states = variant_infos.drain(1..=2);
1076 let end_states: Vec<_> = end_states.collect();
1077 variant_infos.extend(end_states);
1078
1079 (
1080 variant_infos,
1081 match tag_encoding {
1082 TagEncoding::Direct => Some(tag.size(cx)),
1083 _ => None,
1084 },
1085 )
1086}