mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 22:09:49 +00:00
don't make OPV tuple fields comptime
This commit is contained in:
parent
60a332406c
commit
60be67d3c0
45
src/Sema.zig
45
src/Sema.zig
@ -2824,9 +2824,6 @@ fn zirTupleDecl(
|
||||
}
|
||||
break :init field_init_val.toIntern();
|
||||
}
|
||||
if (try sema.typeHasOnePossibleValue(field_type)) |opv| {
|
||||
break :init opv.toIntern();
|
||||
}
|
||||
break :init .none;
|
||||
};
|
||||
}
|
||||
@ -21479,18 +21476,8 @@ fn reifyTuple(
|
||||
return sema.fail(block, src, "non-comptime tuple fields cannot specify default initialization value", .{});
|
||||
}
|
||||
|
||||
const default_or_opv: InternPool.Index = default: {
|
||||
if (field_default_value != .none) {
|
||||
break :default field_default_value;
|
||||
}
|
||||
if (try sema.typeHasOnePossibleValue(field_type)) |opv| {
|
||||
break :default opv.toIntern();
|
||||
}
|
||||
break :default .none;
|
||||
};
|
||||
|
||||
field_ty.* = field_type.toIntern();
|
||||
field_init.* = default_or_opv;
|
||||
field_init.* = field_default_value;
|
||||
}
|
||||
|
||||
return Air.internedToRef(try zcu.intern_pool.getTupleType(gpa, pt.tid, .{
|
||||
@ -36282,13 +36269,31 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
|
||||
},
|
||||
|
||||
.tuple_type => |tuple| {
|
||||
for (tuple.values.get(ip)) |val| {
|
||||
if (val == .none) return null;
|
||||
try ty.resolveLayout(pt);
|
||||
|
||||
if (tuple.types.len == 0) {
|
||||
return try pt.aggregateValue(ty, &.{});
|
||||
}
|
||||
// In this case the struct has all comptime-known fields and
|
||||
// therefore has one possible value.
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
return try pt.aggregateValue(ty, try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)));
|
||||
|
||||
const field_vals = try sema.arena.alloc(
|
||||
InternPool.Index,
|
||||
tuple.types.len,
|
||||
);
|
||||
for (
|
||||
field_vals,
|
||||
tuple.types.get(ip),
|
||||
tuple.values.get(ip),
|
||||
) |*field_val, field_ty, field_comptime_val| {
|
||||
if (field_comptime_val != .none) {
|
||||
field_val.* = field_comptime_val;
|
||||
continue;
|
||||
}
|
||||
if (try sema.typeHasOnePossibleValue(.fromInterned(field_ty))) |opv| {
|
||||
field_val.* = opv.toIntern();
|
||||
} else return null;
|
||||
}
|
||||
|
||||
return try pt.aggregateValue(ty, field_vals);
|
||||
},
|
||||
|
||||
.union_type => {
|
||||
|
||||
63
src/Type.zig
63
src/Type.zig
@ -2581,15 +2581,30 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
|
||||
},
|
||||
|
||||
.tuple_type => |tuple| {
|
||||
for (tuple.values.get(ip)) |val| {
|
||||
if (val == .none) return null;
|
||||
if (tuple.types.len == 0) {
|
||||
return try pt.aggregateValue(ty, &.{});
|
||||
}
|
||||
// In this case the struct has all comptime-known fields and
|
||||
// therefore has one possible value.
|
||||
// TODO: write something like getCoercedInts to avoid needing to dupe
|
||||
const duped_values = try zcu.gpa.dupe(InternPool.Index, tuple.values.get(ip));
|
||||
defer zcu.gpa.free(duped_values);
|
||||
return try pt.aggregateValue(ty, duped_values);
|
||||
|
||||
const field_vals = try zcu.gpa.alloc(
|
||||
InternPool.Index,
|
||||
tuple.types.len,
|
||||
);
|
||||
defer zcu.gpa.free(field_vals);
|
||||
for (
|
||||
field_vals,
|
||||
tuple.types.get(ip),
|
||||
tuple.values.get(ip),
|
||||
) |*field_val, field_ty, field_comptime_val| {
|
||||
if (field_comptime_val != .none) {
|
||||
field_val.* = field_comptime_val;
|
||||
continue;
|
||||
}
|
||||
if (try Type.fromInterned(field_ty).onePossibleValue(pt)) |opv| {
|
||||
field_val.* = opv.toIntern();
|
||||
} else return null;
|
||||
}
|
||||
|
||||
return try pt.aggregateValue(ty, field_vals);
|
||||
},
|
||||
|
||||
.union_type => {
|
||||
@ -2630,24 +2645,22 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
|
||||
.auto, .explicit => {
|
||||
if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;
|
||||
|
||||
switch (enum_type.names.len) {
|
||||
0 => {
|
||||
const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
|
||||
return Value.fromInterned(only);
|
||||
},
|
||||
1 => {
|
||||
if (enum_type.values.len == 0) {
|
||||
const only = try pt.intern(.{ .enum_tag = .{
|
||||
.ty = ty.toIntern(),
|
||||
.int = (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern(),
|
||||
} });
|
||||
return Value.fromInterned(only);
|
||||
} else {
|
||||
return Value.fromInterned(enum_type.values.get(ip)[0]);
|
||||
}
|
||||
},
|
||||
return Value.fromInterned(switch (enum_type.names.len) {
|
||||
0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
|
||||
1 => try pt.intern(.{ .enum_tag = .{
|
||||
.ty = ty.toIntern(),
|
||||
.int = if (enum_type.values.len == 0)
|
||||
(try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern()
|
||||
else
|
||||
try ip.getCoercedInts(
|
||||
zcu.gpa,
|
||||
pt.tid,
|
||||
ip.indexToKey(enum_type.values.get(ip)[0]).int,
|
||||
enum_type.tag_ty,
|
||||
),
|
||||
} }),
|
||||
else => return null,
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@ -611,3 +611,24 @@ test "field pointer of underaligned tuple" {
|
||||
try S.doTheTest();
|
||||
try comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "OPV tuple fields aren't comptime" {
|
||||
const T = struct { void };
|
||||
const t_info = @typeInfo(T);
|
||||
try expect(!t_info.@"struct".fields[0].is_comptime);
|
||||
|
||||
const T2 = @Type(.{ .@"struct" = .{
|
||||
.layout = .auto,
|
||||
.fields = &.{.{
|
||||
.name = "0",
|
||||
.type = void,
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = @alignOf(void),
|
||||
}},
|
||||
.decls = &.{},
|
||||
.is_tuple = true,
|
||||
} });
|
||||
const t2_info = @typeInfo(T2);
|
||||
try expect(!t2_info.@"struct".fields[0].is_comptime);
|
||||
}
|
||||
|
||||
@ -8,5 +8,5 @@ export fn entry() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :6:31: error: expected type 'tmp.S', found 'struct { comptime void = {} }'
|
||||
// :6:31: error: expected type 'tmp.S', found 'struct { void }'
|
||||
// :1:11: note: struct declared here
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user