diff --git a/src/Sema.zig b/src/Sema.zig index 79a97a3e37..38fada09b0 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -23393,8 +23393,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins const field_name_src = block.builtinCallArgSrc(extra.src_node, 0); const field_ptr_src = block.builtinCallArgSrc(extra.src_node, 1); - const parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr"); - try sema.checkPtrType(block, inst_src, parent_ptr_ty, true); + const maybe_opt_parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr"); + try sema.checkPtrType(block, inst_src, maybe_opt_parent_ptr_ty, true); + const parent_ptr_ty = switch (maybe_opt_parent_ptr_ty.zigTypeTag(zcu)) { + .optional => maybe_opt_parent_ptr_ty.optionalChild(zcu), + .pointer => maybe_opt_parent_ptr_ty, + else => unreachable, + }; const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); if (parent_ptr_info.flags.size != .one) { return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)}); @@ -23441,7 +23446,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins ); const unaligned_parent_ptr_ty = try pt.ptrType(info: { - var info = parent_ptr_ty.ptrInfo(zcu); + var info = parent_ptr_info; info.flags.alignment = hypothetical_field_ptr_ty.ptrAlignment(zcu); break :info info; }); @@ -23512,7 +23517,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins // a field pointer of type `*align(1) u16`. switch (hypothetical_field_ptr_ty.ptrAlignment(zcu).order(parent_ptr_ty.ptrAlignment(zcu))) { .gt => unreachable, // getting a field pointer can never increase alignment - .eq => return unaligned_parent_ptr, + .eq => return sema.coerce(block, maybe_opt_parent_ptr_ty, unaligned_parent_ptr, inst_src), .lt => if (flags.align_cast) { // Go through `ptrCastFull` for the safety check. return sema.ptrCastFull( @@ -23521,7 +23526,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins inst_src, unaligned_parent_ptr, inst_src, - parent_ptr_ty, + maybe_opt_parent_ptr_ty, "@fieldParentPtr", ); } else return sema.failWithOwnedErrorMsg(block, msg: { @@ -25184,7 +25189,7 @@ pub fn explainWhyTypeIsNotExtern( } }, .@"union" => { - const union_obj = zcu.intern_pool.loadStructType(ty.toIntern()); + const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern()); switch (union_obj.layout) { .auto => try sema.errNote(src_loc, msg, "union with automatic layout has no guaranteed in-memory representation", .{}), .@"extern" => unreachable, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index ef22213c9a..06377692c9 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -1393,17 +1393,17 @@ pub fn ensureTypeLayoutUpToDate( .@"union" => Sema.type_resolution.resolveUnionLayout(&sema, ty), else => unreachable, }; - const new_success: bool = if (result) s: { - break :s true; + const new_failed: bool = if (result) failed: { + break :failed false; } else |err| switch (err) { - error.AnalysisFail => success: { + error.AnalysisFail => failed: { if (!zcu.failed_analysis.contains(anal_unit)) { // If this unit caused the error, it would have an entry in `failed_analysis`. // Since it does not, this must be a transitive failure. try zcu.transitive_failed_analysis.put(gpa, anal_unit, {}); log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)}); } - break :success false; + break :failed true; }, error.OutOfMemory, error.Canceled, @@ -1422,8 +1422,10 @@ pub fn ensureTypeLayoutUpToDate( comp.link_prog_node.increaseEstimatedTotalItems(1); try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_container_type = .{ .ty = ty.toIntern(), - .success = new_success, + .success = !new_failed, } }); + + if (new_failed) return error.AnalysisFail; } /// Ensures that the resolved value of the given `Nav` is fully up-to-date, performing re-analysis