aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2023-11-10 01:38:41 +0000
committerMatthew Lugg <mlugg@mlugg.co.uk>2023-11-10 06:51:48 +0000
commit3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0 (patch)
tree0c7cf428b569626b1e3502fb2417cbcc70dc3e64 /src
parente9b3fcaa4315a9c0c1d916a23267728d4d9ae550 (diff)
downloadzig-3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0.tar.gz
zig-3f10b3ee1eaca13d8edbdebeae8cd50d40c095c0.zip
Sema: do not allow comptime-only pointer fields in packed structs
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 4fbd80e23c..795f0c43fe 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -20923,7 +20923,7 @@ fn zirReify(
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
- } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) {
+ } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
const msg = msg: {
const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(gpa);
@@ -21290,7 +21290,7 @@ fn reifyStruct(
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
- } else if (layout == .Packed and !(validatePackedType(field_ty, mod))) {
+ } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
const msg = msg: {
const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
errdefer msg.destroy(gpa);
@@ -25663,8 +25663,9 @@ fn explainWhyTypeIsNotExtern(
}
/// Returns true if `ty` is allowed in packed types.
-/// Does *NOT* require `ty` to be resolved in any way.
-fn validatePackedType(ty: Type, mod: *Module) bool {
+/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.
+fn validatePackedType(sema: *Sema, ty: Type) !bool {
+ const mod = sema.mod;
switch (ty.zigTypeTag(mod)) {
.Type,
.ComptimeFloat,
@@ -25689,7 +25690,7 @@ fn validatePackedType(ty: Type, mod: *Module) bool {
.Vector,
.Enum,
=> return true,
- .Pointer => return !ty.isSlice(mod),
+ .Pointer => return !ty.isSlice(mod) and !try sema.typeRequiresComptime(ty),
.Struct, .Union => return ty.containerLayout(mod) == .Packed,
}
}
@@ -25724,7 +25725,12 @@ fn explainWhyTypeIsNotPacked(
.Optional,
.Array,
=> try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
- .Pointer => try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}),
+ .Pointer => if (ty.isSlice(mod)) {
+ try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
+ } else {
+ try mod.errNoteNonLazy(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{});
+ try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
+ },
.Fn => {
try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
@@ -35890,7 +35896,7 @@ fn semaStructFields(
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
},
- .Packed => if (!validatePackedType(field_ty, mod)) {
+ .Packed => if (!try sema.validatePackedType(field_ty)) {
const msg = msg: {
const ty_src = mod.fieldSrcLoc(decl_index, .{
.index = field_i,
@@ -36443,7 +36449,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
break :msg msg;
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
- } else if (layout == .Packed and !validatePackedType(field_ty, mod)) {
+ } else if (layout == .Packed and !try sema.validatePackedType(field_ty)) {
const msg = msg: {
const ty_src = mod.fieldSrcLoc(union_type.decl, .{
.index = field_i,