Commit 5e4483fff8

Veikka Tuominen <git@vexu.eu>
2022-09-09 23:53:26
Sema: handle comptime fields in field call bind
Closes #12801
1 parent 5e37da6
Changed files (5)
src/Sema.zig
@@ -21683,12 +21683,19 @@ fn finishFieldCallBind(
         .@"addrspace" = ptr_ty.ptrAddressSpace(),
     });
 
+    const container_ty = ptr_ty.childType();
+    if (container_ty.zigTypeTag() == .Struct) {
+        if (container_ty.structFieldValueComptime(field_index)) |default_val| {
+            return sema.addConstant(field_ty, default_val);
+        }
+    }
+
     if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {
         const pointer = try sema.addConstant(
             ptr_field_ty,
             try Value.Tag.field_ptr.create(arena, .{
                 .container_ptr = struct_ptr_val,
-                .container_ty = ptr_ty.childType(),
+                .container_ty = container_ty,
                 .field_index = field_index,
             }),
         );
src/value.zig
@@ -2778,6 +2778,9 @@ pub const Value = extern union {
                     const tuple = ty.tupleFields();
                     return tuple.values[index];
                 }
+                if (ty.structFieldValueComptime(index)) |some| {
+                    return some;
+                }
                 unreachable;
             },
             .undef => return Value.undef,
test/behavior/bugs/12801-1.zig
@@ -0,0 +1,13 @@
+const std = @import("std");
+const builtin = @import("builtin");
+
+comptime capacity: fn () u64 = capacity_,
+fn capacity_() u64 {
+    return 64;
+}
+
+test {
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+    try std.testing.expect((@This(){}).capacity() == 64);
+}
test/behavior/bugs/12801-2.zig
@@ -0,0 +1,24 @@
+const std = @import("std");
+const builtin = @import("builtin");
+
+const Auto = struct {
+    auto: [max_len]u8 = undefined,
+    offset: u64 = 0,
+
+    comptime capacity: *const fn () u64 = capacity,
+
+    const max_len: u64 = 32;
+
+    fn capacity() u64 {
+        return max_len;
+    }
+};
+test {
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+    const a: Auto = .{ .offset = 16, .capacity = Auto.capacity };
+    try std.testing.expect(a.capacity() == 32);
+    try std.testing.expect((a.capacity)() == 32);
+}
test/behavior.zig
@@ -89,6 +89,8 @@ test {
     _ = @import("behavior/bugs/12776.zig");
     _ = @import("behavior/bugs/12786.zig");
     _ = @import("behavior/bugs/12794.zig");
+    _ = @import("behavior/bugs/12801-1.zig");
+    _ = @import("behavior/bugs/12801-2.zig");
     _ = @import("behavior/byteswap.zig");
     _ = @import("behavior/byval_arg_var.zig");
     _ = @import("behavior/call.zig");