authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-14 14:38:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-14 14:38:40-07:00
log4696cd3e09c4e33519dbb53a41c32bbdfd97f6f6
tree82757e8ebf565c4960c639e3604f4247daef4dc9
parent67273cbe7618253bffa56298b5bea0e1dd37dfc2

fix ability to call methods on enums with pointer-to-self

closes #3218

3 files changed, 42 insertions(+), 4 deletions(-)

src/ir.cpp+2-4
...@@ -20182,7 +20182,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20182,7 +20182,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20182 }20182 }
2018320183
20184 IrInstGen *first_arg;20184 IrInstGen *first_arg;
20185 if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) {20185 if (!first_arg_known_bare) {
20186 first_arg = first_arg_ptr;20186 first_arg = first_arg_ptr;
20187 } else {20187 } else {
20188 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);20188 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
...@@ -20522,9 +20522,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20522,9 +20522,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20522 return ira->codegen->invalid_inst_gen;20522 return ira->codegen->invalid_inst_gen;
2052320523
20524 IrInstGen *first_arg;20524 IrInstGen *first_arg;
20525 if (param_type->id == ZigTypeIdPointer &&20525 if (param_type->id == ZigTypeIdPointer) {
20526 handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type))
20527 {
20528 first_arg = first_arg_ptr;20526 first_arg = first_arg_ptr;
20529 } else {20527 } else {
20530 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);20528 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
test/stage1/behavior/enum.zig+19
...@@ -1140,3 +1140,22 @@ test "tagName on enum literals" {...@@ -1140,3 +1140,22 @@ test "tagName on enum literals" {
1140 expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));1140 expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
1141 comptime expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));1141 comptime expect(mem.eql(u8, @tagName(.FooBar), "FooBar"));
1142}1142}
1143
1144test "method call on an enum" {
1145 const S = struct {
1146 const E = enum {
1147 one,
1148 two,
1149
1150 fn method(self: *E) bool {
1151 return self.* == .two;
1152 }
1153 };
1154 fn doTheTest() void {
1155 var e = E.two;
1156 expect(e.method());
1157 }
1158 };
1159 S.doTheTest();
1160 comptime S.doTheTest();
1161}
test/stage1/behavior/union.zig+21
...@@ -669,3 +669,24 @@ test "cast from anonymous struct to union" {...@@ -669,3 +669,24 @@ test "cast from anonymous struct to union" {
669 S.doTheTest();669 S.doTheTest();
670 comptime S.doTheTest();670 comptime S.doTheTest();
671}671}
672
673test "method call on an empty union" {
674 const S = struct {
675 const MyUnion = union(Tag) {
676 pub const Tag = enum { X1, X2 };
677 X1: [0]u8,
678 X2: [0]u8,
679
680 pub fn useIt(self: *@This()) bool {
681 return true;
682 }
683 };
684
685 fn doTheTest() void {
686 var u = MyUnion{ .X1 = [0]u8{} };
687 expect(u.useIt());
688 }
689 };
690 S.doTheTest();
691 comptime S.doTheTest();
692}