zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 5e4483fff8077ec8d87ba9125f946955a34b6fc0 (tree)
parent 5e37da6ade7eb307d51c21a2dfcdbef23e9cbf08
Author: Veikka Tuominen <git@vexu.eu>
Date:   Sat, 10 Sep 2022 00:53:26 +0300

Sema: handle comptime fields in field call bind

Closes #12801

Diffstat:
Msrc/Sema.zig | 9++++++++-
Msrc/value.zig | 3+++
Mtest/behavior.zig | 2++
Atest/behavior/bugs/12801-1.zig | 13+++++++++++++
Atest/behavior/bugs/12801-2.zig | 24++++++++++++++++++++++++
5 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/Sema.zig b/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, }), ); diff --git a/src/value.zig b/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, diff --git a/test/behavior.zig b/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"); diff --git a/test/behavior/bugs/12801-1.zig b/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); +} diff --git a/test/behavior/bugs/12801-2.zig b/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); +}