pub const SwitchBlock = struct {
/// Either `catch`/`if` or `switch` operand.
raw_operand: Ref,
bits: Bits,
pub const Bits = packed struct(u32) {
/// If true, one or more prongs have multiple items.
has_multi_cases: bool,
/// If true, one or more prongs have ranges.
/// Only valid if `has_multi_cases` is also set.
any_ranges: bool,
has_else: bool,
has_under: bool,
/// If true, at least one prong contains a `continue`.
/// Only valid if `has_label` is set.
has_continue: bool,
// If true, at least one prong has a non-inline payload/tag capture.
any_maybe_runtime_capture: bool,
payload_capture_inst_is_placeholder: bool,
tag_capture_inst_is_placeholder: bool,
scalar_cases_len: ScalarCasesLen,
// NOTE maybe don't steal any more bits from poor `scalar_cases_len`
// and split `Bits` into two parts instead, `raw_operand` surely
// wouldn't mind donating a couple of bits for that purpose...
pub const ScalarCasesLen = u24;
};
pub const ProngInfo = packed struct(u32) {
body_len: u27,
capture: ProngInfo.Capture,
is_inline: bool,
has_tag_capture: bool,
is_comptime_unreach: bool,
pub const Capture = enum(u2) {
none,
by_val,
by_ref,
};
pub const NonErr = packed struct(u32) {
body_len: u29,
capture: ProngInfo.Capture,
operand_is_ref: bool,
};
pub const Else = packed struct(u32) {
body_len: u27,
capture: ProngInfo.Capture,
is_inline: bool,
has_tag_capture: bool,
is_simple_noreturn: bool,
};
};
pub const ItemInfo = packed struct(u32) {
kind: ItemInfo.Kind,
data: u30,
pub const Kind = enum(u2) {
enum_literal,
error_value,
body_len,
under,
};
pub const Unwrapped = union(ItemInfo.Kind) {
enum_literal: Zir.NullTerminatedString,
error_value: Zir.NullTerminatedString,
body_len: u32,
under,
};
pub fn wrap(unwrapped: ItemInfo.Unwrapped) ItemInfo {
const data_uncasted: u32 = switch (unwrapped) {
.enum_literal => |str_index| @backingInt(str_index),
.error_value => |str_index| @backingInt(str_index),
.body_len => |body_len| body_len,
.under => 0,
};
return .{ .kind = unwrapped, .data = @intCast(data_uncasted) };
}
pub fn unwrap(item_info: ItemInfo) ItemInfo.Unwrapped {
return switch (item_info.kind) {
.enum_literal => .{ .enum_literal = @fromBackingInt(@intCast(item_info.data)) },
.error_value => .{ .error_value = @fromBackingInt(@intCast(item_info.data)) },
.body_len => .{ .body_len = item_info.data },
.under => .under,
};
}
pub fn bodyLen(item_info: ItemInfo) ?u32 {
return if (item_info.kind == .body_len) item_info.data else null;
}
};
}
Trailing: