diff --git a/src/Sema.zig b/src/Sema.zig index 2cec686989..bcac427caf 100644 --- 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 index 0580d7cd3c..01df65a715 100644 --- 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 index e8a13d7034..dd7c843099 100644 --- 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 new file mode 100644 index 0000000000..ff94382d1f --- /dev/null +++ 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 new file mode 100644 index 0000000000..f98fcfbcff --- /dev/null +++ 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); +}