fix using @typeOf on a generic function call
This commit is contained in:
parent
0fe28855c5
commit
d291d3c8c0
58
src/ir.cpp
58
src/ir.cpp
|
@ -15648,6 +15648,31 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
|
|||
return &store_ptr->base;
|
||||
}
|
||||
|
||||
static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
|
||||
ZigFn *fn_entry)
|
||||
{
|
||||
if (call_instruction->new_stack == nullptr)
|
||||
return nullptr;
|
||||
|
||||
IrInstruction *new_stack = call_instruction->new_stack->child;
|
||||
if (type_is_invalid(new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (call_instruction->is_async_call_builtin &&
|
||||
fn_entry != nullptr && new_stack->value.type->id == ZigTypeIdPointer &&
|
||||
new_stack->value.type->data.pointer.child_type->id == ZigTypeIdFnFrame)
|
||||
{
|
||||
ZigType *needed_frame_type = get_pointer_to_type(ira->codegen,
|
||||
get_fn_frame_type(ira->codegen, fn_entry), false);
|
||||
return ir_implicit_cast(ira, new_stack, needed_frame_type);
|
||||
} else {
|
||||
ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
|
||||
false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false);
|
||||
ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
|
||||
return ir_implicit_cast(ira, new_stack, u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
|
||||
ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,
|
||||
IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)
|
||||
|
@ -15826,31 +15851,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
return ir_finish_anal(ira, new_instruction);
|
||||
}
|
||||
|
||||
IrInstruction *casted_new_stack = nullptr;
|
||||
if (call_instruction->new_stack != nullptr) {
|
||||
IrInstruction *new_stack = call_instruction->new_stack->child;
|
||||
if (type_is_invalid(new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (call_instruction->is_async_call_builtin &&
|
||||
fn_entry != nullptr && new_stack->value.type->id == ZigTypeIdPointer &&
|
||||
new_stack->value.type->data.pointer.child_type->id == ZigTypeIdFnFrame)
|
||||
{
|
||||
ZigType *needed_frame_type = get_pointer_to_type(ira->codegen,
|
||||
get_fn_frame_type(ira->codegen, fn_entry), false);
|
||||
casted_new_stack = ir_implicit_cast(ira, new_stack, needed_frame_type);
|
||||
if (type_is_invalid(casted_new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
|
||||
false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false);
|
||||
ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
|
||||
casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice);
|
||||
if (type_is_invalid(casted_new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
}
|
||||
|
||||
if (fn_type->data.fn.is_generic) {
|
||||
if (!fn_entry) {
|
||||
ir_add_error(ira, call_instruction->fn_ref,
|
||||
|
@ -16063,6 +16063,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
parent_fn_entry->calls_or_awaits_errorable_fn = true;
|
||||
}
|
||||
|
||||
IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, impl_fn);
|
||||
if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
size_t impl_param_count = impl_fn_type_id->param_count;
|
||||
if (call_instruction->is_async) {
|
||||
IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
|
||||
|
@ -16211,6 +16215,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
|
|||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, call_instruction, fn_entry);
|
||||
if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value.type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (call_instruction->is_async) {
|
||||
IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
|
||||
casted_args, call_param_count, casted_new_stack);
|
||||
|
|
|
@ -1031,3 +1031,28 @@ test "@typeOf an async function call of generic fn with error union type" {
|
|||
};
|
||||
_ = async S.func(i32);
|
||||
}
|
||||
|
||||
test "using @typeOf on a generic function call" {
|
||||
const S = struct {
|
||||
var global_frame: anyframe = undefined;
|
||||
var global_ok = false;
|
||||
|
||||
var buf: [100]u8 align(16) = undefined;
|
||||
|
||||
fn amain(x: var) void {
|
||||
if (x == 0) {
|
||||
global_ok = true;
|
||||
return;
|
||||
}
|
||||
suspend {
|
||||
global_frame = @frame();
|
||||
}
|
||||
const F = @typeOf(async amain(x - 1));
|
||||
const frame = @intToPtr(*F, @ptrToInt(&buf));
|
||||
return await @asyncCall(frame, {}, amain, x - 1);
|
||||
}
|
||||
};
|
||||
_ = async S.amain(u32(1));
|
||||
resume S.global_frame;
|
||||
expect(S.global_ok);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user