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,...@@ -17675,18 +17675,36 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
17675 assert(container_scope != nullptr);17675 assert(container_scope != nullptr);
17676 auto entry = container_scope->decl_table.maybe_get(field_name);17676 auto entry = container_scope->decl_table.maybe_get(field_name);
17677 Tld *tld = entry ? entry->value : nullptr;17677 Tld *tld = entry ? entry->value : nullptr;
17678 if (tld && tld->id == TldIdFn) {17678 if (tld) {
17679 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);17679 if (tld->id == TldIdFn) {
17680 if (tld->resolution == TldResolutionInvalid)17680 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false);
17681 return ira->codegen->invalid_instruction;17681 if (tld->resolution == TldResolutionInvalid)
17682 TldFn *tld_fn = (TldFn *)tld;17682 return ira->codegen->invalid_instruction;
17683 ZigFn *fn_entry = tld_fn->fn_entry;17683 TldFn *tld_fn = (TldFn *)tld;
17684 if (type_is_invalid(fn_entry->type_entry))17684 ZigFn *fn_entry = tld_fn->fn_entry;
17685 return ira->codegen->invalid_instruction;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,17700 if (var->const_value->type->id == ZigTypeIdFn) {
17688 source_instr->source_node, fn_entry, container_ptr);17701 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr);
17689 return ir_get_ref(ira, source_instr, bound_fn_value, true, false);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 }
17690 }17708 }
17691 }17709 }
17692 const char *prefix_name;17710 const char *prefix_name;
test/stage1/behavior.zig+1
...@@ -58,6 +58,7 @@ comptime {...@@ -58,6 +58,7 @@ comptime {
58 _ = @import("behavior/floatop.zig");58 _ = @import("behavior/floatop.zig");
59 _ = @import("behavior/fn.zig");59 _ = @import("behavior/fn.zig");
60 _ = @import("behavior/fn_in_struct_in_comptime.zig");60 _ = @import("behavior/fn_in_struct_in_comptime.zig");
61 _ = @import("behavior/fn_delegation.zig");
61 _ = @import("behavior/for.zig");62 _ = @import("behavior/for.zig");
62 _ = @import("behavior/generics.zig");63 _ = @import("behavior/generics.zig");
63 _ = @import("behavior/hasdecl.zig");64 _ = @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}