From 4696cd3e09c4e33519dbb53a41c32bbdfd97f6f6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 14 Jul 2020 14:38:40 -0700 Subject: [PATCH] fix ability to call methods on enums with pointer-to-self closes #3218 --- src/ir.cpp | 6 ++---- test/stage1/behavior/enum.zig | 19 +++++++++++++++++++ test/stage1/behavior/union.zig | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index dc380b4389c25ae6fa275e13633d49f70d422ed2..0dd8f4e86a3761132a79057a8fe3fd035dd77c38 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -20182,7 +20182,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, } IrInstGen *first_arg; - if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { + if (!first_arg_known_bare) { first_arg = first_arg_ptr; } else { 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, return ira->codegen->invalid_inst_gen; IrInstGen *first_arg; - if (param_type->id == ZigTypeIdPointer && - handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) - { + if (param_type->id == ZigTypeIdPointer) { first_arg = first_arg_ptr; } else { first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig index 765828f5ce14660583cb5b2044fbdcb8073e3a8c..b9bb1db5332fc8c73a3607c1ae7cf3ffd49b831e 100644 --- a/test/stage1/behavior/enum.zig +++ b/test/stage1/behavior/enum.zig @@ -1140,3 +1140,22 @@ test "tagName on enum literals" { expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); comptime expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); } + +test "method call on an enum" { + const S = struct { + const E = enum { + one, + two, + + fn method(self: *E) bool { + return self.* == .two; + } + }; + fn doTheTest() void { + var e = E.two; + expect(e.method()); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index da898347b96e575079b51df400f51580e3d6c161..cf3412eb5b7e0ee1e33e55b3fdd439204a5b553c 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -669,3 +669,24 @@ test "cast from anonymous struct to union" { S.doTheTest(); comptime S.doTheTest(); } + +test "method call on an empty union" { + const S = struct { + const MyUnion = union(Tag) { + pub const Tag = enum { X1, X2 }; + X1: [0]u8, + X2: [0]u8, + + pub fn useIt(self: *@This()) bool { + return true; + } + }; + + fn doTheTest() void { + var u = MyUnion{ .X1 = [0]u8{} }; + expect(u.useIt()); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} -- 2.54.0