Sema: handle comptime fields in field call bind

Closes #12801
This commit is contained in:
Veikka Tuominen 2022-09-10 00:53:26 +03:00
parent 5e37da6ade
commit 5e4483fff8
5 changed files with 50 additions and 1 deletions

View File

@ -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,
}),
);

View File

@ -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,

View File

@ -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");

View File

@ -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);
}

View File

@ -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);
}