MCPcopy Create free account
hub / github.com/Rust-GPU/rust-gpu / trans_aggregate

Function trans_aggregate

crates/rustc_codegen_spirv/src/abi.rs:600–671  ·  view source on GitHub ↗

FIXME(eddyb) all `ty: TyAndLayout` variables should be `layout: TyAndLayout`, the type is really more "Layout with Ty" (`.ty` field + `Deref`s to `Layout`).

(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>)

Source from the content-addressed store, hash-verified

598// FIXME(eddyb) all `ty: TyAndLayout` variables should be `layout: TyAndLayout`,
599// the type is really more "Layout with Ty" (`.ty` field + `Deref`s to `Layout`).
600fn trans_aggregate<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>) -> Word {
601 fn create_zst<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>) -> Word {
602 SpirvType::Adt {
603 def_id: def_id_for_spirv_type_adt(ty),
604 size: Some(Size::ZERO),
605 align: Align::from_bytes(0).unwrap(),
606 field_types: &[],
607 field_offsets: &[],
608 field_names: None,
609 }
610 .def_with_name(cx, span, TyLayoutNameKey::from(ty))
611 }
612 match ty.fields {
613 FieldsShape::Primitive => span_bug!(
614 span,
615 "trans_aggregate called for FieldsShape::Primitive layout {:#?}",
616 ty
617 ),
618 FieldsShape::Union(_) => {
619 assert!(!ty.is_unsized(), "{ty:#?}");
620
621 // Represent the `union` with its largest case, which should work
622 // for at least `MaybeUninit<T>` (which is between `T` and `()`),
623 // but also potentially some other ones as well.
624 // NOTE(eddyb) even if long-term this may become a byte array, that
625 // only works for "data types" and not "opaque handles" (images etc.).
626 let largest_case = (0..ty.fields.count())
627 .map(|i| ty.field(cx, i))
628 .max_by_key(|case| case.size);
629
630 if let Some(case) = largest_case {
631 assert_eq!(ty.size, case.size);
632 case.spirv_type(span, cx)
633 } else {
634 assert_eq!(ty.size, Size::ZERO);
635 create_zst(cx, span, ty)
636 }
637 }
638 FieldsShape::Array { stride, count } => {
639 let element_type = ty.field(cx, 0).spirv_type(span, cx);
640 if ty.is_unsized() {
641 // There's a potential for this array to be sized, but the element to be unsized, e.g. `[[u8]; 5]`.
642 // However, I think rust disallows all these cases, so assert this here.
643 assert_eq!(count, 0);
644 SpirvType::RuntimeArray {
645 element: element_type,
646 }
647 .def(span, cx)
648 } else if count == 0 {
649 // spir-v doesn't support zero-sized arrays
650 create_zst(cx, span, ty)
651 } else {
652 let count_const = cx.constant_u32(span, count as u32);
653 let element_spv = cx.lookup_type(element_type);
654 let stride_spv = element_spv
655 .sizeof(cx)
656 .expect("Unexpected unsized type in sized FieldsShape::Array")
657 .align_to(element_spv.alignof(cx));

Callers 1

spirv_typeMethod · 0.85

Calls 9

create_zstFunction · 0.85
trans_structFunction · 0.85
spirv_typeMethod · 0.80
constant_u32Method · 0.80
lookup_typeMethod · 0.80
expectMethod · 0.80
sizeofMethod · 0.80
alignofMethod · 0.80
defMethod · 0.45

Tested by

no test coverage detected