authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2019-09-24 17:53:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-24 19:24:48-04:00
log9983501ff2cccf828bb357dddefb21e36813046d
tree4e46409e9a0fc1ba3cf0abbeb831c74b1107498e
parent56b1818beb0e6acce60ff399556af257acc77983

add VarDecl support for struct-method call syntax

implements #3306

3 files changed, 69 insertions(+), 11 deletions(-)

src/ir.cpp+29-11
......@@ -17675,18 +17675,36 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
1767517675 assert(container_scope != nullptr);
1767617676 auto entry = container_scope->decl_table.maybe_get(field_name);
1767717677 Tld *tld = entry ? entry->value : nullptr;
17678 if (tld && tld->id == TldIdFn) {
17679 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
17680 if (tld->resolution == TldResolutionInvalid)
17681 return ira->codegen->invalid_instruction;
17682 TldFn *tld_fn = (TldFn *)tld;
17683 ZigFn *fn_entry = tld_fn->fn_entry;
17684 if (type_is_invalid(fn_entry->type_entry))
17685 return ira->codegen->invalid_instruction;
17678 if (tld) {
17679 if (tld->id == TldIdFn) {
17680 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
17681 if (tld->resolution == TldResolutionInvalid)
17682 return ira->codegen->invalid_instruction;
17683 TldFn *tld_fn = (TldFn *)tld;
17684 ZigFn *fn_entry = tld_fn->fn_entry;
17685 if (type_is_invalid(fn_entry->type_entry))
17686 return ira->codegen->invalid_instruction;
17687
17688 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
17689 source_instr->source_node, fn_entry, container_ptr);
17690 return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
17691 } else if (tld->id == TldIdVar) {
17692 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
17693 if (tld->resolution == TldResolutionInvalid)
17694 return ira->codegen->invalid_instruction;
17695 TldVar *tld_var = (TldVar *)tld;
17696 ZigVar *var = tld_var->var;
17697 if (type_is_invalid(var->var_type))
17698 return ira->codegen->invalid_instruction;
1768617699
17687 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
17688 source_instr->source_node, fn_entry, container_ptr);
17689 return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
17700 if (var->const_value->type->id == ZigTypeIdFn) {
17701 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr);
17702 ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry;
17703 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope,
17704 source_instr->source_node, fn, container_ptr);
17705 return ir_get_ref(ira, source_instr, bound_fn_value, true, false);
17706 }
17707 }
1769017708 }
1769117709 }
1769217710 const char *prefix_name;
test/stage1/behavior.zig+1
......@@ -58,6 +58,7 @@ comptime {
5858 _ = @import("behavior/floatop.zig");
5959 _ = @import("behavior/fn.zig");
6060 _ = @import("behavior/fn_in_struct_in_comptime.zig");
61 _ = @import("behavior/fn_delegation.zig");
6162 _ = @import("behavior/for.zig");
6263 _ = @import("behavior/generics.zig");
6364 _ = @import("behavior/hasdecl.zig");
test/stage1/behavior/fn_delegation.zig created+39
......@@ -0,0 +1,39 @@
1const expect = @import("std").testing.expect;
2
3const Foo = struct {
4 a: u64 = 10,
5
6 fn one(self: Foo) u64 {
7 return self.a + 1;
8 }
9
10 const two = __two;
11
12 fn __two(self: Foo) u64 {
13 return self.a + 2;
14 }
15
16 const three = __three;
17
18 const four = custom(Foo, 4);
19};
20
21fn __three(self: Foo) u64 {
22 return self.a + 3;
23}
24
25fn custom(comptime T: type, comptime num: u64) fn (T) u64 {
26 return struct {
27 fn function(self: T) u64 {
28 return self.a + num;
29 }
30 }.function;
31}
32
33test "fn delegation" {
34 const foo = Foo{};
35 expect(foo.one() == 11);
36 expect(foo.two() == 12);
37 expect(foo.three() == 13);
38 expect(foo.four() == 14);
39}