mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 23:22:44 +00:00
parent
f205d23e65
commit
a3f6a58c77
@ -5862,7 +5862,7 @@ pub fn main() void {
|
||||
|
||||
{#code_begin|syntax#}
|
||||
/// Calls print and then flushes the buffer.
|
||||
pub fn printf(self: *OutStream, comptime format: []const u8, args: ...) anyerror!void {
|
||||
pub fn printf(self: *OutStream, comptime format: []const u8, args: var) anyerror!void {
|
||||
const State = enum {
|
||||
Start,
|
||||
OpenBrace,
|
||||
@ -8277,7 +8277,6 @@ test "integer truncation" {
|
||||
<li>{#link|union#}</li>
|
||||
<li>{#link|Functions#}</li>
|
||||
<li>BoundFn</li>
|
||||
<li>ArgTuple</li>
|
||||
<li>{#link|struct#}</li>
|
||||
</ul>
|
||||
{#header_close#}
|
||||
@ -8310,7 +8309,6 @@ pub const TypeId = enum {
|
||||
Fn,
|
||||
Block,
|
||||
BoundFn,
|
||||
ArgTuple,
|
||||
Opaque,
|
||||
};
|
||||
{#code_end#}
|
||||
@ -8343,7 +8341,6 @@ pub const TypeInfo = union(TypeId) {
|
||||
Union: Union,
|
||||
Fn: Fn,
|
||||
BoundFn: Fn,
|
||||
ArgTuple: void,
|
||||
Opaque: void,
|
||||
Promise: Promise,
|
||||
Vector: Vector,
|
||||
|
@ -116,7 +116,6 @@ pub const TypeInfo = union(enum) {
|
||||
Union: Union,
|
||||
Fn: Fn,
|
||||
BoundFn: Fn,
|
||||
ArgTuple: void,
|
||||
Opaque: void,
|
||||
Frame: void,
|
||||
AnyFrame: AnyFrame,
|
||||
|
@ -94,9 +94,7 @@ pub fn format(
|
||||
args: var,
|
||||
) Errors!void {
|
||||
const ArgSetType = @IntType(false, 32);
|
||||
const args_fields = std.meta.fields(@typeOf(args));
|
||||
const args_len = args_fields.len;
|
||||
if (args_len > ArgSetType.bit_count) {
|
||||
if (args.len > ArgSetType.bit_count) {
|
||||
@compileError("32 arguments max are supported per format call");
|
||||
}
|
||||
|
||||
@ -160,14 +158,14 @@ pub fn format(
|
||||
maybe_pos_arg.? += c - '0';
|
||||
specifier_start = i + 1;
|
||||
|
||||
if (maybe_pos_arg.? >= args_len) {
|
||||
if (maybe_pos_arg.? >= args.len) {
|
||||
@compileError("Positional value refers to non-existent argument");
|
||||
}
|
||||
},
|
||||
'}' => {
|
||||
const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
|
||||
|
||||
if (arg_to_print >= args_len) {
|
||||
if (arg_to_print >= args.len) {
|
||||
@compileError("Too few arguments");
|
||||
}
|
||||
|
||||
@ -304,7 +302,7 @@ pub fn format(
|
||||
used_pos_args |= 1 << i;
|
||||
}
|
||||
|
||||
if (@popCount(ArgSetType, used_pos_args) != args_len) {
|
||||
if (@popCount(ArgSetType, used_pos_args) != args.len) {
|
||||
@compileError("Unused arguments");
|
||||
}
|
||||
if (state != State.Start) {
|
||||
|
@ -79,7 +79,6 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
|
||||
.NoReturn,
|
||||
.Opaque,
|
||||
.Undefined,
|
||||
.ArgTuple,
|
||||
.Void,
|
||||
.Null,
|
||||
.BoundFn,
|
||||
|
@ -1194,7 +1194,7 @@
|
||||
// This is just for debugging purposes, not needed to function
|
||||
var assertList = ["Type","Void","Bool","NoReturn","Int","Float","Pointer","Array","Struct",
|
||||
"ComptimeFloat","ComptimeInt","Undefined","Null","Optional","ErrorUnion","ErrorSet","Enum",
|
||||
"Union","Fn","BoundFn","ArgTuple","Opaque","Frame","AnyFrame","Vector","EnumLiteral"];
|
||||
"Union","Fn","BoundFn","Opaque","Frame","AnyFrame","Vector","EnumLiteral"];
|
||||
for (var i = 0; i < assertList.length; i += 1) {
|
||||
if (map[assertList[i]] == null) throw new Error("No type kind '" + assertList[i] + "' found");
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
|
||||
switch (@typeInfo(@typeOf(actual))) {
|
||||
.NoReturn,
|
||||
.BoundFn,
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
|
@ -41,7 +41,6 @@ pub const Type = struct {
|
||||
.Enum => @fieldParentPtr(Enum, "base", base).destroy(comp),
|
||||
.Union => @fieldParentPtr(Union, "base", base).destroy(comp),
|
||||
.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(comp),
|
||||
.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
|
||||
.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
|
||||
.Frame => @fieldParentPtr(Frame, "base", base).destroy(comp),
|
||||
.AnyFrame => @fieldParentPtr(AnyFrame, "base", base).destroy(comp),
|
||||
@ -76,7 +75,6 @@ pub const Type = struct {
|
||||
.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.ArgTuple => unreachable,
|
||||
.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Frame => return @fieldParentPtr(Frame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.AnyFrame => return @fieldParentPtr(AnyFrame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
@ -93,7 +91,6 @@ pub const Type = struct {
|
||||
.Undefined,
|
||||
.Null,
|
||||
.BoundFn,
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
=> unreachable,
|
||||
|
||||
@ -128,7 +125,6 @@ pub const Type = struct {
|
||||
.Undefined,
|
||||
.Null,
|
||||
.BoundFn,
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
=> unreachable,
|
||||
|
||||
@ -1004,14 +1000,6 @@ pub const Type = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const ArgTuple = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ArgTuple, comp: *Compilation) void {
|
||||
comp.gpa().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Opaque = struct {
|
||||
base: Type,
|
||||
|
||||
|
@ -1471,7 +1471,6 @@ enum ZigTypeId {
|
||||
ZigTypeIdUnion,
|
||||
ZigTypeIdFn,
|
||||
ZigTypeIdBoundFn,
|
||||
ZigTypeIdArgTuple,
|
||||
ZigTypeIdOpaque,
|
||||
ZigTypeIdFnFrame,
|
||||
ZigTypeIdAnyFrame,
|
||||
@ -2039,7 +2038,6 @@ struct CodeGen {
|
||||
ZigType *entry_null;
|
||||
ZigType *entry_var;
|
||||
ZigType *entry_global_error_set;
|
||||
ZigType *entry_arg_tuple;
|
||||
ZigType *entry_enum_literal;
|
||||
ZigType *entry_any_frame;
|
||||
} builtin_types;
|
||||
|
@ -323,7 +323,6 @@ AstNode *type_decl_node(ZigType *type_entry) {
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdAnyFrame:
|
||||
return nullptr;
|
||||
@ -392,7 +391,6 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdAnyFrame:
|
||||
return true;
|
||||
@ -1558,7 +1556,6 @@ static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigT
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
@ -1661,7 +1658,6 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
@ -1786,12 +1782,9 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
if (fn_type_id.cc == CallingConventionC) {
|
||||
fn_type_id.param_count = fn_type_id.next_param_index;
|
||||
continue;
|
||||
} else if (calling_convention_allows_zig_types(fn_type_id.cc)) {
|
||||
return get_generic_fn_type(g, &fn_type_id);
|
||||
} else {
|
||||
add_node_error(g, param_node,
|
||||
buf_sprintf("var args not allowed in function with calling convention '%s'",
|
||||
calling_convention_name(fn_type_id.cc)));
|
||||
buf_sprintf("var args only allowed in functions with C calling convention"));
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
} else if (param_node->data.param_decl.var_token != nullptr) {
|
||||
@ -1838,7 +1831,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
add_node_error(g, param_node->data.param_decl.type,
|
||||
buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
|
||||
@ -1913,7 +1905,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
add_node_error(g, fn_proto->return_type,
|
||||
buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
|
||||
return g->builtin_types.entry_invalid;
|
||||
@ -1963,7 +1954,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
zig_unreachable();
|
||||
|
||||
@ -3720,7 +3710,6 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
|
||||
buf_ptr(&type_entry->name)));
|
||||
@ -4275,7 +4264,6 @@ bool is_container(ZigType *type_entry) {
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdFnFrame:
|
||||
@ -4982,7 +4970,6 @@ bool handle_is_ptr(ZigType *type_entry) {
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdUnreachable:
|
||||
@ -5201,9 +5188,6 @@ static uint32_t hash_const_val(ZigValue *const_val) {
|
||||
memcpy(&ints[0], &f128, 16);
|
||||
return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb;
|
||||
}
|
||||
case ZigTypeIdArgTuple:
|
||||
return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
|
||||
(uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;
|
||||
case ZigTypeIdFn:
|
||||
assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
|
||||
assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
|
||||
@ -5357,9 +5341,6 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
|
||||
|
||||
case ZigTypeIdUnion:
|
||||
return can_mutate_comptime_var_state(value->data.x_union.payload);
|
||||
|
||||
case ZigTypeIdArgTuple:
|
||||
zig_panic("TODO var args at comptime is currently not supported");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5400,9 +5381,6 @@ static bool return_type_is_cacheable(ZigType *return_type) {
|
||||
|
||||
case ZigTypeIdErrorUnion:
|
||||
return return_type_is_cacheable(return_type->data.error_union.payload_type);
|
||||
|
||||
case ZigTypeIdArgTuple:
|
||||
zig_panic("TODO var args at comptime is currently not supported");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5540,7 +5518,6 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
case ZigTypeIdEnumLiteral:
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBool:
|
||||
@ -5626,7 +5603,6 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
return ReqCompTimeYes;
|
||||
case ZigTypeIdArray:
|
||||
return type_requires_comptime(g, ty->data.array.child_type);
|
||||
@ -5918,20 +5894,6 @@ ZigValue *create_const_ptr_hard_coded_addr(CodeGen *g, ZigType *pointee_type,
|
||||
return const_val;
|
||||
}
|
||||
|
||||
void init_const_arg_tuple(CodeGen *g, ZigValue *const_val, size_t arg_index_start, size_t arg_index_end) {
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = g->builtin_types.entry_arg_tuple;
|
||||
const_val->data.x_arg_tuple.start_index = arg_index_start;
|
||||
const_val->data.x_arg_tuple.end_index = arg_index_end;
|
||||
}
|
||||
|
||||
ZigValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {
|
||||
ZigValue *const_val = create_const_vals(1);
|
||||
init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);
|
||||
return const_val;
|
||||
}
|
||||
|
||||
|
||||
ZigValue *create_const_vals(size_t count) {
|
||||
return allocate<ZigValue>(count, "ZigValue");
|
||||
}
|
||||
@ -6679,9 +6641,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
|
||||
}
|
||||
case ZigTypeIdErrorUnion:
|
||||
zig_panic("TODO");
|
||||
case ZigTypeIdArgTuple:
|
||||
return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
|
||||
a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdUnreachable:
|
||||
@ -7008,11 +6967,6 @@ void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) {
|
||||
}
|
||||
case ZigTypeIdErrorSet:
|
||||
return render_const_val_err_set(g, buf, const_val, type_entry);
|
||||
case ZigTypeIdArgTuple:
|
||||
{
|
||||
buf_appendf(buf, "(args value)");
|
||||
return;
|
||||
}
|
||||
case ZigTypeIdFnFrame:
|
||||
buf_appendf(buf, "(TODO: async function frame value)");
|
||||
return;
|
||||
@ -7075,7 +7029,6 @@ uint32_t type_id_hash(TypeId x) {
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
zig_unreachable();
|
||||
@ -7127,7 +7080,6 @@ bool type_id_eql(TypeId a, TypeId b) {
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
@ -7350,7 +7302,6 @@ static const ZigTypeId all_type_ids[] = {
|
||||
ZigTypeIdUnion,
|
||||
ZigTypeIdFn,
|
||||
ZigTypeIdBoundFn,
|
||||
ZigTypeIdArgTuple,
|
||||
ZigTypeIdOpaque,
|
||||
ZigTypeIdFnFrame,
|
||||
ZigTypeIdAnyFrame,
|
||||
@ -7413,18 +7364,16 @@ size_t type_id_index(ZigType *entry) {
|
||||
return 18;
|
||||
case ZigTypeIdBoundFn:
|
||||
return 19;
|
||||
case ZigTypeIdArgTuple:
|
||||
return 20;
|
||||
case ZigTypeIdOpaque:
|
||||
return 21;
|
||||
return 20;
|
||||
case ZigTypeIdFnFrame:
|
||||
return 22;
|
||||
return 21;
|
||||
case ZigTypeIdAnyFrame:
|
||||
return 23;
|
||||
return 22;
|
||||
case ZigTypeIdVector:
|
||||
return 24;
|
||||
return 23;
|
||||
case ZigTypeIdEnumLiteral:
|
||||
return 25;
|
||||
return 24;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -7475,8 +7424,6 @@ const char *type_id_name(ZigTypeId id) {
|
||||
return "Fn";
|
||||
case ZigTypeIdBoundFn:
|
||||
return "BoundFn";
|
||||
case ZigTypeIdArgTuple:
|
||||
return "ArgTuple";
|
||||
case ZigTypeIdOpaque:
|
||||
return "Opaque";
|
||||
case ZigTypeIdVector:
|
||||
@ -9064,7 +9011,6 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdOpaque:
|
||||
|
@ -171,9 +171,6 @@ void init_const_slice(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
|
||||
size_t start, size_t len, bool is_const);
|
||||
ZigValue *create_const_slice(CodeGen *g, ZigValue *array_val, size_t start, size_t len, bool is_const);
|
||||
|
||||
void init_const_arg_tuple(CodeGen *g, ZigValue *const_val, size_t arg_index_start, size_t arg_index_end);
|
||||
ZigValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
|
||||
|
||||
void init_const_null(ZigValue *const_val, ZigType *type);
|
||||
ZigValue *create_const_null(ZigType *type);
|
||||
|
||||
|
@ -6539,7 +6539,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdOpaque:
|
||||
zig_unreachable();
|
||||
@ -7182,7 +7181,6 @@ check: switch (const_val->special) {
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdFnFrame:
|
||||
@ -7887,11 +7885,6 @@ static void define_builtin_types(CodeGen *g) {
|
||||
buf_init_from_str(&entry->name, "(var)");
|
||||
g->builtin_types.entry_var = entry;
|
||||
}
|
||||
{
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
|
||||
buf_init_from_str(&entry->name, "(args)");
|
||||
g->builtin_types.entry_arg_tuple = entry;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
|
||||
const CIntTypeInfo *info = &c_int_type_infos[i];
|
||||
@ -9532,7 +9525,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdFnFrame:
|
||||
@ -9721,7 +9713,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
|
||||
case ZigTypeIdEnumLiteral:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
zig_unreachable();
|
||||
@ -9781,7 +9772,6 @@ static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) {
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdVector:
|
||||
|
238
src/ir.cpp
238
src/ir.cpp
@ -780,7 +780,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdFnFrame:
|
||||
return false;
|
||||
@ -14791,7 +14790,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdEnumLiteral:
|
||||
case ZigTypeIdAnyFrame:
|
||||
@ -16437,7 +16435,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
@ -16462,7 +16459,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
||||
case ZigTypeIdVector:
|
||||
zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name));
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdEnumLiteral:
|
||||
case ZigTypeIdFnFrame:
|
||||
@ -16609,7 +16605,6 @@ static bool type_can_bit_cast(ZigType *t) {
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdComptimeInt:
|
||||
@ -17416,23 +17411,6 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
|
||||
return true;
|
||||
}
|
||||
|
||||
static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) {
|
||||
FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index];
|
||||
if (!type_has_bits(src_param_info->type))
|
||||
return nullptr;
|
||||
|
||||
size_t next_var_i = 0;
|
||||
for (size_t param_i = 0; param_i < index; param_i += 1) {
|
||||
FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i];
|
||||
if (!type_has_bits(src_param_info->type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
next_var_i += 1;
|
||||
}
|
||||
return fn_entry->variable_list.at(next_var_i);
|
||||
}
|
||||
|
||||
static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) {
|
||||
while (var->next_var != nullptr) {
|
||||
var = var->next_var;
|
||||
@ -17690,16 +17668,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
|
||||
var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0;
|
||||
}
|
||||
size_t src_param_count = fn_type_id->param_count - var_args_1_or_0;
|
||||
|
||||
size_t call_param_count = args_len + first_arg_1_or_0;
|
||||
for (size_t i = 0; i < args_len; i += 1) {
|
||||
ZigValue *arg_tuple_value = args_ptr[i]->value;
|
||||
if (arg_tuple_value->type->id == ZigTypeIdArgTuple) {
|
||||
call_param_count -= 1;
|
||||
call_param_count += arg_tuple_value->data.x_arg_tuple.end_index -
|
||||
arg_tuple_value->data.x_arg_tuple.start_index;
|
||||
}
|
||||
}
|
||||
AstNode *source_node = source_instr->source_node;
|
||||
|
||||
AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;;
|
||||
@ -17854,16 +17823,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
// Count the arguments of the function type id we are creating
|
||||
size_t new_fn_arg_count = first_arg_1_or_0;
|
||||
for (size_t call_i = 0; call_i < args_len; call_i += 1) {
|
||||
IrInstruction *arg = args_ptr[call_i];
|
||||
if (arg->value->type->id == ZigTypeIdArgTuple) {
|
||||
new_fn_arg_count += arg->value->data.x_arg_tuple.end_index - arg->value->data.x_arg_tuple.start_index;
|
||||
} else {
|
||||
new_fn_arg_count += 1;
|
||||
}
|
||||
}
|
||||
size_t new_fn_arg_count = first_arg_1_or_0 + args_len;
|
||||
|
||||
IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count);
|
||||
|
||||
@ -17914,76 +17874,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
|
||||
}
|
||||
}
|
||||
|
||||
bool found_first_var_arg = false;
|
||||
size_t first_var_arg;
|
||||
|
||||
ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
|
||||
assert(parent_fn_entry);
|
||||
for (size_t call_i = 0; call_i < args_len; call_i += 1) {
|
||||
IrInstruction *arg = args_ptr[call_i];
|
||||
|
||||
if (arg->value->type->id == ZigTypeIdArgTuple) {
|
||||
for (size_t arg_tuple_i = arg->value->data.x_arg_tuple.start_index;
|
||||
arg_tuple_i < arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1)
|
||||
{
|
||||
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
|
||||
assert(param_decl_node->type == NodeTypeParamDecl);
|
||||
bool is_var_args = param_decl_node->data.param_decl.is_var_args;
|
||||
if (is_var_args && !found_first_var_arg) {
|
||||
first_var_arg = inst_fn_type_id.param_count;
|
||||
found_first_var_arg = true;
|
||||
}
|
||||
|
||||
ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
|
||||
if (arg_var == nullptr) {
|
||||
ir_add_error(ira, arg,
|
||||
buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var);
|
||||
if (type_is_invalid(arg_var_ptr_inst->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr);
|
||||
if (type_is_invalid(arg_tuple_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope,
|
||||
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
|
||||
{
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
|
||||
assert(param_decl_node->type == NodeTypeParamDecl);
|
||||
bool is_var_args = param_decl_node->data.param_decl.is_var_args;
|
||||
if (is_var_args && !found_first_var_arg) {
|
||||
first_var_arg = inst_fn_type_id.param_count;
|
||||
found_first_var_arg = true;
|
||||
}
|
||||
|
||||
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
|
||||
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
|
||||
{
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fn_proto_node->data.fn_proto.is_var_args) {
|
||||
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
|
||||
Buf *param_name = param_decl_node->data.param_decl.name;
|
||||
assert(param_decl_node->type == NodeTypeParamDecl);
|
||||
|
||||
if (!found_first_var_arg) {
|
||||
first_var_arg = inst_fn_type_id.param_count;
|
||||
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
|
||||
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
|
||||
{
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
ZigValue *var_args_val = create_const_arg_tuple(ira->codegen,
|
||||
first_var_arg, inst_fn_type_id.param_count);
|
||||
ZigVar *var = add_variable(ira->codegen, param_decl_node,
|
||||
impl_fn->child_scope, param_name, true, var_args_val, nullptr, var_args_val->type);
|
||||
impl_fn->child_scope = var->child_scope;
|
||||
}
|
||||
|
||||
if (fn_proto_node->data.fn_proto.align_expr != nullptr) {
|
||||
@ -18153,55 +18056,20 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
|
||||
if (type_is_invalid(old_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (old_arg->value->type->id == ZigTypeIdArgTuple) {
|
||||
for (size_t arg_tuple_i = old_arg->value->data.x_arg_tuple.start_index;
|
||||
arg_tuple_i < old_arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1)
|
||||
{
|
||||
ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
|
||||
if (arg_var == nullptr) {
|
||||
ir_add_error(ira, old_arg,
|
||||
buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, old_arg, arg_var);
|
||||
if (type_is_invalid(arg_var_ptr_inst->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *arg_tuple_arg = ir_get_deref(ira, old_arg, arg_var_ptr_inst, nullptr);
|
||||
if (type_is_invalid(arg_tuple_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, arg_tuple_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
casted_arg = arg_tuple_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
}
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
IrInstruction *casted_arg;
|
||||
if (next_arg_index < src_param_count) {
|
||||
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
|
||||
if (type_is_invalid(casted_arg->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
casted_arg = old_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
casted_arg = old_arg;
|
||||
}
|
||||
|
||||
casted_args[next_arg_index] = casted_arg;
|
||||
next_arg_index += 1;
|
||||
}
|
||||
|
||||
assert(next_arg_index == call_param_count);
|
||||
@ -19186,37 +19054,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
|
||||
} else if (is_slice(array_type)) {
|
||||
return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry,
|
||||
elem_ptr_instruction->ptr_len);
|
||||
} else if (array_type->id == ZigTypeIdArgTuple) {
|
||||
ZigValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
|
||||
if (!ptr_val)
|
||||
return ira->codegen->invalid_instruction;
|
||||
ZigValue *args_val = const_ptr_pointee(ira, ira->codegen, ptr_val, elem_ptr_instruction->base.source_node);
|
||||
if (args_val == nullptr)
|
||||
return ira->codegen->invalid_instruction;
|
||||
size_t start = args_val->data.x_arg_tuple.start_index;
|
||||
size_t end = args_val->data.x_arg_tuple.end_index;
|
||||
uint64_t elem_index_val;
|
||||
if (!ir_resolve_usize(ira, elem_index, &elem_index_val))
|
||||
return ira->codegen->invalid_instruction;
|
||||
size_t index = elem_index_val;
|
||||
size_t len = end - start;
|
||||
if (index >= len) {
|
||||
ir_add_error(ira, &elem_ptr_instruction->base,
|
||||
buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
size_t abs_index = start + index;
|
||||
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
|
||||
assert(fn_entry);
|
||||
ZigVar *var = get_fn_var_by_index(fn_entry, abs_index);
|
||||
bool is_const = true;
|
||||
bool is_volatile = false;
|
||||
if (var) {
|
||||
return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var);
|
||||
} else {
|
||||
return ir_get_const_ptr(ira, &elem_ptr_instruction->base, ira->codegen->intern.for_void(),
|
||||
ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0);
|
||||
}
|
||||
} else if (array_type->id == ZigTypeIdVector) {
|
||||
// This depends on whether the element index is comptime, so it is computed later.
|
||||
return_type = nullptr;
|
||||
@ -20025,6 +19862,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
|
||||
|
||||
if (type_is_invalid(container_type)) {
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) {
|
||||
IrInstruction *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base,
|
||||
container_type->data.structure.src_field_count);
|
||||
return ir_get_ref(ira, &field_ptr_instruction->base, len_inst, true, false);
|
||||
} else if (is_slice(container_type) || is_container_ref(container_type)) {
|
||||
assert(container_ptr->value->type->id == ZigTypeIdPointer);
|
||||
if (container_type->id == ZigTypeIdPointer) {
|
||||
@ -20045,32 +19886,6 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
|
||||
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
|
||||
}
|
||||
|
||||
ZigType *usize = ira->codegen->builtin_types.entry_usize;
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val,
|
||||
usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
|
||||
} else {
|
||||
ir_add_error_node(ira, source_node,
|
||||
buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
|
||||
buf_ptr(&container_type->name)));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
} else if (container_type->id == ZigTypeIdArgTuple) {
|
||||
ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
|
||||
if (!container_ptr_val)
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
assert(container_ptr->value->type->id == ZigTypeIdPointer);
|
||||
ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node);
|
||||
if (child_val == nullptr)
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (buf_eql_str(field_name, "len")) {
|
||||
ZigValue *len_val = create_const_vals(1);
|
||||
size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index;
|
||||
init_const_usize(ira->codegen, len_val, len);
|
||||
|
||||
ZigType *usize = ira->codegen->builtin_types.entry_usize;
|
||||
bool ptr_is_const = true;
|
||||
bool ptr_is_volatile = false;
|
||||
@ -21258,7 +21073,6 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdFnFrame:
|
||||
@ -22580,7 +22394,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
|
||||
case ZigTypeIdEnumLiteral:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
result = ira->codegen->intern.for_void();
|
||||
break;
|
||||
@ -23357,7 +23170,6 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdStruct:
|
||||
ir_add_error(ira, instruction, buf_sprintf(
|
||||
"@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId)));
|
||||
@ -26452,7 +26264,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdComptimeInt:
|
||||
@ -26609,7 +26420,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
|
||||
case ZigTypeIdMetaType:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdComptimeInt:
|
||||
@ -28838,7 +28648,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdOpaque:
|
||||
ir_add_error(ira, lazy_align_of->target_type,
|
||||
@ -28890,7 +28699,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
ir_add_error(ira, lazy_size_of->target_type,
|
||||
buf_sprintf("no size available for type '%s'",
|
||||
@ -28969,7 +28777,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
ir_add_error(ira, lazy_slice_type->elem_type,
|
||||
buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name)));
|
||||
@ -29102,7 +28909,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
ir_add_error(ira, lazy_array_type->elem_type,
|
||||
buf_sprintf("array of type '%s' not allowed",
|
||||
|
@ -802,12 +802,6 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
|
||||
res->data.fn_proto.auto_err_set = exmark != nullptr;
|
||||
res->data.fn_proto.return_type = return_type;
|
||||
|
||||
// It seems that the Zig compiler expects varargs to be the
|
||||
// last parameter in the decl list. This is not encoded in
|
||||
// the grammar, which allows varargs anywhere in the decl.
|
||||
// Since varargs is gonna be removed at some point, I'm not
|
||||
// gonna encode this "varargs is always last" rule in the
|
||||
// grammar, and just enforce it here, until varargs is removed.
|
||||
for (size_t i = 0; i < params.length; i++) {
|
||||
AstNode *param_decl = params.at(i);
|
||||
assert(param_decl->type == NodeTypeParamDecl);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
cases.add("declare enum",
|
||||
\\const Foo = extern enum { A, B, C };
|
||||
\\export fn entry(foo: Foo) void { }
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\enum Foo {
|
||||
\\ A = 0,
|
||||
\\ B = 1,
|
||||
@ -12,7 +12,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\};
|
||||
,
|
||||
\\void entry(enum Foo foo);
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("declare struct",
|
||||
\\const Foo = extern struct {
|
||||
@ -24,7 +24,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ F: u64,
|
||||
\\};
|
||||
\\export fn entry(foo: Foo) void { }
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\struct Foo {
|
||||
\\ int32_t A;
|
||||
\\ float B;
|
||||
@ -36,7 +36,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
,
|
||||
\\void entry(struct Foo foo);
|
||||
\\
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("declare union",
|
||||
\\const Big = extern struct {
|
||||
@ -53,7 +53,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ D: Big,
|
||||
\\};
|
||||
\\export fn entry(foo: Foo) void {}
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\struct Big {
|
||||
\\ uint64_t A;
|
||||
\\ uint64_t B;
|
||||
@ -71,17 +71,17 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
,
|
||||
\\void entry(union Foo foo);
|
||||
\\
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("declare opaque type",
|
||||
\\const Foo = @OpaqueType();
|
||||
\\
|
||||
\\export fn entry(foo: ?*Foo) void { }
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\struct Foo;
|
||||
,
|
||||
\\void entry(struct Foo * foo);
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("array field-type",
|
||||
\\const Foo = extern struct {
|
||||
@ -89,7 +89,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ B: [4]*u32,
|
||||
\\};
|
||||
\\export fn entry(foo: Foo, bar: [3]u8) void { }
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\struct Foo {
|
||||
\\ int32_t A[2];
|
||||
\\ uint32_t * B[4];
|
||||
@ -97,7 +97,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
,
|
||||
\\void entry(struct Foo foo, uint8_t bar[]);
|
||||
\\
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("ptr to zig struct",
|
||||
\\const S = struct {
|
||||
@ -107,12 +107,12 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\export fn a(s: *S) u8 {
|
||||
\\ return s.a;
|
||||
\\}
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\struct S;
|
||||
,
|
||||
\\uint8_t a(struct S * s);
|
||||
\\
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("ptr to zig union",
|
||||
\\const U = union(enum) {
|
||||
@ -123,12 +123,12 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\export fn a(s: *U) u8 {
|
||||
\\ return s.A;
|
||||
\\}
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\union U;
|
||||
,
|
||||
\\uint8_t a(union U * s);
|
||||
\\
|
||||
);
|
||||
});
|
||||
|
||||
cases.add("ptr to zig enum",
|
||||
\\const E = enum(u8) {
|
||||
@ -139,10 +139,10 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\export fn a(s: *E) u8 {
|
||||
\\ return @enumToInt(s.*);
|
||||
\\}
|
||||
,
|
||||
, &[_][]const u8{
|
||||
\\enum E;
|
||||
,
|
||||
\\uint8_t a(enum E * s);
|
||||
\\
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -670,10 +670,10 @@ fn loopNTimes(comptime n: usize) void {
|
||||
}
|
||||
|
||||
test "variable inside inline loop that has different types on different iterations" {
|
||||
testVarInsideInlineLoop(true, @as(u32, 42));
|
||||
testVarInsideInlineLoop(.{true, @as(u32, 42)});
|
||||
}
|
||||
|
||||
fn testVarInsideInlineLoop(args: ...) void {
|
||||
fn testVarInsideInlineLoop(args: var) void {
|
||||
comptime var i = 0;
|
||||
inline while (i < args.len) : (i += 1) {
|
||||
const x = args[i];
|
||||
|
@ -15,7 +15,6 @@ test "reflection: function return type, var args, and param types" {
|
||||
comptime {
|
||||
expect(@typeOf(dummy).ReturnType == i32);
|
||||
expect(!@typeOf(dummy).is_var_args);
|
||||
expect(@typeOf(dummy_varargs).is_var_args);
|
||||
expect(@typeOf(dummy).arg_count == 3);
|
||||
expect(@ArgType(@typeOf(dummy), 0) == bool);
|
||||
expect(@ArgType(@typeOf(dummy), 1) == i32);
|
||||
@ -26,7 +25,6 @@ test "reflection: function return type, var args, and param types" {
|
||||
fn dummy(a: bool, b: i32, c: f32) i32 {
|
||||
return 1234;
|
||||
}
|
||||
fn dummy_varargs(args: ...) void {}
|
||||
|
||||
test "reflection: struct member types and names" {
|
||||
comptime {
|
||||
|
@ -198,7 +198,7 @@ fn testUnion() void {
|
||||
expect(@as(TypeId, typeinfo_info) == TypeId.Union);
|
||||
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||
expect(typeinfo_info.Union.tag_type.? == TypeId);
|
||||
expect(typeinfo_info.Union.fields.len == 26);
|
||||
expect(typeinfo_info.Union.fields.len == 25);
|
||||
expect(typeinfo_info.Union.fields[4].enum_field != null);
|
||||
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
||||
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
||||
|
@ -1,6 +1,6 @@
|
||||
const expect = @import("std").testing.expect;
|
||||
|
||||
fn add(args: ...) i32 {
|
||||
fn add(args: var) i32 {
|
||||
var sum = @as(i32, 0);
|
||||
{
|
||||
comptime var i: usize = 0;
|
||||
@ -12,43 +12,42 @@ fn add(args: ...) i32 {
|
||||
}
|
||||
|
||||
test "add arbitrary args" {
|
||||
expect(add(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
|
||||
expect(add(@as(i32, 1234)) == 1234);
|
||||
expect(add() == 0);
|
||||
expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
||||
expect(add(.{@as(i32, 1234)}) == 1234);
|
||||
expect(add(.{}) == 0);
|
||||
}
|
||||
|
||||
fn readFirstVarArg(args: ...) void {
|
||||
fn readFirstVarArg(args: var) void {
|
||||
const value = args[0];
|
||||
}
|
||||
|
||||
test "send void arg to var args" {
|
||||
readFirstVarArg({});
|
||||
readFirstVarArg(.{{}});
|
||||
}
|
||||
|
||||
test "pass args directly" {
|
||||
expect(addSomeStuff(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
|
||||
expect(addSomeStuff(@as(i32, 1234)) == 1234);
|
||||
expect(addSomeStuff() == 0);
|
||||
expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
||||
expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
|
||||
expect(addSomeStuff(.{}) == 0);
|
||||
}
|
||||
|
||||
fn addSomeStuff(args: ...) i32 {
|
||||
fn addSomeStuff(args: var) i32 {
|
||||
return add(args);
|
||||
}
|
||||
|
||||
test "runtime parameter before var args" {
|
||||
expect(extraFn(10) == 0);
|
||||
expect(extraFn(10, false) == 1);
|
||||
expect(extraFn(10, false, true) == 2);
|
||||
expect(extraFn(10, .{}) == 0);
|
||||
expect(extraFn(10, .{false}) == 1);
|
||||
expect(extraFn(10, .{ false, true }) == 2);
|
||||
|
||||
// TODO issue #313
|
||||
//comptime {
|
||||
// expect(extraFn(10) == 0);
|
||||
// expect(extraFn(10, false) == 1);
|
||||
// expect(extraFn(10, false, true) == 2);
|
||||
//}
|
||||
comptime {
|
||||
expect(extraFn(10, .{}) == 0);
|
||||
expect(extraFn(10, .{false}) == 1);
|
||||
expect(extraFn(10, .{ false, true }) == 2);
|
||||
}
|
||||
}
|
||||
|
||||
fn extraFn(extra: u32, args: ...) usize {
|
||||
fn extraFn(extra: u32, args: var) usize {
|
||||
if (args.len >= 1) {
|
||||
expect(args[0] == false);
|
||||
}
|
||||
@ -58,27 +57,27 @@ fn extraFn(extra: u32, args: ...) usize {
|
||||
return args.len;
|
||||
}
|
||||
|
||||
const foos = [_]fn (...) bool{
|
||||
const foos = [_]fn (var) bool{
|
||||
foo1,
|
||||
foo2,
|
||||
};
|
||||
|
||||
fn foo1(args: ...) bool {
|
||||
fn foo1(args: var) bool {
|
||||
return true;
|
||||
}
|
||||
fn foo2(args: ...) bool {
|
||||
fn foo2(args: var) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
test "array of var args functions" {
|
||||
expect(foos[0]());
|
||||
expect(!foos[1]());
|
||||
expect(foos[0](.{}));
|
||||
expect(!foos[1](.{}));
|
||||
}
|
||||
|
||||
test "pass zero length array to var args param" {
|
||||
doNothingWithFirstArg("");
|
||||
doNothingWithFirstArg(.{""});
|
||||
}
|
||||
|
||||
fn doNothingWithFirstArg(args: ...) void {
|
||||
fn doNothingWithFirstArg(args: var) void {
|
||||
const a = args[0];
|
||||
}
|
||||
|
110
test/tests.zig
110
test/tests.zig
@ -1253,7 +1253,12 @@ pub const CompileErrorContext = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
|
||||
pub fn create(
|
||||
self: *CompileErrorContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) *TestCase {
|
||||
const tc = self.b.allocator.create(TestCase) catch unreachable;
|
||||
tc.* = TestCase{
|
||||
.name = name,
|
||||
@ -1266,31 +1271,46 @@ pub const CompileErrorContext = struct {
|
||||
};
|
||||
|
||||
tc.addSourceFile("tmp.zig", source);
|
||||
comptime var arg_i = 0;
|
||||
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
var arg_i: usize = 0;
|
||||
while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
tc.addExpectedError(expected_lines[arg_i]);
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
|
||||
var tc = self.create(name, source, expected_lines);
|
||||
tc.link_libc = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addExe(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addExe(
|
||||
self: *CompileErrorContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
var tc = self.create(name, source, expected_lines);
|
||||
tc.is_exe = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn add(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn add(
|
||||
self: *CompileErrorContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addTest(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addTest(
|
||||
self: *CompileErrorContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(name, source, expected_lines);
|
||||
tc.is_test = true;
|
||||
self.addCase(tc);
|
||||
@ -1549,7 +1569,14 @@ pub const TranslateCContext = struct {
|
||||
warn("\n", .{});
|
||||
}
|
||||
|
||||
pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
|
||||
pub fn create(
|
||||
self: *TranslateCContext,
|
||||
allow_warnings: bool,
|
||||
filename: []const u8,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) *TestCase {
|
||||
const tc = self.b.allocator.create(TestCase) catch unreachable;
|
||||
tc.* = TestCase{
|
||||
.name = name,
|
||||
@ -1560,24 +1587,39 @@ pub const TranslateCContext = struct {
|
||||
};
|
||||
|
||||
tc.addSourceFile(filename, source);
|
||||
comptime var arg_i = 0;
|
||||
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
var arg_i: usize = 0;
|
||||
while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
tc.addExpectedLine(expected_lines[arg_i]);
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
pub fn add(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn add(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(false, "source.h", name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addC(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addC(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn add_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn add_both(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
for ([_]bool{ false, true }) |stage2| {
|
||||
const tc = self.create(false, "source.h", name, source, expected_lines);
|
||||
tc.stage2 = stage2;
|
||||
@ -1585,7 +1627,12 @@ pub const TranslateCContext = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addC_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addC_both(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
for ([_]bool{ false, true }) |stage2| {
|
||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
||||
tc.stage2 = stage2;
|
||||
@ -1593,19 +1640,34 @@ pub const TranslateCContext = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn add_2(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(false, "source.h", name, source, expected_lines);
|
||||
tc.stage2 = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addC_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addC_2(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
||||
tc.stage2 = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addAllowWarnings(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn addAllowWarnings(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(true, "source.h", name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
@ -1723,7 +1785,13 @@ pub const GenHContext = struct {
|
||||
warn("\n", .{});
|
||||
}
|
||||
|
||||
pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
|
||||
pub fn create(
|
||||
self: *GenHContext,
|
||||
filename: []const u8,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) *TestCase {
|
||||
const tc = self.b.allocator.create(TestCase) catch unreachable;
|
||||
tc.* = TestCase{
|
||||
.name = name,
|
||||
@ -1732,14 +1800,14 @@ pub const GenHContext = struct {
|
||||
};
|
||||
|
||||
tc.addSourceFile(filename, source);
|
||||
comptime var arg_i = 0;
|
||||
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
var arg_i: usize = 0;
|
||||
while (arg_i < expected_lines.len) : (arg_i += 1) {
|
||||
tc.addExpectedLine(expected_lines[arg_i]);
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
pub fn add(self: *GenHContext, name: []const u8, source: []const u8, expected_lines: ...) void {
|
||||
pub fn add(self: *GenHContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
|
||||
const tc = self.create("test.zig", name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user