parent
956ba8b0e7
commit
37318bf151
@ -5404,7 +5404,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
|
|||||||
<p>
|
<p>
|
||||||
For example, if we were to introduce another function to the above snippet:
|
For example, if we were to introduce another function to the above snippet:
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test_err|cannot store runtime value in type 'type'#}
|
{#code_begin|test_err|values of type 'type' must be comptime known#}
|
||||||
fn max(comptime T: type, a: T, b: T) T {
|
fn max(comptime T: type, a: T, b: T) T {
|
||||||
return if (a > b) a else b;
|
return if (a > b) a else b;
|
||||||
}
|
}
|
||||||
|
@ -645,12 +645,6 @@ pub const Loop = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is equivalent to function call, except it calls `startCpuBoundOperation` first.
|
|
||||||
pub fn call(comptime func: var, args: ...) @typeOf(func).ReturnType {
|
|
||||||
startCpuBoundOperation();
|
|
||||||
return func(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Yielding lets the event loop run, starting any unstarted async operations.
|
/// Yielding lets the event loop run, starting any unstarted async operations.
|
||||||
/// Note that async operations automatically start when a function yields for any other reason,
|
/// Note that async operations automatically start when a function yields for any other reason,
|
||||||
/// for example, when async I/O is performed. This function is intended to be used only when
|
/// for example, when async I/O is performed. This function is intended to be used only when
|
||||||
@ -942,23 +936,6 @@ test "std.event.Loop - basic" {
|
|||||||
loop.run();
|
loop.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
test "std.event.Loop - call" {
|
|
||||||
// https://github.com/ziglang/zig/issues/1908
|
|
||||||
if (builtin.single_threaded) return error.SkipZigTest;
|
|
||||||
|
|
||||||
var loop: Loop = undefined;
|
|
||||||
try loop.initMultiThreaded();
|
|
||||||
defer loop.deinit();
|
|
||||||
|
|
||||||
var did_it = false;
|
|
||||||
var handle = async Loop.call(testEventLoop);
|
|
||||||
var handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
|
|
||||||
|
|
||||||
loop.run();
|
|
||||||
|
|
||||||
testing.expect(did_it);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn testEventLoop() i32 {
|
async fn testEventLoop() i32 {
|
||||||
return 1234;
|
return 1234;
|
||||||
}
|
}
|
||||||
|
@ -3665,6 +3665,7 @@ struct IrInstructionArgType {
|
|||||||
|
|
||||||
IrInstruction *fn_type;
|
IrInstruction *fn_type;
|
||||||
IrInstruction *arg_index;
|
IrInstruction *arg_index;
|
||||||
|
bool allow_var;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrInstructionExport {
|
struct IrInstructionExport {
|
||||||
|
@ -7820,6 +7820,11 @@ static void define_builtin_types(CodeGen *g) {
|
|||||||
buf_init_from_str(&entry->name, "(null)");
|
buf_init_from_str(&entry->name, "(null)");
|
||||||
g->builtin_types.entry_null = entry;
|
g->builtin_types.entry_null = entry;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
|
||||||
|
buf_init_from_str(&entry->name, "(var)");
|
||||||
|
g->builtin_types.entry_var = entry;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
|
ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
|
||||||
buf_init_from_str(&entry->name, "(args)");
|
buf_init_from_str(&entry->name, "(args)");
|
||||||
|
155
src/ir.cpp
155
src/ir.cpp
@ -206,6 +206,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
|
|||||||
TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
|
TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
|
||||||
static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
|
static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
|
||||||
IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
|
IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
|
||||||
|
static ResultLoc *no_result_loc(void);
|
||||||
|
|
||||||
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
|
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
|
||||||
assert(get_src_ptr_type(const_val->type) != nullptr);
|
assert(get_src_ptr_type(const_val->type) != nullptr);
|
||||||
@ -3115,11 +3116,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast
|
|||||||
}
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||||
IrInstruction *fn_type, IrInstruction *arg_index)
|
IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var)
|
||||||
{
|
{
|
||||||
IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);
|
IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);
|
||||||
instruction->fn_type = fn_type;
|
instruction->fn_type = fn_type;
|
||||||
instruction->arg_index = arg_index;
|
instruction->arg_index = arg_index;
|
||||||
|
instruction->allow_var = allow_var;
|
||||||
|
|
||||||
ir_ref_instruction(fn_type, irb->current_basic_block);
|
ir_ref_instruction(fn_type, irb->current_basic_block);
|
||||||
ir_ref_instruction(arg_index, irb->current_basic_block);
|
ir_ref_instruction(arg_index, irb->current_basic_block);
|
||||||
@ -5647,7 +5649,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
|||||||
if (arg1_value == irb->codegen->invalid_instruction)
|
if (arg1_value == irb->codegen->invalid_instruction)
|
||||||
return arg1_value;
|
return arg1_value;
|
||||||
|
|
||||||
IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
|
IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false);
|
||||||
return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
|
return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
|
||||||
}
|
}
|
||||||
case BuiltinFnIdExport:
|
case BuiltinFnIdExport:
|
||||||
@ -5842,13 +5844,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
|
|||||||
if (fn_ref == irb->codegen->invalid_instruction)
|
if (fn_ref == irb->codegen->invalid_instruction)
|
||||||
return fn_ref;
|
return fn_ref;
|
||||||
|
|
||||||
|
IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref);
|
||||||
|
|
||||||
size_t arg_count = node->data.fn_call_expr.params.length;
|
size_t arg_count = node->data.fn_call_expr.params.length;
|
||||||
IrInstruction **args = allocate<IrInstruction*>(arg_count);
|
IrInstruction **args = allocate<IrInstruction*>(arg_count);
|
||||||
for (size_t i = 0; i < arg_count; i += 1) {
|
for (size_t i = 0; i < arg_count; i += 1) {
|
||||||
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
|
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
|
||||||
args[i] = ir_gen_node(irb, arg_node, scope);
|
|
||||||
if (args[i] == irb->codegen->invalid_instruction)
|
IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i);
|
||||||
return args[i];
|
IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true);
|
||||||
|
ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc());
|
||||||
|
|
||||||
|
IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base);
|
||||||
|
if (arg == irb->codegen->invalid_instruction)
|
||||||
|
return arg;
|
||||||
|
|
||||||
|
args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
|
IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
|
||||||
@ -12504,6 +12515,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr,
|
||||||
|
IrInstruction *value, ZigType *wanted_type)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array"));
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr,
|
||||||
|
IrInstruction *value, ZigType *wanted_type)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct"));
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr,
|
||||||
|
IrInstruction *value, ZigType *wanted_type)
|
||||||
|
{
|
||||||
|
ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union"));
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
|
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
|
||||||
ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
|
ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
|
||||||
{
|
{
|
||||||
@ -12515,6 +12547,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This means the wanted type is anything.
|
||||||
|
if (wanted_type == ira->codegen->builtin_types.entry_var) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
// perfect match or non-const to const
|
// perfect match or non-const to const
|
||||||
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
|
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
|
||||||
source_node, false);
|
source_node, false);
|
||||||
@ -13071,6 +13108,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
|
return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cast from inferred struct type to array, union, or struct
|
||||||
|
if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) {
|
||||||
|
AstNode *decl_node = actual_type->data.structure.decl_node;
|
||||||
|
ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr);
|
||||||
|
ContainerInitKind init_kind = decl_node->data.container_init_expr.kind;
|
||||||
|
uint32_t field_count = actual_type->data.structure.src_field_count;
|
||||||
|
if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) &&
|
||||||
|
wanted_type->data.array.len == field_count)
|
||||||
|
{
|
||||||
|
return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type);
|
||||||
|
} else if (wanted_type->id == ZigTypeIdStruct &&
|
||||||
|
(init_kind == ContainerInitKindStruct || field_count == 0))
|
||||||
|
{
|
||||||
|
return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type);
|
||||||
|
} else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) {
|
||||||
|
return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cast from undefined to anything
|
// cast from undefined to anything
|
||||||
if (actual_type->id == ZigTypeIdUndefined) {
|
if (actual_type->id == ZigTypeIdUndefined) {
|
||||||
return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
|
return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
|
||||||
@ -15537,21 +15593,31 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
|
|||||||
ptr->value.data.x_ptr.data.ref.pointee = undef_child;
|
ptr->value.data.x_ptr.data.ref.pointee = undef_child;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ir_result_has_type(ResultLoc *result_loc) {
|
static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) {
|
||||||
switch (result_loc->id) {
|
switch (result_loc->id) {
|
||||||
case ResultLocIdInvalid:
|
case ResultLocIdInvalid:
|
||||||
case ResultLocIdPeerParent:
|
case ResultLocIdPeerParent:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case ResultLocIdNone:
|
case ResultLocIdNone:
|
||||||
case ResultLocIdPeer:
|
case ResultLocIdPeer:
|
||||||
return false;
|
*out = false;
|
||||||
|
return ErrorNone;
|
||||||
case ResultLocIdReturn:
|
case ResultLocIdReturn:
|
||||||
case ResultLocIdInstruction:
|
case ResultLocIdInstruction:
|
||||||
case ResultLocIdBitCast:
|
case ResultLocIdBitCast:
|
||||||
case ResultLocIdCast:
|
*out = true;
|
||||||
return true;
|
return ErrorNone;
|
||||||
|
case ResultLocIdCast: {
|
||||||
|
ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc);
|
||||||
|
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);
|
||||||
|
return ErrorNone;
|
||||||
|
}
|
||||||
case ResultLocIdVar:
|
case ResultLocIdVar:
|
||||||
return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
|
*out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
|
||||||
|
return ErrorNone;
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
@ -15698,7 +15764,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (ir_result_has_type(peer_parent->parent)) {
|
bool peer_parent_has_type;
|
||||||
|
if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
if (peer_parent_has_type) {
|
||||||
if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {
|
if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {
|
||||||
reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true;
|
reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true;
|
||||||
ira->src_implicit_return_type_list.append(value);
|
ira->src_implicit_return_type_list.append(value);
|
||||||
@ -15741,6 +15810,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
|
|||||||
if (type_is_invalid(dest_type))
|
if (type_is_invalid(dest_type))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
|
if (dest_type == ira->codegen->builtin_types.entry_var) {
|
||||||
|
return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
|
||||||
|
force_runtime, non_null_comptime);
|
||||||
|
}
|
||||||
|
|
||||||
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type,
|
ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type,
|
||||||
result_cast->base.source_instruction->source_node, false);
|
result_cast->base.source_instruction->source_node, false);
|
||||||
if (const_cast_result.id == ConstCastResultIdInvalid)
|
if (const_cast_result.id == ConstCastResultIdInvalid)
|
||||||
@ -15948,6 +16022,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
|
|||||||
if (type_is_invalid(implicit_elem_type))
|
if (type_is_invalid(implicit_elem_type))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
} else {
|
} else {
|
||||||
|
implicit_elem_type = ira->codegen->builtin_types.entry_var;
|
||||||
|
}
|
||||||
|
if (implicit_elem_type == ira->codegen->builtin_types.entry_var) {
|
||||||
Buf *bare_name = buf_alloc();
|
Buf *bare_name = buf_alloc();
|
||||||
Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
|
Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
|
||||||
instruction->base.scope, instruction->base.source_node, bare_name);
|
instruction->base.scope, instruction->base.source_node, bare_name);
|
||||||
@ -17532,6 +17609,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
|
static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
|
||||||
|
Error err;
|
||||||
|
|
||||||
if (ira->const_predecessor_bb) {
|
if (ira->const_predecessor_bb) {
|
||||||
for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
|
for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
|
||||||
IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
|
IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
|
||||||
@ -17663,24 +17742,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
|
|||||||
}
|
}
|
||||||
|
|
||||||
ZigType *resolved_type;
|
ZigType *resolved_type;
|
||||||
if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) {
|
if (peer_parent != nullptr) {
|
||||||
if (peer_parent->parent->id == ResultLocIdReturn) {
|
bool peer_parent_has_type;
|
||||||
resolved_type = ira->explicit_return_type;
|
if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
|
||||||
} else if (peer_parent->parent->id == ResultLocIdCast) {
|
return ira->codegen->invalid_instruction;
|
||||||
resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
|
if (peer_parent_has_type) {
|
||||||
if (type_is_invalid(resolved_type))
|
if (peer_parent->parent->id == ResultLocIdReturn) {
|
||||||
return ira->codegen->invalid_instruction;
|
resolved_type = ira->explicit_return_type;
|
||||||
} else {
|
} else if (peer_parent->parent->id == ResultLocIdCast) {
|
||||||
ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
|
resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
|
||||||
ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
|
if (type_is_invalid(resolved_type))
|
||||||
resolved_type = resolved_loc_ptr_type->data.pointer.child_type;
|
return ira->codegen->invalid_instruction;
|
||||||
|
} else {
|
||||||
|
ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
|
||||||
|
ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
|
||||||
|
resolved_type = resolved_loc_ptr_type->data.pointer.child_type;
|
||||||
|
}
|
||||||
|
goto skip_resolve_peer_types;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
{
|
||||||
resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,
|
resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,
|
||||||
new_incoming_values.items, new_incoming_values.length);
|
new_incoming_values.items, new_incoming_values.length);
|
||||||
if (type_is_invalid(resolved_type))
|
if (type_is_invalid(resolved_type))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
}
|
}
|
||||||
|
skip_resolve_peer_types:
|
||||||
|
|
||||||
switch (type_has_one_possible_value(ira->codegen, resolved_type)) {
|
switch (type_has_one_possible_value(ira->codegen, resolved_type)) {
|
||||||
case OnePossibleValueInvalid:
|
case OnePossibleValueInvalid:
|
||||||
@ -18379,7 +18466,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n
|
|||||||
inferred_struct_field->inferred_struct_type = container_type;
|
inferred_struct_field->inferred_struct_type = container_type;
|
||||||
inferred_struct_field->field_name = field_name;
|
inferred_struct_field->field_name = field_name;
|
||||||
|
|
||||||
ZigType *elem_type = ira->codegen->builtin_types.entry_c_void;
|
ZigType *elem_type = ira->codegen->builtin_types.entry_var;
|
||||||
ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
|
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,
|
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);
|
PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field);
|
||||||
@ -25547,6 +25634,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
|
|||||||
if (!ir_resolve_usize(ira, arg_index_inst, &arg_index))
|
if (!ir_resolve_usize(ira, arg_index_inst, &arg_index))
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
|
if (fn_type->id == ZigTypeIdBoundFn) {
|
||||||
|
fn_type = fn_type->data.bound_fn.fn_type;
|
||||||
|
arg_index += 1;
|
||||||
|
}
|
||||||
if (fn_type->id != ZigTypeIdFn) {
|
if (fn_type->id != ZigTypeIdFn) {
|
||||||
ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name)));
|
ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name)));
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
@ -25554,6 +25645,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
|
|||||||
|
|
||||||
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
|
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
|
||||||
if (arg_index >= fn_type_id->param_count) {
|
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, ira->codegen->builtin_types.entry_var);
|
||||||
|
}
|
||||||
ir_add_error(ira, arg_index_inst,
|
ir_add_error(ira, arg_index_inst,
|
||||||
buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",
|
buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",
|
||||||
arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count));
|
arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count));
|
||||||
@ -25565,10 +25660,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
|
|||||||
// Args are only unresolved if our function is generic.
|
// Args are only unresolved if our function is generic.
|
||||||
ir_assert(fn_type->data.fn.is_generic, &instruction->base);
|
ir_assert(fn_type->data.fn.is_generic, &instruction->base);
|
||||||
|
|
||||||
ir_add_error(ira, arg_index_inst,
|
if (instruction->allow_var) {
|
||||||
buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
|
return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var);
|
||||||
arg_index, buf_ptr(&fn_type->name)));
|
} else {
|
||||||
return ira->codegen->invalid_instruction;
|
ir_add_error(ira, arg_index_inst,
|
||||||
|
buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
|
||||||
|
arg_index, buf_ptr(&fn_type->name)));
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ir_const_type(ira, &instruction->base, result_type);
|
return ir_const_type(ira, &instruction->base, result_type);
|
||||||
}
|
}
|
||||||
|
@ -2113,8 +2113,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||||||
\\
|
\\
|
||||||
\\fn bar(x: *b.Foo) void {}
|
\\fn bar(x: *b.Foo) void {}
|
||||||
,
|
,
|
||||||
"tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",
|
"tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'",
|
||||||
"tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
|
"tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
|
||||||
"a.zig:1:17: note: a.Foo declared here",
|
"a.zig:1:17: note: a.Foo declared here",
|
||||||
"b.zig:1:17: note: b.Foo declared here",
|
"b.zig:1:17: note: b.Foo declared here",
|
||||||
);
|
);
|
||||||
@ -4978,7 +4978,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||||||
\\
|
\\
|
||||||
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
|
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
|
||||||
,
|
,
|
||||||
"tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",
|
"tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'",
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
@ -5675,7 +5675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||||||
\\ x.* += 1;
|
\\ x.* += 1;
|
||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
"tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",
|
"tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'",
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.add(
|
cases.add(
|
||||||
|
@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" {
|
|||||||
S.entry();
|
S.entry();
|
||||||
comptime S.entry();
|
comptime S.entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "function call with anon list literal" {
|
||||||
|
const S = struct {
|
||||||
|
fn doTheTest() void {
|
||||||
|
consumeVec(.{9, 8, 7});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consumeVec(vec: [3]f32) void {
|
||||||
|
expect(vec[0] == 9);
|
||||||
|
expect(vec[1] == 8);
|
||||||
|
expect(vec[2] == 7);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
S.doTheTest();
|
||||||
|
comptime S.doTheTest();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user