mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
don't make anonymous tuple fields referencing comptime vars comptime
This commit is contained in:
parent
27aba2d776
commit
2c0aa1c6f5
29
src/Sema.zig
29
src/Sema.zig
@ -20048,10 +20048,14 @@ fn arrayInitAnon(
|
|||||||
const types = try sema.arena.alloc(InternPool.Index, operands.len);
|
const types = try sema.arena.alloc(InternPool.Index, operands.len);
|
||||||
const values = try sema.arena.alloc(InternPool.Index, operands.len);
|
const values = try sema.arena.alloc(InternPool.Index, operands.len);
|
||||||
|
|
||||||
|
var any_comptime = false;
|
||||||
const opt_runtime_src = rs: {
|
const opt_runtime_src = rs: {
|
||||||
var runtime_src: ?LazySrcLoc = null;
|
var runtime_src: ?LazySrcLoc = null;
|
||||||
for (operands, 0..) |operand, i| {
|
for (operands, 0..) |operand, i| {
|
||||||
const operand_src = src; // TODO better source location
|
const operand_src = block.src(.{ .init_elem = .{
|
||||||
|
.init_node_offset = src.offset.node_offset.x,
|
||||||
|
.elem_index = @intCast(i),
|
||||||
|
} });
|
||||||
const elem = try sema.resolveInst(operand);
|
const elem = try sema.resolveInst(operand);
|
||||||
types[i] = sema.typeOf(elem).toIntern();
|
types[i] = sema.typeOf(elem).toIntern();
|
||||||
if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {
|
if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {
|
||||||
@ -20066,6 +20070,7 @@ fn arrayInitAnon(
|
|||||||
}
|
}
|
||||||
if (try sema.resolveValue(elem)) |val| {
|
if (try sema.resolveValue(elem)) |val| {
|
||||||
values[i] = val.toIntern();
|
values[i] = val.toIntern();
|
||||||
|
any_comptime = true;
|
||||||
} else {
|
} else {
|
||||||
values[i] = .none;
|
values[i] = .none;
|
||||||
runtime_src = operand_src;
|
runtime_src = operand_src;
|
||||||
@ -20074,9 +20079,21 @@ fn arrayInitAnon(
|
|||||||
break :rs runtime_src;
|
break :rs runtime_src;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A field can't be `comptime` if it references a `comptime var` but the aggregate can still be comptime-known.
|
||||||
|
// Replace these fields with `.none` only for generating the type.
|
||||||
|
const values_no_comptime = if (!any_comptime) values else blk: {
|
||||||
|
const new_values = try sema.arena.alloc(InternPool.Index, operands.len);
|
||||||
|
for (values, new_values) |val, *new_val| {
|
||||||
|
if (val != .none and Value.fromInterned(val).canMutateComptimeVarState(zcu)) {
|
||||||
|
new_val.* = .none;
|
||||||
|
} else new_val.* = val;
|
||||||
|
}
|
||||||
|
break :blk new_values;
|
||||||
|
};
|
||||||
|
|
||||||
const tuple_ty: Type = .fromInterned(try ip.getTupleType(gpa, pt.tid, .{
|
const tuple_ty: Type = .fromInterned(try ip.getTupleType(gpa, pt.tid, .{
|
||||||
.types = types,
|
.types = types,
|
||||||
.values = values,
|
.values = values_no_comptime,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const runtime_src = opt_runtime_src orelse {
|
const runtime_src = opt_runtime_src orelse {
|
||||||
@ -20086,6 +20103,14 @@ fn arrayInitAnon(
|
|||||||
|
|
||||||
try sema.requireRuntimeBlock(block, src, runtime_src);
|
try sema.requireRuntimeBlock(block, src, runtime_src);
|
||||||
|
|
||||||
|
for (operands, 0..) |operand, i| {
|
||||||
|
const operand_src = block.src(.{ .init_elem = .{
|
||||||
|
.init_node_offset = src.offset.node_offset.x,
|
||||||
|
.elem_index = @intCast(i),
|
||||||
|
} });
|
||||||
|
try sema.validateRuntimeValue(block, operand_src, try sema.resolveInst(operand));
|
||||||
|
}
|
||||||
|
|
||||||
if (is_ref) {
|
if (is_ref) {
|
||||||
const target = sema.pt.zcu.getTarget();
|
const target = sema.pt.zcu.getTarget();
|
||||||
const alloc_ty = try pt.ptrTypeSema(.{
|
const alloc_ty = try pt.ptrTypeSema(.{
|
||||||
|
|||||||
@ -486,6 +486,15 @@ test "tuple with comptime fields with non empty initializer" {
|
|||||||
_ = a;
|
_ = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "anon tuple field referencing comptime var isn't comptime" {
|
||||||
|
comptime var a: u8 = 0;
|
||||||
|
const tuple = .{&a};
|
||||||
|
// field isn't comptime but tuple is still comptime-known
|
||||||
|
comptime assert(@TypeOf(tuple) == struct { *u8 });
|
||||||
|
a = 1;
|
||||||
|
comptime assert(tuple[0].* == 1);
|
||||||
|
}
|
||||||
|
|
||||||
test "tuple with runtime value coerced into a slice with a sentinel" {
|
test "tuple with runtime value coerced into a slice with a sentinel" {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user