parent
56b1818beb
commit
9983501ff2
40
src/ir.cpp
40
src/ir.cpp
|
@ -17675,18 +17675,36 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
|
|||
assert(container_scope != nullptr);
|
||||
auto entry = container_scope->decl_table.maybe_get(field_name);
|
||||
Tld *tld = entry ? entry->value : nullptr;
|
||||
if (tld && tld->id == TldIdFn) {
|
||||
resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->invalid_instruction;
|
||||
TldFn *tld_fn = (TldFn *)tld;
|
||||
ZigFn *fn_entry = tld_fn->fn_entry;
|
||||
if (type_is_invalid(fn_entry->type_entry))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (tld) {
|
||||
if (tld->id == TldIdFn) {
|
||||
resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->invalid_instruction;
|
||||
TldFn *tld_fn = (TldFn *)tld;
|
||||
ZigFn *fn_entry = tld_fn->fn_entry;
|
||||
if (type_is_invalid(fn_entry->type_entry))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, fn_entry, container_ptr);
|
||||
return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
|
||||
IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, fn_entry, container_ptr);
|
||||
return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
|
||||
} else if (tld->id == TldIdVar) {
|
||||
resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->invalid_instruction;
|
||||
TldVar *tld_var = (TldVar *)tld;
|
||||
ZigVar *var = tld_var->var;
|
||||
if (type_is_invalid(var->var_type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (var->const_value->type->id == ZigTypeIdFn) {
|
||||
ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr);
|
||||
ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry;
|
||||
IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
|
||||
source_instr->source_node, fn, container_ptr);
|
||||
return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const char *prefix_name;
|
||||
|
|
|
@ -58,6 +58,7 @@ comptime {
|
|||
_ = @import("behavior/floatop.zig");
|
||||
_ = @import("behavior/fn.zig");
|
||||
_ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
_ = @import("behavior/fn_delegation.zig");
|
||||
_ = @import("behavior/for.zig");
|
||||
_ = @import("behavior/generics.zig");
|
||||
_ = @import("behavior/hasdecl.zig");
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const expect = @import("std").testing.expect;
|
||||
|
||||
const Foo = struct {
|
||||
a: u64 = 10,
|
||||
|
||||
fn one(self: Foo) u64 {
|
||||
return self.a + 1;
|
||||
}
|
||||
|
||||
const two = __two;
|
||||
|
||||
fn __two(self: Foo) u64 {
|
||||
return self.a + 2;
|
||||
}
|
||||
|
||||
const three = __three;
|
||||
|
||||
const four = custom(Foo, 4);
|
||||
};
|
||||
|
||||
fn __three(self: Foo) u64 {
|
||||
return self.a + 3;
|
||||
}
|
||||
|
||||
fn custom(comptime T: type, comptime num: u64) fn (T) u64 {
|
||||
return struct {
|
||||
fn function(self: T) u64 {
|
||||
return self.a + num;
|
||||
}
|
||||
}.function;
|
||||
}
|
||||
|
||||
test "fn delegation" {
|
||||
const foo = Foo{};
|
||||
expect(foo.one() == 11);
|
||||
expect(foo.two() == 12);
|
||||
expect(foo.three() == 13);
|
||||
expect(foo.four() == 14);
|
||||
}
|
Loading…
Reference in New Issue