authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-10 00:53:26+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-15 00:50:18+03:00
log5e4483fff8077ec8d87ba9125f946955a34b6fc0
treed3c03ca0b8197aaf3f9163deb5ac13910bff19b5
parent5e37da6ade7eb307d51c21a2dfcdbef23e9cbf08

Sema: handle comptime fields in field call bind

Closes #12801

5 files changed, 50 insertions(+), 1 deletions(-)

src/Sema.zig+8-1
...@@ -21683,12 +21683,19 @@ fn finishFieldCallBind(...@@ -21683,12 +21683,19 @@ fn finishFieldCallBind(
21683 .@"addrspace" = ptr_ty.ptrAddressSpace(),21683 .@"addrspace" = ptr_ty.ptrAddressSpace(),
21684 });21684 });
2168521685
21686 const container_ty = ptr_ty.childType();
21687 if (container_ty.zigTypeTag() == .Struct) {
21688 if (container_ty.structFieldValueComptime(field_index)) |default_val| {
21689 return sema.addConstant(field_ty, default_val);
21690 }
21691 }
21692
21686 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {21693 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {
21687 const pointer = try sema.addConstant(21694 const pointer = try sema.addConstant(
21688 ptr_field_ty,21695 ptr_field_ty,
21689 try Value.Tag.field_ptr.create(arena, .{21696 try Value.Tag.field_ptr.create(arena, .{
21690 .container_ptr = struct_ptr_val,21697 .container_ptr = struct_ptr_val,
21691 .container_ty = ptr_ty.childType(),21698 .container_ty = container_ty,
21692 .field_index = field_index,21699 .field_index = field_index,
21693 }),21700 }),
21694 );21701 );
src/value.zig+3
...@@ -2778,6 +2778,9 @@ pub const Value = extern union {...@@ -2778,6 +2778,9 @@ pub const Value = extern union {
2778 const tuple = ty.tupleFields();2778 const tuple = ty.tupleFields();
2779 return tuple.values[index];2779 return tuple.values[index];
2780 }2780 }
2781 if (ty.structFieldValueComptime(index)) |some| {
2782 return some;
2783 }
2781 unreachable;2784 unreachable;
2782 },2785 },
2783 .undef => return Value.undef,2786 .undef => return Value.undef,
test/behavior.zig+2
...@@ -89,6 +89,8 @@ test {...@@ -89,6 +89,8 @@ test {
89 _ = @import("behavior/bugs/12776.zig");89 _ = @import("behavior/bugs/12776.zig");
90 _ = @import("behavior/bugs/12786.zig");90 _ = @import("behavior/bugs/12786.zig");
91 _ = @import("behavior/bugs/12794.zig");91 _ = @import("behavior/bugs/12794.zig");
92 _ = @import("behavior/bugs/12801-1.zig");
93 _ = @import("behavior/bugs/12801-2.zig");
92 _ = @import("behavior/byteswap.zig");94 _ = @import("behavior/byteswap.zig");
93 _ = @import("behavior/byval_arg_var.zig");95 _ = @import("behavior/byval_arg_var.zig");
94 _ = @import("behavior/call.zig");96 _ = @import("behavior/call.zig");
test/behavior/bugs/12801-1.zig created+13
...@@ -0,0 +1,13 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4comptime capacity: fn () u64 = capacity_,
5fn capacity_() u64 {
6 return 64;
7}
8
9test {
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11
12 try std.testing.expect((@This(){}).capacity() == 64);
13}
test/behavior/bugs/12801-2.zig created+24
...@@ -0,0 +1,24 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4const Auto = struct {
5 auto: [max_len]u8 = undefined,
6 offset: u64 = 0,
7
8 comptime capacity: *const fn () u64 = capacity,
9
10 const max_len: u64 = 32;
11
12 fn capacity() u64 {
13 return max_len;
14 }
15};
16test {
17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
20
21 const a: Auto = .{ .offset = 16, .capacity = Auto.capacity };
22 try std.testing.expect(a.capacity() == 32);
23 try std.testing.expect((a.capacity)() == 32);
24}