Skip to content

Commit 779bb22

Browse files
committed
Sema: allow void as an extern union field & fix invalid extern unions
1 parent d00da05 commit 779bb22

File tree

5 files changed

+13
-12
lines changed

5 files changed

+13
-12
lines changed

lib/compiler_rt/multi3.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ const twords = extern union {
5959
s: S,
6060

6161
const S = if (native_endian == .Little)
62-
struct {
62+
extern struct {
6363
low: u64,
6464
high: u64,
6565
}
6666
else
67-
struct {
67+
extern struct {
6868
high: u64,
6969
low: u64,
7070
};

lib/compiler_rt/shift.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
3131

3232
all: T,
3333
s: if (native_endian == .Little)
34-
struct { low: HalfT, high: HalfT }
34+
extern struct { low: HalfT, high: HalfT }
3535
else
36-
struct { high: HalfT, low: HalfT },
36+
extern struct { high: HalfT, low: HalfT },
3737
};
3838
}
3939

lib/std/c/haiku.zig

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
3030
pub const sem_t = extern struct {
3131
type: i32,
3232
u: extern union {
33-
named_sem_id: ?i32,
34-
unnamed_sem: ?i32,
33+
named_sem_id: i32,
34+
unnamed_sem: i32,
3535
},
3636
padding: [2]i32,
3737
};

src/Sema.zig

+4-3
Original file line numberDiff line numberDiff line change
@@ -18192,6 +18192,7 @@ fn explainWhyTypeIsComptime(
1819218192
const ExternPosition = enum {
1819318193
ret_ty,
1819418194
param_ty,
18195+
union_field,
1819518196
other,
1819618197
};
1819718198

@@ -18206,9 +18207,9 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr
1820618207
.ErrorUnion,
1820718208
.ErrorSet,
1820818209
.BoundFn,
18209-
.Void,
1821018210
.Frame,
1821118211
=> return false,
18212+
.Void => return position == .union_field,
1821218213
.NoReturn => return position == .ret_ty,
1821318214
.Opaque,
1821418215
.Bool,
@@ -24193,13 +24194,13 @@ fn resolveUnionFully(
2419324194
for (union_obj.fields.values()) |field| {
2419424195
try sema.resolveTypeFully(block, src, field.ty);
2419524196

24196-
if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
24197+
if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) {
2419724198
const msg = msg: {
2419824199
const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
2419924200
errdefer msg.destroy(sema.gpa);
2420024201

2420124202
const src_decl = sema.mod.declPtr(block.src_decl);
24202-
try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other);
24203+
try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field);
2420324204

2420424205
try sema.addDeclaredHereNote(msg, field.ty);
2420524206
break :msg msg;

test/behavior/union.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ test "comptime union field access" {
8484

8585
const FooExtern = extern union {
8686
int: i32,
87-
str: struct {
88-
slice: []const u8,
87+
str: extern struct {
88+
slice: [*:0]const u8,
8989
},
9090
};
9191

@@ -95,7 +95,7 @@ test "basic extern unions" {
9595
var foo = FooExtern{ .int = 1 };
9696
try expect(foo.int == 1);
9797
foo.str.slice = "Well";
98-
try expect(std.mem.eql(u8, foo.str.slice, "Well"));
98+
try expect(std.mem.eql(u8, std.mem.sliceTo(foo.str.slice, 0), "Well"));
9999
}
100100

101101
const ExternPtrOrInt = extern union {

0 commit comments

Comments
 (0)