Commit 4696cd3e09

Andrew Kelley <andrew@ziglang.org>
2020-07-14 23:38:40
fix ability to call methods on enums with pointer-to-self
closes #3218
1 parent 67273cb
Changed files (3)
src
test
stage1
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);
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();
+}
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();
+}