fn failExpectedTypeInner(
self: @This(),
T: type,
opt: bool,
node: Zoir.Node.Index,
) error{ ParseZon, OutOfMemory } {
_ = valid_types;
switch (@typeInfo(T)) {
.@"struct" => |@"struct"| if (@"struct".is_tuple) {
if (opt) {
return self.failNode(node, "expected optional tuple");
} else {
return self.failNode(node, "expected tuple");
}
} else {
if (opt) {
return self.failNode(node, "expected optional struct");
} else {
return self.failNode(node, "expected struct");
}
},
.@"union" => if (opt) {
return self.failNode(node, "expected optional union");
} else {
return self.failNode(node, "expected union");
},
.array => if (opt) {
return self.failNode(node, "expected optional array");
} else {
return self.failNode(node, "expected array");
},
.pointer => |pointer| switch (pointer.size) {
.one => return self.failExpectedTypeInner(pointer.child, opt, node),
.slice => {
if (pointer.child == u8 and
pointer.attrs.@"const" and
(pointer.sentinel() == null or pointer.sentinel() == 0) and
(pointer.attrs.@"align" == null or pointer.attrs.@"align" == 1))
{
if (opt) {
return self.failNode(node, "expected optional string");
} else {
return self.failNode(node, "expected string");
}
} else {
if (opt) {
return self.failNode(node, "expected optional array");
} else {
return self.failNode(node, "expected array");
}
}
},
else => comptime unreachable,
},
.vector, .bool, .int, .float => if (opt) {
return self.failNodeFmt(node, "expected type '{s}'", .{@typeName(?T)});
} else {
return self.failNodeFmt(node, "expected type '{s}'", .{@typeName(T)});
},
.@"enum" => if (opt) {
return self.failNode(node, "expected optional enum literal");
} else {
return self.failNode(node, "expected enum literal");
},
.optional => |optional| {
return self.failExpectedTypeInner(optional.child, true, node);
},
else => comptime unreachable,
}
}