aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-07-14 14:38:40 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-07-14 14:38:40 -0700
commit4696cd3e09c4e33519dbb53a41c32bbdfd97f6f6 (patch)
tree82757e8ebf565c4960c639e3604f4247daef4dc9
parent67273cbe7618253bffa56298b5bea0e1dd37dfc2 (diff)
downloadzig-4696cd3e09c4e33519dbb53a41c32bbdfd97f6f6.tar.gz
zig-4696cd3e09c4e33519dbb53a41c32bbdfd97f6f6.zip
fix ability to call methods on enums with pointer-to-self
closes #3218
-rw-r--r--src/ir.cpp6
-rw-r--r--test/stage1/behavior/enum.zig19
-rw-r--r--test/stage1/behavior/union.zig21
3 files changed, 42 insertions, 4 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index dc380b4389..0dd8f4e86a 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 765828f5ce..b9bb1db533 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 da898347b9..cf3412eb5b 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();
+}