aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp728
1 files changed, 584 insertions, 144 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 887f0a2f9b..11ff7746e7 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -13,6 +13,7 @@
#include "os.hpp"
#include "range_set.hpp"
#include "softfloat.hpp"
+#include "softfloat_ext.hpp"
#include "util.hpp"
#include "mem_list.hpp"
#include "all_types.hpp"
@@ -286,6 +287,7 @@ static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* so
IrInstGen *struct_operand, TypeStructField *field);
static bool value_cmp_numeric_val_any(ZigValue *left, Cmp predicate, ZigValue *right);
static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *right);
+static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);
#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
#define ir_assert_gen(OK, SOURCE_INSTRUCTION) ir_assert_gen_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
@@ -308,6 +310,8 @@ static void destroy_instruction_src(IrInstSrc *inst) {
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst));
case IrInstSrcIdCallExtra:
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst));
+ case IrInstSrcIdAsyncCallExtra:
+ return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst));
case IrInstSrcIdUnOp:
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst));
case IrInstSrcIdCondBr:
@@ -560,6 +564,8 @@ static void destroy_instruction_src(IrInstSrc *inst) {
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemorySize *>(inst));
case IrInstSrcIdWasmMemoryGrow:
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemoryGrow *>(inst));
+ case IrInstSrcIdSrc:
+ return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSrc *>(inst));
}
zig_unreachable();
}
@@ -822,12 +828,11 @@ static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_
ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val;
size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
- // TODO handle sentinel terminated arrays
expand_undef_array(g, array_val);
result = g->pass1_arena->create<ZigValue>();
result->special = array_val->special;
result->type = get_array_type(g, array_val->type->data.array.child_type,
- array_val->type->data.array.len - elem_index, nullptr);
+ array_val->type->data.array.len - elem_index, array_val->type->data.array.sentinel);
result->data.x_array.special = ConstArraySpecialNone;
result->data.x_array.data.s_none.elements = &array_val->data.x_array.data.s_none.elements[elem_index];
result->parent.id = ConstParentIdArray;
@@ -1170,6 +1175,10 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) {
return IrInstSrcIdCallExtra;
}
+static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) {
+ return IrInstSrcIdAsyncCallExtra;
+}
+
static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) {
return IrInstSrcIdConst;
}
@@ -1626,6 +1635,9 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) {
return IrInstSrcIdWasmMemoryGrow;
}
+static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) {
+ return IrInstSrcIdSrc;
+}
static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) {
return IrInstGenIdDeclVar;
@@ -2436,6 +2448,25 @@ static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *
return &call_instruction->base;
}
+static IrInstSrc *ir_build_async_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
+ CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc)
+{
+ IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(irb, scope, source_node);
+ call_instruction->modifier = modifier;
+ call_instruction->fn_ref = fn_ref;
+ call_instruction->ret_ptr = ret_ptr;
+ call_instruction->new_stack = new_stack;
+ call_instruction->args = args;
+ call_instruction->result_loc = result_loc;
+
+ ir_ref_instruction(fn_ref, irb->current_basic_block);
+ if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block);
+ ir_ref_instruction(new_stack, irb->current_basic_block);
+ ir_ref_instruction(args, irb->current_basic_block);
+
+ return &call_instruction->base;
+}
+
static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len,
ResultLoc *result_loc)
@@ -5029,6 +5060,11 @@ static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_i
return &instruction->base;
}
+static IrInstSrc *ir_build_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
+ IrInstSrcSrc *instruction = ir_build_instruction<IrInstSrcSrc>(irb, scope, source_node);
+
+ return &instruction->base;
+}
static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
@@ -6172,11 +6208,10 @@ static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *nod
static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node,
LVal lval, ResultLoc *result_loc)
{
- size_t arg_offset = 3;
- if (call_node->data.fn_call_expr.params.length < arg_offset) {
+ if (call_node->data.fn_call_expr.params.length != 4) {
add_node_error(irb->codegen, call_node,
- buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize,
- arg_offset, call_node->data.fn_call_expr.params.length));
+ buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize,
+ call_node->data.fn_call_expr.params.length));
return irb->codegen->invalid_inst_src;
}
@@ -6195,20 +6230,37 @@ static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *aw
if (fn_ref == irb->codegen->invalid_inst_src)
return fn_ref;
- size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset;
- IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
- for (size_t i = 0; i < arg_count; i += 1) {
- AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset);
- IrInstSrc *arg = ir_gen_node(irb, arg_node, scope);
- if (arg == irb->codegen->invalid_inst_src)
- return arg;
- args[i] = arg;
- }
-
CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone;
bool is_async_call_builtin = true;
- IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args,
- ret_ptr, modifier, is_async_call_builtin, bytes, result_loc);
+ AstNode *args_node = call_node->data.fn_call_expr.params.at(3);
+ if (args_node->type == NodeTypeContainerInitExpr) {
+ if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
+ args_node->data.container_init_expr.entries.length == 0)
+ {
+ size_t arg_count = args_node->data.container_init_expr.entries.length;
+ IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
+ for (size_t i = 0; i < arg_count; i += 1) {
+ AstNode *arg_node = args_node->data.container_init_expr.entries.at(i);
+ IrInstSrc *arg = ir_gen_node(irb, arg_node, scope);
+ if (arg == irb->codegen->invalid_inst_src)
+ return arg;
+ args[i] = arg;
+ }
+
+ IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args,
+ ret_ptr, modifier, is_async_call_builtin, bytes, result_loc);
+ return ir_lval_wrap(irb, scope, call, lval, result_loc);
+ } else {
+ exec_add_error_node(irb->codegen, irb->exec, args_node,
+ buf_sprintf("TODO: @asyncCall with anon struct literal"));
+ return irb->codegen->invalid_inst_src;
+ }
+ }
+ IrInstSrc *args = ir_gen_node(irb, args_node, scope);
+ if (args == irb->codegen->invalid_inst_src)
+ return args;
+
+ IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc);
return ir_lval_wrap(irb, scope, call, lval, result_loc);
}
@@ -7449,6 +7501,11 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node,
lval, result_loc);
}
+ case BuiltinFnIdSrc:
+ {
+ IrInstSrc *src_inst = ir_build_src(irb, scope, node);
+ return ir_lval_wrap(irb, scope, src_inst, lval, result_loc);
+ }
}
zig_unreachable();
}
@@ -9885,7 +9942,7 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
is_var_args = true;
break;
}
- if (param_node->data.param_decl.var_token == nullptr) {
+ if (param_node->data.param_decl.anytype_token == nullptr) {
AstNode *type_node = param_node->data.param_decl.type;
IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope);
if (type_value == irb->codegen->invalid_inst_src)
@@ -9911,7 +9968,7 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
}
IrInstSrc *return_type;
- if (node->data.fn_proto.return_var_token == nullptr) {
+ if (node->data.fn_proto.return_anytype_token == nullptr) {
if (node->data.fn_proto.return_type == nullptr) {
return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void);
} else {
@@ -10169,9 +10226,9 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
add_node_error(irb->codegen, node,
buf_sprintf("inferred array size invalid here"));
return irb->codegen->invalid_inst_src;
- case NodeTypeVarFieldType:
+ case NodeTypeAnyTypeField:
return ir_lval_wrap(irb, scope,
- ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var), lval, result_loc);
+ ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_anytype), lval, result_loc);
}
zig_unreachable();
}
@@ -10239,7 +10296,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco
case NodeTypeSuspend:
case NodeTypeEnumLiteral:
case NodeTypeInferredArrayType:
- case NodeTypeVarFieldType:
+ case NodeTypeAnyTypeField:
case NodeTypePrefixOpExpr:
add_node_error(irb->codegen, node,
buf_sprintf("invalid left-hand side to assignment"));
@@ -10461,7 +10518,7 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va
if (val == nullptr) return nullptr;
assert(const_val->type->id == ZigTypeIdPointer);
ZigType *expected_type = const_val->type->data.pointer.child_type;
- if (expected_type == codegen->builtin_types.entry_var) {
+ if (expected_type == codegen->builtin_types.entry_anytype) {
return val;
}
switch (type_has_one_possible_value(codegen, expected_type)) {
@@ -12585,28 +12642,29 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (prev_type->id == ZigTypeIdPointer &&
prev_type->data.pointer.ptr_len == PtrLenSingle &&
prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
- ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown)))
+ ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown)))
{
- prev_inst = cur_inst;
+ convert_to_const_slice = false;
+ prev_inst = cur_inst;
if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) {
// const array pointer and non-const unknown pointer
make_the_pointer_const = true;
}
- continue;
+ continue;
}
// *[N]T to [*]T
if (cur_type->id == ZigTypeIdPointer &&
cur_type->data.pointer.ptr_len == PtrLenSingle &&
cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
- ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown)))
+ ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown)))
{
if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) {
// const array pointer and non-const unknown pointer
make_the_pointer_const = true;
}
- continue;
+ continue;
}
// *[N]T to []T
@@ -12962,7 +13020,11 @@ static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGe
{
if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) {
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
- if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type,
+ ZigValue *val = ir_resolve_const(ira, value, UndefBad);
+ if (val == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
+ if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, val, val->type,
result->value, wanted_type))
{
return ira->codegen->invalid_inst_gen;
@@ -14703,10 +14765,139 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou
}
static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr,
- IrInstGen *value, ZigType *wanted_type)
+ IrInstGen *struct_operand, ZigType *wanted_type)
{
- ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct"));
- return ira->codegen->invalid_inst_gen;
+ Error err;
+
+ IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false);
+ if (type_is_invalid(struct_ptr->value->type))
+ return ira->codegen->invalid_inst_gen;
+
+ if (wanted_type->data.structure.resolve_status == ResolveStatusBeingInferred) {
+ ir_add_error(ira, source_instr, buf_sprintf("type coercion of anon struct literal to inferred struct"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown)))
+ return ira->codegen->invalid_inst_gen;
+
+ size_t actual_field_count = wanted_type->data.structure.src_field_count;
+ size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count;
+
+ bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope)
+ || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;
+ bool is_comptime = true;
+
+ // Determine if the struct_operand will be comptime.
+ // Also emit compile errors for missing fields and duplicate fields.
+ AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count);
+ ZigValue **field_values = heap::c_allocator.allocate<ZigValue *>(actual_field_count);
+ IrInstGen **casted_fields = heap::c_allocator.allocate<IrInstGen *>(actual_field_count);
+ IrInstGen *const_result = ir_const(ira, source_instr, wanted_type);
+
+ for (size_t i = 0; i < instr_field_count; i += 1) {
+ TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i];
+ TypeStructField *dst_field = find_struct_type_field(wanted_type, src_field->name);
+ if (dst_field == nullptr) {
+ ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("no field named '%s' in struct '%s'",
+ buf_ptr(src_field->name), buf_ptr(&wanted_type->name)));
+ if (wanted_type->data.structure.decl_node) {
+ add_error_note(ira->codegen, msg, wanted_type->data.structure.decl_node,
+ buf_sprintf("struct '%s' declared here", buf_ptr(&wanted_type->name)));
+ }
+ add_error_note(ira->codegen, msg, src_field->decl_node,
+ buf_sprintf("field '%s' declared here", buf_ptr(src_field->name)));
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ ir_assert(src_field->decl_node != nullptr, source_instr);
+ AstNode *existing_assign_node = field_assign_nodes[dst_field->src_index];
+ if (existing_assign_node != nullptr) {
+ ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("duplicate field"));
+ add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ field_assign_nodes[dst_field->src_index] = src_field->decl_node;
+
+ IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr,
+ struct_operand->value->type, false);
+ if (type_is_invalid(field_ptr->value->type))
+ return ira->codegen->invalid_inst_gen;
+ IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr);
+ if (type_is_invalid(field_value->value->type))
+ return ira->codegen->invalid_inst_gen;
+ IrInstGen *casted_value = ir_implicit_cast(ira, field_value, dst_field->type_entry);
+ if (type_is_invalid(casted_value->value->type))
+ return ira->codegen->invalid_inst_gen;
+
+ casted_fields[dst_field->src_index] = casted_value;
+ if (need_comptime || instr_is_comptime(casted_value)) {
+ ZigValue *field_val = ir_resolve_const(ira, casted_value, UndefOk);
+ if (field_val == nullptr)
+ return ira->codegen->invalid_inst_gen;
+ field_val->parent.id = ConstParentIdStruct;
+ field_val->parent.data.p_struct.struct_val = const_result->value;
+ field_val->parent.data.p_struct.field_index = dst_field->src_index;
+ field_values[dst_field->src_index] = field_val;
+ } else {
+ is_comptime = false;
+ }
+ }
+
+ bool any_missing = false;
+ for (size_t i = 0; i < actual_field_count; i += 1) {
+ if (field_assign_nodes[i] != nullptr) continue;
+
+ // look for a default field value
+ TypeStructField *field = wanted_type->data.structure.fields[i];
+ memoize_field_init_val(ira->codegen, wanted_type, field);
+ if (field->init_val == nullptr) {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("missing field: '%s'", buf_ptr(field->name)));
+ any_missing = true;
+ continue;
+ }
+ if (type_is_invalid(field->init_val->type))
+ return ira->codegen->invalid_inst_gen;
+ ZigValue *init_val_copy = ira->codegen->pass1_arena->create<ZigValue>();
+ copy_const_val(ira->codegen, init_val_copy, field->init_val);
+ init_val_copy->parent.id = ConstParentIdStruct;
+ init_val_copy->parent.data.p_struct.struct_val = const_result->value;
+ init_val_copy->parent.data.p_struct.field_index = i;
+ field_values[i] = init_val_copy;
+ casted_fields[i] = ir_const_move(ira, source_instr, init_val_copy);
+ }
+ if (any_missing)
+ return ira->codegen->invalid_inst_gen;
+
+ if (is_comptime) {
+ heap::c_allocator.deallocate(field_assign_nodes, actual_field_count);
+ IrInstGen *const_result = ir_const(ira, source_instr, wanted_type);
+ const_result->value->data.x_struct.fields = field_values;
+ return const_result;
+ }
+
+ IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(),
+ wanted_type, nullptr, true, true);
+ if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) {
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ for (size_t i = 0; i < actual_field_count; i += 1) {
+ TypeStructField *field = wanted_type->data.structure.fields[i];
+ IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc_inst, wanted_type, true);
+ if (type_is_invalid(field_ptr->value->type))
+ return ira->codegen->invalid_inst_gen;
+ IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, field_ptr, casted_fields[i], true);
+ if (type_is_invalid(store_ptr_inst->value->type))
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ heap::c_allocator.deallocate(field_assign_nodes, actual_field_count);
+ heap::c_allocator.deallocate(field_values, actual_field_count);
+ heap::c_allocator.deallocate(casted_fields, actual_field_count);
+
+ return ir_get_deref(ira, source_instr, result_loc_inst, nullptr);
}
static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr,
@@ -14727,7 +14918,7 @@ static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* sou
TypeUnionField *union_field = find_union_type_field(union_type, only_field->name);
if (union_field == nullptr) {
ir_add_error_node(ira, only_field->decl_node,
- buf_sprintf("no member named '%s' in union '%s'",
+ buf_sprintf("no field named '%s' in union '%s'",
buf_ptr(only_field->name), buf_ptr(&union_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -14849,7 +15040,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
}
// This means the wanted type is anything.
- if (wanted_type == ira->codegen->builtin_types.entry_var) {
+ if (wanted_type == ira->codegen->builtin_types.entry_anytype) {
return value;
}
@@ -15127,46 +15318,6 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
}
}
- // *[N]T to E![]T
- if (wanted_type->id == ZigTypeIdErrorUnion &&
- is_slice(wanted_type->data.error_union.payload_type) &&
- actual_type->id == ZigTypeIdPointer &&
- actual_type->data.pointer.ptr_len == PtrLenSingle &&
- actual_type->data.pointer.child_type->id == ZigTypeIdArray)
- {
- ZigType *slice_type = wanted_type->data.error_union.payload_type;
- ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
- assert(slice_ptr_type->id == ZigTypeIdPointer);
- ZigType *array_type = actual_type->data.pointer.child_type;
- bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
- || !actual_type->data.pointer.is_const);
- if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
- array_type->data.array.child_type, source_node,
- !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
- {
- // If the pointers both have ABI align, it works.
- bool ok_align = slice_ptr_type->data.pointer.explicit_alignment == 0 &&
- actual_type->data.pointer.explicit_alignment == 0;
- if (!ok_align) {
- // If either one has non ABI align, we have to resolve them both
- if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type,
- ResolveStatusAlignmentKnown)))
- {
- return ira->codegen->invalid_inst_gen;
- }
- if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type,
- ResolveStatusAlignmentKnown)))
- {
- return ira->codegen->invalid_inst_gen;
- }
- ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);
- }
- if (ok_align) {
- return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr);
- }
- }
- }
-
// @Vector(N,T1) to @Vector(N,T2)
if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) {
if (actual_type->data.vector.len == wanted_type->data.vector.len &&
@@ -15346,6 +15497,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
if (is_pointery_and_elem_is_not_pointery(actual_type)) {
ZigType *dest_ptr_type = nullptr;
if (wanted_type->id == ZigTypeIdPointer &&
+ actual_type->id != ZigTypeIdOptional &&
wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void)
{
dest_ptr_type = wanted_type;
@@ -15483,7 +15635,7 @@ static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *ex
static ZigType *get_ptr_elem_type(CodeGen *g, IrInstGen *ptr) {
ir_assert_gen(ptr->value->type->id == ZigTypeIdPointer, ptr);
ZigType *elem_type = ptr->value->type->data.pointer.child_type;
- if (elem_type != g->builtin_types.entry_var)
+ if (elem_type != g->builtin_types.entry_anytype)
return elem_type;
if (ir_resolve_lazy(g, ptr->base.source_node, ptr->value))
@@ -15535,7 +15687,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns
}
if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value);
- if (child_type == ira->codegen->builtin_types.entry_var) {
+ if (child_type == ira->codegen->builtin_types.entry_anytype) {
child_type = pointee->type;
}
if (pointee->special != ConstValSpecialRuntime) {
@@ -18353,7 +18505,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
if (decl_var_instruction->var_type != nullptr) {
var_type = decl_var_instruction->var_type->child;
ZigType *proposed_type = ir_resolve_type(ira, var_type);
- explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type);
+ explicit_type = validate_var_type(ira->codegen, &var->decl_node->data.variable_declaration, proposed_type);
if (type_is_invalid(explicit_type)) {
var->var_type = ira->codegen->builtin_types.entry_invalid;
return ira->codegen->invalid_inst_gen;
@@ -18935,7 +19087,7 @@ static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out
ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
if (type_is_invalid(dest_type))
return ErrorSemanticAnalyzeFail;
- *out = (dest_type != ira->codegen->builtin_types.entry_var);
+ *out = (dest_type != ira->codegen->builtin_types.entry_anytype);
return ErrorNone;
}
case ResultLocIdVar:
@@ -19141,7 +19293,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
if (type_is_invalid(dest_type))
return ira->codegen->invalid_inst_gen;
- if (dest_type == ira->codegen->builtin_types.entry_var) {
+ if (dest_type == ira->codegen->builtin_types.entry_anytype) {
return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type);
}
@@ -19287,7 +19439,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
return ira->codegen->invalid_inst_gen;
}
- if (child_type != ira->codegen->builtin_types.entry_var) {
+ if (child_type != ira->codegen->builtin_types.entry_anytype) {
if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) {
// pointer cast won't work; we need a temporary location.
result_bit_cast->parent->written = parent_was_written;
@@ -19448,9 +19600,9 @@ static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSr
if (type_is_invalid(implicit_elem_type))
return ira->codegen->invalid_inst_gen;
} else {
- implicit_elem_type = ira->codegen->builtin_types.entry_var;
+ implicit_elem_type = ira->codegen->builtin_types.entry_anytype;
}
- if (implicit_elem_type == ira->codegen->builtin_types.entry_var) {
+ if (implicit_elem_type == ira->codegen->builtin_types.entry_anytype) {
Buf *bare_name = buf_alloc();
Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
instruction->base.base.scope, instruction->base.base.source_node, bare_name);
@@ -19607,7 +19759,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
assert(param_decl_node->type == NodeTypeParamDecl);
IrInstGen *casted_arg;
- if (param_decl_node->data.param_decl.var_token == nullptr) {
+ if (param_decl_node->data.param_decl.anytype_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
if (type_is_invalid(param_type))
@@ -19647,7 +19799,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
arg_part_of_generic_id = true;
casted_arg = arg;
} else {
- if (param_decl_node->data.param_decl.var_token == nullptr) {
+ if (param_decl_node->data.param_decl.anytype_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
if (type_is_invalid(param_type))
@@ -19859,7 +20011,7 @@ static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr,
}
if (ptr->value->type->data.pointer.inferred_struct_field != nullptr &&
- child_type == ira->codegen->builtin_types.entry_var)
+ child_type == ira->codegen->builtin_types.entry_anytype)
{
child_type = ptr->value->type->data.pointer.inferred_struct_field->inferred_struct_type;
}
@@ -20030,7 +20182,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
}
IrInstGen *first_arg;
- if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) {
+ if (!first_arg_known_bare) {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
@@ -20050,6 +20202,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
}
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
+ if (return_type_node == nullptr) {
+ ir_add_error(ira, &fn_ref->base,
+ buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"));
+ return ira->codegen->invalid_inst_gen;
+ }
ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node);
if (type_is_invalid(specified_return_type))
return ira->codegen->invalid_inst_gen;
@@ -20160,7 +20317,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
}
IrInstGen *first_arg;
- if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) {
+ if (!first_arg_known_bare) {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
@@ -20212,7 +20369,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
inst_fn_type_id.alignment = align_bytes;
}
- if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
+ if (fn_proto_node->data.fn_proto.return_anytype_token == nullptr) {
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
if (type_is_invalid(specified_return_type))
@@ -20311,7 +20468,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (type_is_invalid(dummy_result->value->type))
return ira->codegen->invalid_inst_gen;
ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
- if (res_child_type == ira->codegen->builtin_types.entry_var) {
+ if (res_child_type == ira->codegen->builtin_types.entry_anytype) {
res_child_type = impl_fn_type_id->return_type;
}
if (!handle_is_ptr(ira->codegen, res_child_type)) {
@@ -20365,9 +20522,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
return ira->codegen->invalid_inst_gen;
IrInstGen *first_arg;
- if (param_type->id == ZigTypeIdPointer &&
- handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type))
- {
+ if (param_type->id == ZigTypeIdPointer) {
first_arg = first_arg_ptr;
} else {
first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
@@ -20454,7 +20609,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (type_is_invalid(dummy_result->value->type))
return ira->codegen->invalid_inst_gen;
ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
- if (res_child_type == ira->codegen->builtin_types.entry_var) {
+ if (res_child_type == ira->codegen->builtin_types.entry_anytype) {
res_child_type = return_type;
}
if (!handle_is_ptr(ira->codegen, res_child_type)) {
@@ -20614,40 +20769,106 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
modifier, stack, stack_src, false, args_ptr, args_len, nullptr, result_loc);
}
-static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) {
- IrInstGen *args = instruction->args->child;
+static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_instr, CallModifier modifier,
+ IrInstSrc *pass1_fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstGen **args_ptr, size_t args_len, ResultLoc *result_loc)
+{
+ IrInstGen *fn_ref = pass1_fn_ref->child;
+ if (type_is_invalid(fn_ref->value->type))
+ return ira->codegen->invalid_inst_gen;
+
+ if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) {
+ ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ IrInstGen *first_arg_ptr = nullptr;
+ IrInst *first_arg_ptr_src = nullptr;
+ ZigFn *fn = nullptr;
+ if (instr_is_comptime(fn_ref)) {
+ if (fn_ref->value->type->id == ZigTypeIdBoundFn) {
+ assert(fn_ref->value->special == ConstValSpecialStatic);
+ fn = fn_ref->value->data.x_bound_fn.fn;
+ first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg;
+ first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src;
+ if (type_is_invalid(first_arg_ptr->value->type))
+ return ira->codegen->invalid_inst_gen;
+ } else {
+ fn = ir_resolve_fn(ira, fn_ref);
+ }
+ }
+
+ IrInstGen *ret_ptr_uncasted = nullptr;
+ if (ret_ptr != nullptr) {
+ ret_ptr_uncasted = ret_ptr->child;
+ if (type_is_invalid(ret_ptr_uncasted->value->type))
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type;
+ IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack->child,
+ &new_stack->base, true, fn);
+ if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type))
+ return ira->codegen->invalid_inst_gen;
+
+ return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src,
+ modifier, casted_new_stack, &new_stack->base, true, args_ptr, args_len, ret_ptr_uncasted, result_loc);
+}
+
+static bool ir_extract_tuple_call_args(IrAnalyze *ira, IrInst *source_instr, IrInstGen *args, IrInstGen ***args_ptr, size_t *args_len) {
ZigType *args_type = args->value->type;
if (type_is_invalid(args_type))
- return ira->codegen->invalid_inst_gen;
+ return false;
if (args_type->id != ZigTypeIdStruct) {
ir_add_error(ira, &args->base,
buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name)));
- return ira->codegen->invalid_inst_gen;
+ return false;
}
- IrInstGen **args_ptr = nullptr;
- size_t args_len = 0;
-
if (is_tuple(args_type)) {
- args_len = args_type->data.structure.src_field_count;
- args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len);
- for (size_t i = 0; i < args_len; i += 1) {
+ *args_len = args_type->data.structure.src_field_count;
+ *args_ptr = heap::c_allocator.allocate<IrInstGen *>(*args_len);
+ for (size_t i = 0; i < *args_len; i += 1) {
TypeStructField *arg_field = args_type->data.structure.fields[i];
- args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field);
- if (type_is_invalid(args_ptr[i]->value->type))
- return ira->codegen->invalid_inst_gen;
+ (*args_ptr)[i] = ir_analyze_struct_value_field_value(ira, source_instr, args, arg_field);
+ if (type_is_invalid((*args_ptr)[i]->value->type))
+ return false;
}
} else {
ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args"));
+ return false;
+ }
+ return true;
+}
+
+static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) {
+ IrInstGen *args = instruction->args->child;
+ IrInstGen **args_ptr = nullptr;
+ size_t args_len = 0;
+ if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) {
return ira->codegen->invalid_inst_gen;
}
+
IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options,
instruction->fn_ref, args_ptr, args_len, instruction->result_loc);
heap::c_allocator.deallocate(args_ptr, args_len);
return result;
}
+static IrInstGen *ir_analyze_instruction_async_call_extra(IrAnalyze *ira, IrInstSrcAsyncCallExtra *instruction) {
+ IrInstGen *args = instruction->args->child;
+ IrInstGen **args_ptr = nullptr;
+ size_t args_len = 0;
+ if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) {
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ IrInstGen *result = ir_analyze_async_call_extra(ira, &instruction->base.base, instruction->modifier,
+ instruction->fn_ref, instruction->ret_ptr, instruction->new_stack, args_ptr, args_len, instruction->result_loc);
+ heap::c_allocator.deallocate(args_ptr, args_len);
+ return result;
+}
+
static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) {
IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len);
for (size_t i = 0; i < instruction->args_len; i += 1) {
@@ -20881,17 +21102,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
if (type_is_invalid(expr_type))
return ira->codegen->invalid_inst_gen;
- if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt ||
- expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat ||
- expr_type->id == ZigTypeIdVector))
- {
- ir_add_error(ira, &instruction->base.base,
- buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));
- return ira->codegen->invalid_inst_gen;
- }
-
bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);
+ switch (expr_type->id) {
+ case ZigTypeIdComptimeInt:
+ case ZigTypeIdFloat:
+ case ZigTypeIdComptimeFloat:
+ case ZigTypeIdVector:
+ break;
+ case ZigTypeIdInt:
+ if (is_wrap_op || expr_type->data.integral.is_signed)
+ break;
+ ZIG_FALLTHROUGH;
+ default:
+ ir_add_error(ira, &instruction->base.base,
+ buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));
+ return ira->codegen->invalid_inst_gen;
+ }
+
ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
if (instr_is_comptime(value)) {
@@ -22112,7 +22340,7 @@ static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
inferred_struct_field->inferred_struct_type = container_type;
inferred_struct_field->field_name = field_name;
- ZigType *elem_type = ira->codegen->builtin_types.entry_var;
+ ZigType *elem_type = ira->codegen->builtin_types.entry_anytype;
ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile,
PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr);
@@ -22407,7 +22635,7 @@ static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFiel
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_sprintf("no field named '%s' in '%s'", buf_ptr(field_name),
buf_ptr(&container_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -23834,7 +24062,7 @@ static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instructi
TypeUnionField *type_field = find_union_type_field(union_type, field_name);
if (type_field == nullptr) {
ir_add_error_node(ira, field_source_node,
- buf_sprintf("no member named '%s' in union '%s'",
+ buf_sprintf("no field named '%s' in union '%s'",
buf_ptr(field_name), buf_ptr(&union_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -23930,7 +24158,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
TypeStructField *type_field = find_struct_type_field(container_type, field->name);
if (!type_field) {
ir_add_error_node(ira, field->source_node,
- buf_sprintf("no member named '%s' in struct '%s'",
+ buf_sprintf("no field named '%s' in struct '%s'",
buf_ptr(field->name), buf_ptr(&container_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -23965,7 +24193,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
memoize_field_init_val(ira->codegen, container_type, field);
if (field->init_val == nullptr) {
ir_add_error(ira, source_instr,
- buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name)));
+ buf_sprintf("missing field: '%s'", buf_ptr(field->name)));
any_missing = true;
continue;
}
@@ -24890,7 +25118,7 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_ent
fields[5]->special = ConstValSpecialStatic;
fields[5]->type = ira->codegen->builtin_types.entry_bool;
fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero;
- // sentinel: var
+ // sentinel: anytype
ensure_field_index(result->type, "sentinel", 6);
fields[6]->special = ConstValSpecialStatic;
if (attrs_type->data.pointer.child_type->id != ZigTypeIdOpaque) {
@@ -25018,7 +25246,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
fields[1]->special = ConstValSpecialStatic;
fields[1]->type = ira->codegen->builtin_types.entry_type;
fields[1]->data.x_type = type_entry->data.array.child_type;
- // sentinel: var
+ // sentinel: anytype
fields[2]->special = ConstValSpecialStatic;
fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type);
fields[2]->data.x_optional = type_entry->data.array.sentinel;
@@ -25318,7 +25546,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Struct", nullptr);
- ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3);
+ ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4);
result->data.x_struct.fields = fields;
// layout: ContainerLayout
@@ -25373,7 +25601,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
inner_fields[2]->data.x_type = struct_field->type_entry;
- // default_value: var
+ // default_value: anytype
inner_fields[3]->special = ConstValSpecialStatic;
inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;
@@ -25399,6 +25627,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
return err;
}
+ // is_tuple: bool
+ ensure_field_index(result->type, "is_tuple", 3);
+ fields[3]->special = ConstValSpecialStatic;
+ fields[3]->type = ira->codegen->builtin_types.entry_bool;
+ fields[3]->data.x_bool = is_tuple(type_entry);
+
break;
}
case ZigTypeIdFn:
@@ -25504,9 +25738,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
break;
}
case ZigTypeIdFnFrame:
- ir_add_error(ira, source_instr,
- buf_sprintf("compiler bug: TODO @typeInfo for async function frames. https://github.com/ziglang/zig/issues/3066"));
- return ErrorSemanticAnalyzeFail;
+ {
+ result = ira->codegen->pass1_arena->create<ZigValue>();
+ result->special = ConstValSpecialStatic;
+ result->type = ir_type_info_get_type(ira, "Frame", nullptr);
+ ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1);
+ result->data.x_struct.fields = fields;
+ ZigFn *fn = type_entry->data.frame.fn;
+ // function: anytype
+ ensure_field_index(result->type, "function", 0);
+ fields[0] = create_const_fn(ira->codegen, fn);
+ break;
+ }
}
assert(result != nullptr);
@@ -25676,6 +25919,11 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
{
return ira->codegen->invalid_inst_gen->value->type;
}
+ if (sentinel != nullptr && (size_enum_index == BuiltinPtrSizeOne || size_enum_index == BuiltinPtrSizeC)) {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("sentinels are only allowed on slices and unknown-length pointers"));
+ return ira->codegen->invalid_inst_gen->value->type;
+ }
BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3);
if (bi == nullptr)
return ira->codegen->invalid_inst_gen->value->type;
@@ -25709,7 +25957,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
0, // host_int_bytes
is_allowzero,
VECTOR_INDEX_NONE, nullptr, sentinel);
- if (size_enum_index != 2)
+ if (size_enum_index != BuiltinPtrSizeSlice)
return ptr_type;
return get_slice_type(ira->codegen, ptr_type);
}
@@ -25775,10 +26023,90 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
ZigType *child_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "child", 0);
return get_any_frame_type(ira->codegen, child_type);
}
- case ZigTypeIdErrorSet:
- case ZigTypeIdEnum:
- case ZigTypeIdFnFrame:
case ZigTypeIdEnumLiteral:
+ return ira->codegen->builtin_types.entry_enum_literal;
+ case ZigTypeIdFnFrame: {
+ assert(payload->special == ConstValSpecialStatic);
+ assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr));
+ ZigValue *function = get_const_field(ira, source_instr->source_node, payload, "function", 0);
+ assert(function->type->id == ZigTypeIdFn);
+ ZigFn *fn = function->data.x_ptr.data.fn.fn_entry;
+ return get_fn_frame_type(ira->codegen, fn);
+ }
+ case ZigTypeIdErrorSet: {
+ assert(payload->special == ConstValSpecialStatic);
+ assert(payload->type->id == ZigTypeIdOptional);
+ ZigValue *slice = payload->data.x_optional;
+ if (slice == nullptr)
+ return ira->codegen->builtin_types.entry_global_error_set;
+ assert(slice->special == ConstValSpecialStatic);
+ assert(is_slice(slice->type));
+ ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
+ Buf bare_name = BUF_INIT;
+ buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->old_irb.exec, "error", source_instr->scope, source_instr->source_node, &bare_name));
+ err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
+ err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
+ err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;
+ ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];
+ assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);;
+ assert(ptr->data.x_ptr.data.base_array.elem_index == 0);
+ ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;
+ assert(arr->special == ConstValSpecialStatic);
+ assert(arr->data.x_array.special == ConstArraySpecialNone);
+ ZigValue *len = slice->data.x_struct.fields[slice_len_index];
+ size_t count = bigint_as_usize(&len->data.x_bigint);
+ err_set_type->data.error_set.err_count = count;
+ err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count);
+ bool *already_set = heap::c_allocator.allocate<bool>(ira->codegen->errors_by_index.length + count);
+ for (size_t i = 0; i < count; i++) {
+ ZigValue *error = &arr->data.x_array.data.s_none.elements[i];
+ assert(error->type == ir_type_info_get_type(ira, "Error", nullptr));
+ ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>();
+ err_entry->decl_node = source_instr->source_node;
+ ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0);
+ ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index];
+ ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index];
+ assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
+ assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0);
+ ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val;
+ assert(name_arr->special == ConstValSpecialStatic);
+ switch (name_arr->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ return ira->codegen->invalid_inst_gen->value->type;
+ case ConstArraySpecialNone: {
+ buf_resize(&err_entry->name, 0);
+ size_t name_count = bigint_as_usize(&name_len->data.x_bigint);
+ for (size_t j = 0; j < name_count; j++) {
+ ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j];
+ unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
+ buf_append_char(&err_entry->name, ch);
+ }
+ break;
+ }
+ case ConstArraySpecialBuf:
+ buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf);
+ break;
+ }
+ auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry);
+ if (existing_entry) {
+ err_entry->value = existing_entry->value->value;
+ } else {
+ size_t error_value_count = ira->codegen->errors_by_index.length;
+ assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count));
+ err_entry->value = error_value_count;
+ ira->codegen->errors_by_index.append(err_entry);
+ }
+ if (already_set[err_entry->value]) {
+ ir_add_error(ira, source_instr, buf_sprintf("duplicate error: %s", buf_ptr(&err_entry->name)));
+ return ira->codegen->invalid_inst_gen->value->type;
+ } else {
+ already_set[err_entry->value] = true;
+ }
+ err_set_type->data.error_set.errors[i] = err_entry;
+ }
+ return err_set_type;
+ }
+ case ZigTypeIdEnum:
ir_add_error(ira, source_instr, buf_sprintf(
"TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId)));
return ira->codegen->invalid_inst_gen->value->type;
@@ -26370,6 +26698,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa
}
if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) {
+ ZigValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (val == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);
}
@@ -26407,16 +26739,20 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo
}
}
- if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) {
- return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);
- }
-
if (target->value->type->id != ZigTypeIdFloat) {
ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'",
buf_ptr(&target->value->type->name)));
return ira->codegen->invalid_inst_gen;
}
+ if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) {
+ ZigValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (val == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
+ return ir_analyze_widen_or_shorten(ira, &instruction->target->base, target, dest_type);
+ }
+
return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type);
}
@@ -28660,7 +28996,37 @@ static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
ir_add_error(ira, &instruction->base.base,
buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name)));
return ira->codegen->invalid_inst_gen;
- }
+ } else if(switch_type->id == ZigTypeIdMetaType) {
+ HashMap<const ZigType*, IrInstGen*, type_ptr_hash, type_ptr_eql> prevs;
+ // HashMap doubles capacity when reaching 60% capacity,
+ // because we know the size at init we can avoid reallocation by doubling it here
+ prevs.init(instruction->range_count * 2);
+ for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
+ IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i];
+
+ IrInstGen *value = range->start->child;
+ IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type);
+ if (type_is_invalid(casted_value->value->type)) {
+ prevs.deinit();
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad);
+ if (!const_expr_val) {
+ prevs.deinit();
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ auto entry = prevs.put_unique(const_expr_val->data.x_type, value);
+ if(entry != nullptr) {
+ ErrorMsg *msg = ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value"));
+ add_error_note(ira->codegen, msg, entry->value->base.source_node, buf_sprintf("previous value is here"));
+ prevs.deinit();
+ return ira->codegen->invalid_inst_gen;
+ }
+ }
+ prevs.deinit();
+ }
return ir_const_void(ira, &instruction->base.base);
}
@@ -29650,7 +30016,7 @@ static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgTy
if (arg_index >= fn_type_id->param_count) {
if (instruction->allow_var) {
// TODO remove this with var args
- return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var);
+ return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_anytype);
}
ir_add_error(ira, &arg_index_inst->base,
buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",
@@ -29664,7 +30030,7 @@ static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgTy
ir_assert(fn_type->data.fn.is_generic, &instruction->base.base);
if (instruction->allow_var) {
- return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var);
+ return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_anytype);
} else {
ir_add_error(ira, &arg_index_inst->base,
buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
@@ -30173,6 +30539,21 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
case BuiltinFnIdSqrt:
f128M_sqrt(in, out);
break;
+ case BuiltinFnIdFabs:
+ f128M_abs(in, out);
+ break;
+ case BuiltinFnIdFloor:
+ f128M_roundToInt(in, softfloat_round_min, false, out);
+ break;
+ case BuiltinFnIdCeil:
+ f128M_roundToInt(in, softfloat_round_max, false, out);
+ break;
+ case BuiltinFnIdTrunc:
+ f128M_trunc(in, out);
+ break;
+ case BuiltinFnIdRound:
+ f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
+ break;
case BuiltinFnIdNearbyInt:
case BuiltinFnIdSin:
case BuiltinFnIdCos:
@@ -30181,11 +30562,6 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
case BuiltinFnIdLog:
case BuiltinFnIdLog10:
case BuiltinFnIdLog2:
- case BuiltinFnIdFabs:
- case BuiltinFnIdFloor:
- case BuiltinFnIdCeil:
- case BuiltinFnIdTrunc:
- case BuiltinFnIdRound:
return ir_add_error(ira, source_instr,
buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
float_op_to_name(fop), buf_ptr(&float_type->name)));
@@ -30769,6 +31145,64 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil
return ir_build_spill_end_gen(ira, &instruction->base.base, begin, operand->value->type);
}
+static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instruction) {
+ ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope);
+ if (fn_entry == nullptr) {
+ ir_add_error(ira, &instruction->base.base, buf_sprintf("@src outside function"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ ZigType *u8_ptr = get_pointer_to_type_extra2(
+ ira->codegen, ira->codegen->builtin_types.entry_u8,
+ true, false, PtrLenUnknown,
+ 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte());
+ ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
+
+ ZigType *source_location_type = get_builtin_type(ira->codegen, "SourceLocation");
+ if (type_resolve(ira->codegen, source_location_type, ResolveStatusSizeKnown)) {
+ zig_unreachable();
+ }
+
+ ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>();
+ result->special = ConstValSpecialStatic;
+ result->type = source_location_type;
+
+ ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4);
+ result->data.x_struct.fields = fields;
+
+ // file: [:0]const u8
+ ensure_field_index(source_location_type, "file", 0);
+ fields[0]->special = ConstValSpecialStatic;
+
+ ZigType *import = instruction->base.base.source_node->owner;
+ Buf *path = import->data.structure.root_struct->path;
+ ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee;
+ init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true);
+ fields[0]->type = u8_slice;
+
+ // fn_name: [:0]const u8
+ ensure_field_index(source_location_type, "fn_name", 1);
+ fields[1]->special = ConstValSpecialStatic;
+
+ ZigValue *fn_name = create_const_str_lit(ira->codegen, &fn_entry->symbol_name)->data.x_ptr.data.ref.pointee;
+ init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true);
+ fields[1]->type = u8_slice;
+
+ // line: u32
+ ensure_field_index(source_location_type, "line", 2);
+ fields[2]->special = ConstValSpecialStatic;
+ fields[2]->type = ira->codegen->builtin_types.entry_u32;
+ bigint_init_unsigned(&fields[2]->data.x_bigint, instruction->base.base.source_node->line + 1);
+
+ // column: u32
+ ensure_field_index(source_location_type, "column", 3);
+ fields[3]->special = ConstValSpecialStatic;
+ fields[3]->type = ira->codegen->builtin_types.entry_u32;
+ bigint_init_unsigned(&fields[3]->data.x_bigint, instruction->base.base.source_node->column + 1);
+
+ return ir_const_move(ira, &instruction->base.base, result);
+}
+
static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruction) {
switch (instruction->id) {
case IrInstSrcIdInvalid:
@@ -30802,6 +31236,8 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction);
case IrInstSrcIdCallExtra:
return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction);
+ case IrInstSrcIdAsyncCallExtra:
+ return ir_analyze_instruction_async_call_extra(ira, (IrInstSrcAsyncCallExtra *)instruction);
case IrInstSrcIdBr:
return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction);
case IrInstSrcIdCondBr:
@@ -31040,6 +31476,8 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
return ir_analyze_instruction_wasm_memory_size(ira, (IrInstSrcWasmMemorySize *)instruction);
case IrInstSrcIdWasmMemoryGrow:
return ir_analyze_instruction_wasm_memory_grow(ira, (IrInstSrcWasmMemoryGrow *)instruction);
+ case IrInstSrcIdSrc:
+ return ir_analyze_instruction_src(ira, (IrInstSrcSrc *)instruction);
}
zig_unreachable();
}
@@ -31309,6 +31747,7 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
case IrInstSrcIdDeclVar:
case IrInstSrcIdStorePtr:
case IrInstSrcIdCallExtra:
+ case IrInstSrcIdAsyncCallExtra:
case IrInstSrcIdCall:
case IrInstSrcIdCallArgs:
case IrInstSrcIdReturn:
@@ -31435,6 +31874,7 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
case IrInstSrcIdAlloca:
case IrInstSrcIdSpillEnd:
case IrInstSrcIdWasmMemorySize:
+ case IrInstSrcIdSrc:
return false;
case IrInstSrcIdAsm: