Merge pull request #20593 from jacobly0/more-races

InternPool: fix more races
This commit is contained in:
Andrew Kelley
2024-07-14 17:32:51 -07:00
committed by GitHub
31 changed files with 995 additions and 513 deletions

View File

@@ -2530,13 +2530,13 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
}
if (sema.owner_func_index != .none) {
ip.funcAnalysis(sema.owner_func_index).state = .sema_failure;
ip.funcSetAnalysisState(sema.owner_func_index, .sema_failure);
} else {
sema.owner_decl.analysis = .sema_failure;
}
if (sema.func_index != .none) {
ip.funcAnalysis(sema.func_index).state = .sema_failure;
ip.funcSetAnalysisState(sema.func_index, .sema_failure);
}
return error.AnalysisFail;
@@ -2848,7 +2848,7 @@ fn zirStructDecl(
}
try pt.finalizeAnonDecl(new_decl_index);
try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
}
@@ -3353,7 +3353,7 @@ fn zirUnionDecl(
}
try pt.finalizeAnonDecl(new_decl_index);
try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
}
@@ -6550,14 +6550,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
}
sema.prev_stack_alignment_src = src;
const ip = &mod.intern_pool;
const a = ip.funcAnalysis(sema.func_index);
if (a.stack_alignment != .none) {
a.stack_alignment = @enumFromInt(@max(
@intFromEnum(alignment),
@intFromEnum(a.stack_alignment),
));
}
mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
}
fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
@@ -6570,7 +6563,7 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
.needed_comptime_reason = "operand to @setCold must be comptime-known",
});
if (sema.func_index == .none) return; // does nothing outside a function
ip.funcAnalysis(sema.func_index).is_cold = is_cold;
ip.funcSetCold(sema.func_index, is_cold);
}
fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
@@ -7085,7 +7078,7 @@ fn zirCall(
const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
if (sema.owner_func_index == .none or
!mod.intern_pool.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn)
!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn)
{
// No errorable fn actually called; we have no error return trace
input_is_error = false;
@@ -7793,7 +7786,7 @@ fn analyzeCall(
_ = ics.callee();
if (!inlining.has_comptime_args) {
if (module_fn.analysis(ip).state == .sema_failure)
if (module_fn.analysisUnordered(ip).state == .sema_failure)
return error.AnalysisFail;
var block_it = block;
@@ -7816,7 +7809,7 @@ fn analyzeCall(
try sema.resolveInst(fn_info.ret_ty_ref);
const ret_ty_src: LazySrcLoc = .{ .base_node_inst = module_fn.zir_body_inst, .offset = .{ .node_offset_fn_type_ret_ty = 0 } };
sema.fn_ret_ty = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);
if (module_fn.analysis(ip).inferred_error_set) {
if (module_fn.analysisUnordered(ip).inferred_error_set) {
// Create a fresh inferred error set type for inline/comptime calls.
const ies = try sema.arena.create(InferredErrorSet);
ies.* = .{ .func = .none };
@@ -7942,7 +7935,7 @@ fn analyzeCall(
if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;
ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
}
if (try sema.resolveValue(func)) |func_val| {
@@ -8386,7 +8379,7 @@ fn instantiateGenericCall(
const callee_index = (child_sema.resolveConstDefinedValue(&child_block, LazySrcLoc.unneeded, new_func_inst, undefined) catch unreachable).toIntern();
const callee = zcu.funcInfo(callee_index);
callee.branchQuota(ip).* = @max(callee.branchQuota(ip).*, sema.branch_quota);
callee.maxBranchQuota(ip, sema.branch_quota);
// Make a runtime call to the new function, making sure to omit the comptime args.
const func_ty = Type.fromInterned(callee.ty);
@@ -8408,7 +8401,7 @@ fn instantiateGenericCall(
if (sema.owner_func_index != .none and
Type.fromInterned(func_ty_info.return_type).isError(zcu))
{
ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;
ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
}
try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
@@ -8769,9 +8762,9 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
if (int > len: {
const mutate = &ip.global_error_set.mutate;
mutate.mutex.lock();
defer mutate.mutex.unlock();
break :len mutate.list.len;
mutate.map.mutex.lock();
defer mutate.map.mutex.unlock();
break :len mutate.names.len;
} or int == 0)
return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
return Air.internedToRef((try pt.intern(.{ .err = .{
@@ -18395,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
try ty.resolveLayout(pt); // Getting alignment requires type layout
const union_obj = mod.typeToUnion(ty).?;
const tag_type = union_obj.loadTagType(ip);
const layout = union_obj.getLayout(ip);
const layout = union_obj.flagsUnordered(ip).layout;
const union_field_vals = try gpa.alloc(InternPool.Index, tag_type.names.len);
defer gpa.free(union_field_vals);
@@ -18713,8 +18706,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const backing_integer_val = try pt.intern(.{ .opt = .{
.ty = (try pt.optionalType(.type_type)).toIntern(),
.val = if (mod.typeToPackedStruct(ty)) |packed_struct| val: {
assert(Type.fromInterned(packed_struct.backingIntType(ip).*).isInt(mod));
break :val packed_struct.backingIntType(ip).*;
assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(mod));
break :val packed_struct.backingIntTypeUnordered(ip);
} else .none,
} });
@@ -19795,7 +19788,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
return;
}
if (!mod.intern_pool.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
if (!start_block.ownerModule().error_tracing) return;
assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
@@ -21053,7 +21046,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
if (sema.owner_func_index != .none and
ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and
ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and
block.ownerModule().error_tracing)
{
return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
@@ -22201,11 +22194,11 @@ fn reifyUnion(
if (any_aligns) {
loaded_union.setFieldAligns(ip, field_aligns);
}
loaded_union.tagTypePtr(ip).* = enum_tag_ty;
loaded_union.flagsPtr(ip).status = .have_field_types;
loaded_union.setTagType(ip, enum_tag_ty);
loaded_union.setStatus(ip, .have_field_types);
try pt.finalizeAnonDecl(new_decl_index);
try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
}
@@ -22464,15 +22457,15 @@ fn reifyStruct(
if (opt_backing_int_val.optionalValue(mod)) |backing_int_val| {
const backing_int_ty = backing_int_val.toType();
try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
} else {
const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
}
}
try pt.finalizeAnonDecl(new_decl_index);
try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
}
@@ -28347,7 +28340,7 @@ fn unionFieldPtr(
.is_const = union_ptr_info.flags.is_const,
.is_volatile = union_ptr_info.flags.is_volatile,
.address_space = union_ptr_info.flags.address_space,
.alignment = if (union_obj.getLayout(ip) == .auto) blk: {
.alignment = if (union_obj.flagsUnordered(ip).layout == .auto) blk: {
const union_align = if (union_ptr_info.flags.alignment != .none)
union_ptr_info.flags.alignment
else
@@ -28375,7 +28368,7 @@ fn unionFieldPtr(
}
if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
switch (union_obj.getLayout(ip)) {
switch (union_obj.flagsUnordered(ip).layout) {
.auto => if (initializing) {
// Store to the union to initialize the tag.
const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
@@ -28413,7 +28406,7 @@ fn unionFieldPtr(
}
try sema.requireRuntimeBlock(block, src, null);
if (!initializing and union_obj.getLayout(ip) == .auto and block.wantSafety() and
if (!initializing and union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
union_ty.unionTagTypeSafety(mod) != null and union_obj.field_types.len > 1)
{
const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
@@ -28456,7 +28449,7 @@ fn unionFieldVal(
const un = ip.indexToKey(union_val.toIntern()).un;
const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
const tag_matches = un.tag == field_tag.toIntern();
switch (union_obj.getLayout(ip)) {
switch (union_obj.flagsUnordered(ip).layout) {
.auto => {
if (tag_matches) {
return Air.internedToRef(un.val);
@@ -28490,7 +28483,7 @@ fn unionFieldVal(
}
try sema.requireRuntimeBlock(block, src, null);
if (union_obj.getLayout(ip) == .auto and block.wantSafety() and
if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
{
const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
@@ -32037,7 +32030,7 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
pt.ensureDeclAnalyzed(decl_index) catch |err| {
if (sema.owner_func_index != .none) {
ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
} else {
sema.owner_decl.analysis = .dependency_failure;
}
@@ -32051,7 +32044,7 @@ fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void
const ip = &mod.intern_pool;
pt.ensureFuncBodyAnalyzed(func) catch |err| {
if (sema.owner_func_index != .none) {
ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
} else {
sema.owner_decl.analysis = .dependency_failure;
}
@@ -32397,7 +32390,7 @@ fn analyzeIsNonErrComptimeOnly(
// If the error set is empty, we must return a comptime true or false.
// However we want to avoid unnecessarily resolving an inferred error set
// in case it is already non-empty.
switch (ip.funcIesResolved(func_index).*) {
switch (ip.funcIesResolvedUnordered(func_index)) {
.anyerror_type => break :blk,
.none => {},
else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
@@ -33466,7 +33459,7 @@ fn wrapErrorUnionSet(
.inferred_error_set_type => |func_index| ok: {
// We carefully do this in an order that avoids unnecessarily
// resolving the destination error set type.
switch (ip.funcIesResolved(func_index).*) {
switch (ip.funcIesResolvedUnordered(func_index)) {
.anyerror_type => break :ok,
.none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
break :ok;
@@ -35071,33 +35064,25 @@ pub fn resolveStructAlignment(
assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
assert(struct_type.flagsPtr(ip).alignment == .none);
assert(struct_type.layout != .@"packed");
assert(struct_type.flagsUnordered(ip).alignment == .none);
if (struct_type.flagsPtr(ip).field_types_wip) {
// We'll guess "pointer-aligned", if the struct has an
// underaligned pointer field then some allocations
// might require explicit alignment.
struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
struct_type.flagsPtr(ip).alignment = result;
return;
}
const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
// We'll guess "pointer-aligned", if the struct has an
// underaligned pointer field then some allocations
// might require explicit alignment.
if (struct_type.assumePointerAlignedIfFieldTypesWip(ip, ptr_align)) return;
try sema.resolveTypeFieldsStruct(ty, struct_type);
if (struct_type.setAlignmentWip(ip)) {
// We'll guess "pointer-aligned", if the struct has an
// underaligned pointer field then some allocations
// might require explicit alignment.
struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
struct_type.flagsPtr(ip).alignment = result;
return;
}
// We'll guess "pointer-aligned", if the struct has an
// underaligned pointer field then some allocations
// might require explicit alignment.
if (struct_type.assumePointerAlignedIfWip(ip, ptr_align)) return;
defer struct_type.clearAlignmentWip(ip);
var result: Alignment = .@"1";
var alignment: Alignment = .@"1";
for (0..struct_type.field_types.len) |i| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
@@ -35109,10 +35094,10 @@ pub fn resolveStructAlignment(
struct_type.layout,
.sema,
);
result = result.maxStrict(field_align);
alignment = alignment.maxStrict(field_align);
}
struct_type.flagsPtr(ip).alignment = result;
struct_type.setAlignment(ip, alignment);
}
pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
@@ -35177,7 +35162,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
big_align = big_align.maxStrict(field_align.*);
}
if (struct_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
if (struct_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
const msg = try sema.errMsg(
ty.srcLoc(zcu),
"struct layout depends on it having runtime bits",
@@ -35186,7 +35171,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
return sema.failWithOwnedErrorMsg(null, msg);
}
if (struct_type.flagsPtr(ip).assumed_pointer_aligned and
if (struct_type.flagsUnordered(ip).assumed_pointer_aligned and
big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))
{
const msg = try sema.errMsg(
@@ -35254,10 +35239,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
offsets[i] = @intCast(aligns[i].forward(offset));
offset = offsets[i] + sizes[i];
}
struct_type.size(ip).* = @intCast(big_align.forward(offset));
const flags = struct_type.flagsPtr(ip);
flags.alignment = big_align;
flags.layout_resolved = true;
struct_type.setLayoutResolved(ip, @intCast(big_align.forward(offset)), big_align);
_ = try sema.typeRequiresComptime(ty);
}
@@ -35350,13 +35332,13 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
};
try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
} else {
if (fields_bit_sum > std.math.maxInt(u16)) {
return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
}
const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
}
try sema.flushExports();
@@ -35430,15 +35412,12 @@ pub fn resolveUnionAlignment(
assert(!union_type.haveLayout(ip));
if (union_type.flagsPtr(ip).status == .field_types_wip) {
// We'll guess "pointer-aligned", if the union has an
// underaligned pointer field then some allocations
// might require explicit alignment.
union_type.flagsPtr(ip).assumed_pointer_aligned = true;
const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
union_type.flagsPtr(ip).alignment = result;
return;
}
const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
// We'll guess "pointer-aligned", if the union has an
// underaligned pointer field then some allocations
// might require explicit alignment.
if (union_type.assumePointerAlignedIfFieldTypesWip(ip, ptr_align)) return;
try sema.resolveTypeFieldsUnion(ty, union_type);
@@ -35456,7 +35435,7 @@ pub fn resolveUnionAlignment(
max_align = max_align.max(field_align);
}
union_type.flagsPtr(ip).alignment = max_align;
union_type.setAlignment(ip, max_align);
}
/// This logic must be kept in sync with `Module.getUnionLayout`.
@@ -35471,7 +35450,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
assert(sema.ownerUnit().unwrap().decl == union_type.decl);
switch (union_type.flagsPtr(ip).status) {
const old_flags = union_type.flagsUnordered(ip);
switch (old_flags.status) {
.none, .have_field_types => {},
.field_types_wip, .layout_wip => {
const msg = try sema.errMsg(
@@ -35484,12 +35464,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
.have_layout, .fully_resolved_wip, .fully_resolved => return,
}
const prev_status = union_type.flagsPtr(ip).status;
errdefer if (union_type.flagsPtr(ip).status == .layout_wip) {
union_type.flagsPtr(ip).status = prev_status;
};
errdefer union_type.setStatusIfLayoutWip(ip, old_flags.status);
union_type.flagsPtr(ip).status = .layout_wip;
union_type.setStatus(ip, .layout_wip);
var max_size: u64 = 0;
var max_align: Alignment = .@"1";
@@ -35516,8 +35493,8 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
max_align = max_align.max(field_align);
}
const flags = union_type.flagsPtr(ip);
const has_runtime_tag = flags.runtime_tag.hasTag() and try sema.typeHasRuntimeBits(Type.fromInterned(union_type.enum_tag_ty));
const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and
try sema.typeHasRuntimeBits(Type.fromInterned(union_type.enum_tag_ty));
const size, const alignment, const padding = if (has_runtime_tag) layout: {
const enum_tag_type = Type.fromInterned(union_type.enum_tag_ty);
const tag_align = try sema.typeAbiAlignment(enum_tag_type);
@@ -35551,12 +35528,9 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
break :layout .{ size, max_align.max(tag_align), padding };
} else .{ max_align.forward(max_size), max_align, 0 };
union_type.size(ip).* = @intCast(size);
union_type.padding(ip).* = padding;
flags.alignment = alignment;
flags.status = .have_layout;
union_type.setHaveLayout(ip, @intCast(size), padding, alignment);
if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
const msg = try sema.errMsg(
ty.srcLoc(pt.zcu),
"union layout depends on it having runtime bits",
@@ -35565,7 +35539,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
return sema.failWithOwnedErrorMsg(null, msg);
}
if (union_type.flagsPtr(ip).assumed_pointer_aligned and
if (union_type.flagsUnordered(ip).assumed_pointer_aligned and
alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))
{
const msg = try sema.errMsg(
@@ -35612,7 +35586,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
switch (union_obj.flagsPtr(ip).status) {
switch (union_obj.flagsUnordered(ip).status) {
.none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
.fully_resolved_wip, .fully_resolved => return,
}
@@ -35621,15 +35595,15 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
// After we have resolve union layout we have to go over the fields again to
// make sure pointer fields get their child types resolved as well.
// See also similar code for structs.
const prev_status = union_obj.flagsPtr(ip).status;
errdefer union_obj.flagsPtr(ip).status = prev_status;
const prev_status = union_obj.flagsUnordered(ip).status;
errdefer union_obj.setStatus(ip, prev_status);
union_obj.flagsPtr(ip).status = .fully_resolved_wip;
union_obj.setStatus(ip, .fully_resolved_wip);
for (0..union_obj.field_types.len) |field_index| {
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
try field_ty.resolveFully(pt);
}
union_obj.flagsPtr(ip).status = .fully_resolved;
union_obj.setStatus(ip, .fully_resolved);
}
// And let's not forget comptime-only status.
@@ -35662,7 +35636,7 @@ pub fn resolveTypeFieldsStruct(
if (struct_type.haveFieldTypes(ip)) return;
if (struct_type.setTypesWip(ip)) {
if (struct_type.setFieldTypesWip(ip)) {
const msg = try sema.errMsg(
Type.fromInterned(ty).srcLoc(zcu),
"struct '{}' depends on itself",
@@ -35670,7 +35644,7 @@ pub fn resolveTypeFieldsStruct(
);
return sema.failWithOwnedErrorMsg(null, msg);
}
defer struct_type.clearTypesWip(ip);
defer struct_type.clearFieldTypesWip(ip);
semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
error.AnalysisFail => {
@@ -35739,7 +35713,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
},
else => {},
}
switch (union_type.flagsPtr(ip).status) {
switch (union_type.flagsUnordered(ip).status) {
.none => {},
.field_types_wip => {
const msg = try sema.errMsg(
@@ -35757,8 +35731,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
=> return,
}
union_type.flagsPtr(ip).status = .field_types_wip;
errdefer union_type.flagsPtr(ip).status = .none;
union_type.setStatus(ip, .field_types_wip);
errdefer union_type.setStatus(ip, .none);
semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {
error.AnalysisFail => {
if (owner_decl.analysis == .complete) {
@@ -35769,7 +35743,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
error.OutOfMemory => return error.OutOfMemory,
error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
};
union_type.flagsPtr(ip).status = .have_field_types;
union_type.setStatus(ip, .have_field_types);
}
/// Returns a normal error set corresponding to the fully populated inferred
@@ -35790,10 +35764,10 @@ fn resolveInferredErrorSet(
// TODO: during an incremental update this might not be `.none`, but the
// function might be out-of-date!
const resolved_ty = func.resolvedErrorSet(ip).*;
const resolved_ty = func.resolvedErrorSetUnordered(ip);
if (resolved_ty != .none) return resolved_ty;
if (func.analysis(ip).state == .in_progress)
if (func.analysisUnordered(ip).state == .in_progress)
return sema.fail(block, src, "unable to resolve inferred error set", .{});
// In order to ensure that all dependencies are properly added to the set,
@@ -35830,7 +35804,7 @@ fn resolveInferredErrorSet(
// This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
// which calls `resolveInferredErrorSetPtr`.
const final_resolved_ty = func.resolvedErrorSet(ip).*;
const final_resolved_ty = func.resolvedErrorSetUnordered(ip);
assert(final_resolved_ty != .none);
return final_resolved_ty;
}
@@ -35996,8 +35970,7 @@ fn semaStructFields(
return;
},
.auto, .@"extern" => {
struct_type.size(ip).* = 0;
struct_type.flagsPtr(ip).layout_resolved = true;
struct_type.setLayoutResolved(ip, 0, .none);
return;
},
};
@@ -36191,7 +36164,7 @@ fn semaStructFields(
extra_index += zir_field.init_body_len;
}
struct_type.clearTypesWip(ip);
struct_type.clearFieldTypesWip(ip);
if (!any_inits) struct_type.setHaveFieldInits(ip);
try sema.flushExports();
@@ -36467,7 +36440,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
}
} else {
// The provided type is the enum tag type.
union_type.tagTypePtr(ip).* = provided_ty.toIntern();
union_type.setTagType(ip, provided_ty.toIntern());
const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
.enum_type => ip.loadEnumType(provided_ty.toIntern()),
else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),
@@ -36605,10 +36578,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
}
if (explicit_tags_seen.len > 0) {
const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
const tag_ty = union_type.tagTypeUnordered(ip);
const tag_info = ip.loadEnumType(tag_ty);
const enum_index = tag_info.nameIndex(ip, field_name) orelse {
return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{
field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(pt),
field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt),
});
};
@@ -36645,7 +36619,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
}
const layout = union_type.getLayout(ip);
const layout = union_type.flagsUnordered(ip).layout;
if (layout == .@"extern" and
!try sema.validateExternType(field_ty, .union_field))
{
@@ -36688,7 +36662,8 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
union_type.setFieldAligns(ip, field_aligns.items);
if (explicit_tags_seen.len > 0) {
const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
const tag_ty = union_type.tagTypeUnordered(ip);
const tag_info = ip.loadEnumType(tag_ty);
if (tag_info.names.len > fields_len) {
const msg = msg: {
const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});
@@ -36696,21 +36671,21 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
for (tag_info.names.get(ip), 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(Type.fromInterned(union_type.tagTypePtr(ip).*), field_index, msg, "field '{}' missing, declared here", .{
try sema.addFieldErrNote(Type.fromInterned(tag_ty), field_index, msg, "field '{}' missing, declared here", .{
field_name.fmt(ip),
});
}
try sema.addDeclaredHereNote(msg, Type.fromInterned(union_type.tagTypePtr(ip).*));
try sema.addDeclaredHereNote(msg, Type.fromInterned(tag_ty));
break :msg msg;
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
}
} else if (enum_field_vals.count() > 0) {
const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl));
union_type.tagTypePtr(ip).* = enum_ty;
union_type.setTagType(ip, enum_ty);
} else {
const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));
union_type.tagTypePtr(ip).* = enum_ty;
union_type.setTagType(ip, enum_ty);
}
try sema.flushExports();
@@ -37086,7 +37061,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
try ty.resolveLayout(pt);
const union_obj = ip.loadUnionType(ty.toIntern());
const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse
return null;
if (union_obj.field_types.len == 0) {
const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });