| ... | ... | @@ -3190,6 +3190,15 @@ fn zirEnumDecl( |
| 3190 | 3190 | |
| 3191 | 3191 | try sema.declareDependency(.{ .interned = new_ty }); |
| 3192 | 3192 | 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 | |
| 3193 | 3202 | return Air.internedToRef(new_ty); |
| 3194 | 3203 | }, |
| 3195 | 3204 | .wip => |wip| wip, |
| ... | ... | @@ -17801,12 +17810,23 @@ fn zirThis( |
| 17801 | 17810 | ) CompileError!Air.Inst.Ref { |
| 17802 | 17811 | _ = extended; |
| 17803 | 17812 | const pt = sema.pt; |
| 17813 | const zcu = pt.zcu; |
| 17804 | 17814 | const namespace = pt.zcu.namespacePtr(block.namespace); |
| 17805 | 17815 | |
| 17806 | 17816 | const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type); |
| 17807 | 17817 | |
| 17808 | 17818 | 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 | }, |
| 17810 | 17830 | .opaque_type => {}, |
| 17811 | 17831 | else => unreachable, |
| 17812 | 17832 | } |
| ... | ... | @@ -38330,22 +38350,16 @@ pub fn resolveDeclaredEnum( |
| 38330 | 38350 | fields_len: u32, |
| 38331 | 38351 | zir: Zir, |
| 38332 | 38352 | body_end: usize, |
| 38333 | | ) Zcu.CompileError!void { |
| 38353 | ) Zcu.SemaError!void { |
| 38334 | 38354 | const zcu = pt.zcu; |
| 38335 | 38355 | 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; |
| 38339 | 38356 | |
| 38340 | 38357 | 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 } }; |
| 38342 | 38358 | |
| 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); |
| 38346 | 38360 | defer arena.deinit(); |
| 38347 | 38361 | |
| 38348 | | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); |
| 38362 | var comptime_err_ret_trace: std.ArrayList(Zcu.LazySrcLoc) = .init(gpa); |
| 38349 | 38363 | defer comptime_err_ret_trace.deinit(); |
| 38350 | 38364 | |
| 38351 | 38365 | var sema: Sema = .{ |
| ... | ... | @@ -38353,7 +38367,7 @@ pub fn resolveDeclaredEnum( |
| 38353 | 38367 | .gpa = gpa, |
| 38354 | 38368 | .arena = arena.allocator(), |
| 38355 | 38369 | .code = zir, |
| 38356 | | .owner = anal_unit, |
| 38370 | .owner = .wrap(.{ .type = wip_ty.index }), |
| 38357 | 38371 | .func_index = .none, |
| 38358 | 38372 | .func_is_naked = false, |
| 38359 | 38373 | .fn_ret_ty = Type.void, |
| ... | ... | @@ -38379,15 +38393,66 @@ pub fn resolveDeclaredEnum( |
| 38379 | 38393 | }; |
| 38380 | 38394 | defer block.instructions.deinit(gpa); |
| 38381 | 38395 | |
| 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 | |
| 38382 | 38447 | const int_tag_ty = ty: { |
| 38383 | 38448 | if (body.len != 0) { |
| 38384 | | _ = try sema.analyzeInlineBody(&block, body, inst); |
| 38449 | _ = try sema.analyzeInlineBody(block, body, inst); |
| 38385 | 38450 | } |
| 38386 | 38451 | |
| 38387 | 38452 | 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); |
| 38389 | 38454 | 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)}); |
| 38391 | 38456 | } |
| 38392 | 38457 | break :ty ty; |
| 38393 | 38458 | } else if (fields_len == 0) { |
| ... | ... | @@ -38402,7 +38467,7 @@ pub fn resolveDeclaredEnum( |
| 38402 | 38467 | |
| 38403 | 38468 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { |
| 38404 | 38469 | 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", .{}); |
| 38406 | 38471 | } |
| 38407 | 38472 | } |
| 38408 | 38473 | |
| ... | ... | @@ -38434,7 +38499,7 @@ pub fn resolveDeclaredEnum( |
| 38434 | 38499 | const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]); |
| 38435 | 38500 | extra_index += 1; |
| 38436 | 38501 | 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, .{ |
| 38438 | 38503 | .base_node_inst = tracked_inst, |
| 38439 | 38504 | .offset = .{ .container_field_name = field_i }, |
| 38440 | 38505 | }, tag_inst, .{ .simple = .enum_field_tag_value }); |
| ... | ... | @@ -38447,12 +38512,12 @@ pub fn resolveDeclaredEnum( |
| 38447 | 38512 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38448 | 38513 | }; |
| 38449 | 38514 | 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)}); |
| 38451 | 38516 | errdefer msg.destroy(gpa); |
| 38452 | 38517 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38453 | 38518 | break :msg msg; |
| 38454 | 38519 | }; |
| 38455 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38520 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38456 | 38521 | } |
| 38457 | 38522 | break :overflow false; |
| 38458 | 38523 | } else if (any_values) overflow: { |
| ... | ... | @@ -38469,12 +38534,12 @@ pub fn resolveDeclaredEnum( |
| 38469 | 38534 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38470 | 38535 | }; |
| 38471 | 38536 | 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)}); |
| 38473 | 38538 | errdefer msg.destroy(gpa); |
| 38474 | 38539 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38475 | 38540 | break :msg msg; |
| 38476 | 38541 | }; |
| 38477 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38542 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38478 | 38543 | } |
| 38479 | 38544 | break :overflow false; |
| 38480 | 38545 | } else overflow: { |
| ... | ... | @@ -38487,9 +38552,9 @@ pub fn resolveDeclaredEnum( |
| 38487 | 38552 | |
| 38488 | 38553 | if (tag_overflow) { |
| 38489 | 38554 | 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), |
| 38491 | 38556 | }); |
| 38492 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38557 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38493 | 38558 | } |
| 38494 | 38559 | } |
| 38495 | 38560 | } |