Sema: allow void
as an extern union field & fix invalid extern unions
This commit is contained in:
parent
d00da05ecb
commit
122c76a167
|
@ -59,12 +59,12 @@ const twords = extern union {
|
|||
s: S,
|
||||
|
||||
const S = if (native_endian == .Little)
|
||||
struct {
|
||||
extern struct {
|
||||
low: u64,
|
||||
high: u64,
|
||||
}
|
||||
else
|
||||
struct {
|
||||
extern struct {
|
||||
high: u64,
|
||||
low: u64,
|
||||
};
|
||||
|
|
|
@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
|
|||
|
||||
all: T,
|
||||
s: if (native_endian == .Little)
|
||||
struct { low: HalfT, high: HalfT }
|
||||
extern struct { low: HalfT, high: HalfT }
|
||||
else
|
||||
struct { high: HalfT, low: HalfT },
|
||||
extern struct { high: HalfT, low: HalfT },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
|
|||
pub const sem_t = extern struct {
|
||||
type: i32,
|
||||
u: extern union {
|
||||
named_sem_id: ?i32,
|
||||
unnamed_sem: ?i32,
|
||||
named_sem_id: i32,
|
||||
unnamed_sem: i32,
|
||||
},
|
||||
padding: [2]i32,
|
||||
};
|
||||
|
|
|
@ -18192,6 +18192,7 @@ fn explainWhyTypeIsComptime(
|
|||
const ExternPosition = enum {
|
||||
ret_ty,
|
||||
param_ty,
|
||||
union_field,
|
||||
other,
|
||||
};
|
||||
|
||||
|
@ -18206,9 +18207,9 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
|
|||
.ErrorUnion,
|
||||
.ErrorSet,
|
||||
.BoundFn,
|
||||
.Void,
|
||||
.Frame,
|
||||
=> return false,
|
||||
.Void => return position == .union_field,
|
||||
.NoReturn => return position == .ret_ty,
|
||||
.Opaque,
|
||||
.Bool,
|
||||
|
@ -24193,13 +24194,13 @@ fn resolveUnionFully(
|
|||
for (union_obj.fields.values()) |field| {
|
||||
try sema.resolveTypeFully(block, src, field.ty);
|
||||
|
||||
if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
|
||||
if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
||||
const src_decl = sema.mod.declPtr(block.src_decl);
|
||||
try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other);
|
||||
try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field);
|
||||
|
||||
try sema.addDeclaredHereNote(msg, field.ty);
|
||||
break :msg msg;
|
||||
|
|
|
@ -84,18 +84,19 @@ test "comptime union field access" {
|
|||
|
||||
const FooExtern = extern union {
|
||||
int: i32,
|
||||
str: struct {
|
||||
slice: []const u8,
|
||||
str: extern struct {
|
||||
slice: [*:0]const u8,
|
||||
},
|
||||
};
|
||||
|
||||
test "basic extern unions" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
var foo = FooExtern{ .int = 1 };
|
||||
try expect(foo.int == 1);
|
||||
foo.str.slice = "Well";
|
||||
try expect(std.mem.eql(u8, foo.str.slice, "Well"));
|
||||
try expect(std.mem.eql(u8, std.mem.sliceTo(foo.str.slice, 0), "Well"));
|
||||
}
|
||||
|
||||
const ExternPtrOrInt = extern union {
|
||||
|
|
Loading…
Reference in New Issue
Block a user