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>)
| 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`). |
| 600 | fn 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)); |
no test coverage detected