diff --git a/lib/compiler_rt/multi3.zig b/lib/compiler_rt/multi3.zig index 42994a81b..9502dc567 100644 --- a/lib/compiler_rt/multi3.zig +++ b/lib/compiler_rt/multi3.zig @@ -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, }; diff --git a/lib/compiler_rt/shift.zig b/lib/compiler_rt/shift.zig index ee8b634fb..e38c3973b 100644 --- a/lib/compiler_rt/shift.zig +++ b/lib/compiler_rt/shift.zig @@ -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 }, }; } diff --git a/lib/std/c/haiku.zig b/lib/std/c/haiku.zig index 0d238d833..672f4fa4b 100644 --- a/lib/std/c/haiku.zig +++ b/lib/std/c/haiku.zig @@ -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, }; diff --git a/src/Sema.zig b/src/Sema.zig index 48cab0f04..d66c447e7 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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; diff --git a/test/behavior/union.zig b/test/behavior/union.zig index be01b3a04..caa78be97 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -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 {