Commit 3f10b3ee1e
Changed files (2)
src
test
cases
compile_errors
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,
test/cases/compile_errors/packed_struct_with_fields_of_not_allowed_types.zig
@@ -65,6 +65,11 @@ export fn entry12() void {
x: packed struct { a: []u8 },
});
}
+export fn entry13() void {
+ _ = @sizeOf(packed struct {
+ x: *type,
+ });
+}
// error
// backend=llvm
@@ -89,3 +94,6 @@ export fn entry12() void {
// :38:12: note: use '*const ' to make a function pointer type
// :65:31: error: packed structs cannot contain fields of type '[]u8'
// :65:31: note: slices have no guaranteed in-memory representation
+// :70:12: error: packed structs cannot contain fields of type '*type'
+// :70:12: note: comptime-only pointer has no guaranteed in-memory representation
+// :70:12: note: types are not available at runtime