@@ -3190,6 +3190,15 @@ fn zirEnumDecl(
31903190
31913191 try sema.declareDependency(.{ .interned = new_ty });
31923192 try sema.addTypeReferenceEntry(src, new_ty);
3193+
3194+ // Since this is an enum, it has to be resolved immediately.
3195+ // `ensureTypeUpToDate` has resolved the new type if necessary.
3196+ // We just need to check for resolution failures.
3197+ const ty_unit: AnalUnit = .wrap(.{ .type = new_ty });
3198+ if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
3199+ return error.AnalysisFail;
3200+ }
3201+
31933202 return Air.internedToRef(new_ty);
31943203 },
31953204 .wip => |wip| wip,
@@ -17801,12 +17810,23 @@ fn zirThis(
1780117810) CompileError!Air.Inst.Ref {
1780217811 _ = extended;
1780317812 const pt = sema.pt;
17813+ const zcu = pt.zcu;
1780417814 const namespace = pt.zcu.namespacePtr(block.namespace);
1780517815
1780617816 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
1780717817
1780817818 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {
17809- .struct_type, .union_type, .enum_type => try sema.declareDependency(.{ .interned = new_ty }),
17819+ .struct_type, .union_type => try sema.declareDependency(.{ .interned = new_ty }),
17820+ .enum_type => {
17821+ try sema.declareDependency(.{ .interned = new_ty });
17822+ // Since this is an enum, it has to be resolved immediately.
17823+ // `ensureTypeUpToDate` has resolved the new type if necessary.
17824+ // We just need to check for resolution failures.
17825+ const ty_unit: AnalUnit = .wrap(.{ .type = new_ty });
17826+ if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
17827+ return error.AnalysisFail;
17828+ }
17829+ },
1781017830 .opaque_type => {},
1781117831 else => unreachable,
1781217832 }
@@ -38330,30 +38350,24 @@ pub fn resolveDeclaredEnum(
3833038350 fields_len: u32,
3833138351 zir: Zir,
3833238352 body_end: usize,
38333- ) Zcu.CompileError !void {
38353+ ) Zcu.SemaError !void {
3833438354 const zcu = pt.zcu;
3833538355 const gpa = zcu.gpa;
38336- const ip = &zcu.intern_pool;
38337-
38338- const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
3833938356
3834038357 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) };
38341- const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } };
3834238358
38343- const anal_unit = AnalUnit.wrap(.{ .type = wip_ty.index });
38344-
38345- var arena = std.heap.ArenaAllocator.init(gpa);
38359+ var arena: std.heap.ArenaAllocator = .init(gpa);
3834638360 defer arena.deinit();
3834738361
38348- var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
38362+ var comptime_err_ret_trace: std.ArrayList(Zcu.LazySrcLoc) = .init(gpa);
3834938363 defer comptime_err_ret_trace.deinit();
3835038364
3835138365 var sema: Sema = .{
3835238366 .pt = pt,
3835338367 .gpa = gpa,
3835438368 .arena = arena.allocator(),
3835538369 .code = zir,
38356- .owner = anal_unit ,
38370+ .owner = .wrap(.{ .type = wip_ty.index }) ,
3835738371 .func_index = .none,
3835838372 .func_is_naked = false,
3835938373 .fn_ret_ty = Type.void,
@@ -38379,15 +38393,66 @@ pub fn resolveDeclaredEnum(
3837938393 };
3838038394 defer block.instructions.deinit(gpa);
3838138395
38396+ sema.resolveDeclaredEnumInner(
38397+ &block,
38398+ wip_ty,
38399+ inst,
38400+ tracked_inst,
38401+ src,
38402+ small,
38403+ body,
38404+ tag_type_ref,
38405+ any_values,
38406+ fields_len,
38407+ zir,
38408+ body_end,
38409+ ) catch |err| switch (err) {
38410+ error.GenericPoison => unreachable,
38411+ error.ComptimeBreak => unreachable,
38412+ error.ComptimeReturn => unreachable,
38413+ error.OutOfMemory => |e| return e,
38414+ error.AnalysisFail => {
38415+ if (!zcu.failed_analysis.contains(sema.owner)) {
38416+ try zcu.transitive_failed_analysis.put(gpa, sema.owner, {});
38417+ }
38418+ return error.AnalysisFail;
38419+ },
38420+ };
38421+ }
38422+
38423+ fn resolveDeclaredEnumInner(
38424+ sema: *Sema,
38425+ block: *Block,
38426+ wip_ty: InternPool.WipEnumType,
38427+ inst: Zir.Inst.Index,
38428+ tracked_inst: InternPool.TrackedInst.Index,
38429+ src: LazySrcLoc,
38430+ small: Zir.Inst.EnumDecl.Small,
38431+ body: []const Zir.Inst.Index,
38432+ tag_type_ref: Zir.Inst.Ref,
38433+ any_values: bool,
38434+ fields_len: u32,
38435+ zir: Zir,
38436+ body_end: usize,
38437+ ) Zcu.CompileError!void {
38438+ const pt = sema.pt;
38439+ const zcu = pt.zcu;
38440+ const gpa = zcu.gpa;
38441+ const ip = &zcu.intern_pool;
38442+
38443+ const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
38444+
38445+ const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } };
38446+
3838238447 const int_tag_ty = ty: {
3838338448 if (body.len != 0) {
38384- _ = try sema.analyzeInlineBody(& block, body, inst);
38449+ _ = try sema.analyzeInlineBody(block, body, inst);
3838538450 }
3838638451
3838738452 if (tag_type_ref != .none) {
38388- const ty = try sema.resolveType(& block, tag_ty_src, tag_type_ref);
38453+ const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
3838938454 if (ty.zigTypeTag(zcu) != .int and ty.zigTypeTag(zcu) != .comptime_int) {
38390- return sema.fail(& block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)});
38455+ return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)});
3839138456 }
3839238457 break :ty ty;
3839338458 } else if (fields_len == 0) {
@@ -38402,7 +38467,7 @@ pub fn resolveDeclaredEnum(
3840238467
3840338468 if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) {
3840438469 if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(zcu)) {
38405- return sema.fail(& block, src, "non-exhaustive enum specifies every value", .{});
38470+ return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
3840638471 }
3840738472 }
3840838473
@@ -38434,7 +38499,7 @@ pub fn resolveDeclaredEnum(
3843438499 const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
3843538500 extra_index += 1;
3843638501 const tag_inst = try sema.resolveInst(tag_val_ref);
38437- last_tag_val = try sema.resolveConstDefinedValue(& block, .{
38502+ last_tag_val = try sema.resolveConstDefinedValue(block, .{
3843838503 .base_node_inst = tracked_inst,
3843938504 .offset = .{ .container_field_name = field_i },
3844038505 }, tag_inst, .{ .simple = .enum_field_tag_value });
@@ -38447,12 +38512,12 @@ pub fn resolveDeclaredEnum(
3844738512 .offset = .{ .container_field_value = conflict.prev_field_idx },
3844838513 };
3844938514 const msg = msg: {
38450- const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, & sema)});
38515+ const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
3845138516 errdefer msg.destroy(gpa);
3845238517 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3845338518 break :msg msg;
3845438519 };
38455- return sema.failWithOwnedErrorMsg(& block, msg);
38520+ return sema.failWithOwnedErrorMsg(block, msg);
3845638521 }
3845738522 break :overflow false;
3845838523 } else if (any_values) overflow: {
@@ -38469,12 +38534,12 @@ pub fn resolveDeclaredEnum(
3846938534 .offset = .{ .container_field_value = conflict.prev_field_idx },
3847038535 };
3847138536 const msg = msg: {
38472- const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, & sema)});
38537+ const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
3847338538 errdefer msg.destroy(gpa);
3847438539 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3847538540 break :msg msg;
3847638541 };
38477- return sema.failWithOwnedErrorMsg(& block, msg);
38542+ return sema.failWithOwnedErrorMsg(block, msg);
3847838543 }
3847938544 break :overflow false;
3848038545 } else overflow: {
@@ -38487,9 +38552,9 @@ pub fn resolveDeclaredEnum(
3848738552
3848838553 if (tag_overflow) {
3848938554 const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{
38490- last_tag_val.?.fmtValueSema(pt, & sema), int_tag_ty.fmt(pt),
38555+ last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt),
3849138556 });
38492- return sema.failWithOwnedErrorMsg(& block, msg);
38557+ return sema.failWithOwnedErrorMsg(block, msg);
3849338558 }
3849438559 }
3849538560}
0 commit comments