| ... | ... | @@ -3789,6 +3789,39 @@ pub const Type = extern union { |
| 3789 | 3789 | } |
| 3790 | 3790 | } |
| 3791 | 3791 | |
| 3792 | /// Returns true if the type's layout is already resolved and it is safe |
| 3793 | /// to use `abiSize`, `abiAlignment` and `bitSize` on it. |
| 3794 | pub fn layoutIsResolved(ty: Type) bool { |
| 3795 | switch (ty.zigTypeTag()) { |
| 3796 | .Struct => { |
| 3797 | if (ty.castTag(.@"struct")) |struct_ty| { |
| 3798 | return struct_ty.data.haveLayout(); |
| 3799 | } |
| 3800 | return true; |
| 3801 | }, |
| 3802 | .Union => { |
| 3803 | if (ty.cast(Payload.Union)) |union_ty| { |
| 3804 | return union_ty.data.haveLayout(); |
| 3805 | } |
| 3806 | return true; |
| 3807 | }, |
| 3808 | .Array => { |
| 3809 | if (ty.arrayLenIncludingSentinel() == 0) return true; |
| 3810 | return ty.childType().layoutIsResolved(); |
| 3811 | }, |
| 3812 | .Optional => { |
| 3813 | var buf: Type.Payload.ElemType = undefined; |
| 3814 | const payload_ty = ty.optionalChild(&buf); |
| 3815 | return payload_ty.layoutIsResolved(); |
| 3816 | }, |
| 3817 | .ErrorUnion => { |
| 3818 | const payload_ty = ty.errorUnionPayload(); |
| 3819 | return payload_ty.layoutIsResolved(); |
| 3820 | }, |
| 3821 | else => return true, |
| 3822 | } |
| 3823 | } |
| 3824 | |
| 3792 | 3825 | pub fn isSinglePointer(self: Type) bool { |
| 3793 | 3826 | return switch (self.tag()) { |
| 3794 | 3827 | .single_const_pointer, |
| ... | ... | @@ -6498,12 +6531,7 @@ pub const Type = extern union { |
| 6498 | 6531 | // pointee type needs to be resolved more, that needs to be done before calling |
| 6499 | 6532 | // this ptr() function. |
| 6500 | 6533 | if (d.@"align" != 0) canonicalize: { |
| 6501 | | if (d.pointee_type.castTag(.@"struct")) |struct_ty| { |
| 6502 | | if (!struct_ty.data.haveLayout()) break :canonicalize; |
| 6503 | | } |
| 6504 | | if (d.pointee_type.cast(Payload.Union)) |union_ty| { |
| 6505 | | if (!union_ty.data.haveLayout()) break :canonicalize; |
| 6506 | | } |
| 6534 | if (!d.pointee_type.layoutIsResolved()) break :canonicalize; |
| 6507 | 6535 | if (d.@"align" == d.pointee_type.abiAlignment(target)) { |
| 6508 | 6536 | d.@"align" = 0; |
| 6509 | 6537 | } |