| ... | ... | @@ -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 | } |
| ... | ... | @@ -28478,6 +28498,10 @@ fn unionFieldPtr( |
| 28478 | 28498 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: { |
| 28479 | 28499 | switch (union_obj.flagsUnordered(ip).layout) { |
| 28480 | 28500 | .auto => if (initializing) { |
| 28501 | if (!sema.isComptimeMutablePtr(union_ptr_val)) { |
| 28502 | // The initialization is a runtime operation. |
| 28503 | break :ct; |
| 28504 | } |
| 28481 | 28505 | // Store to the union to initialize the tag. |
| 28482 | 28506 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28483 | 28507 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| ... | ... | @@ -38330,22 +38354,16 @@ pub fn resolveDeclaredEnum( |
| 38330 | 38354 | fields_len: u32, |
| 38331 | 38355 | zir: Zir, |
| 38332 | 38356 | body_end: usize, |
| 38333 | | ) Zcu.CompileError!void { |
| 38357 | ) Zcu.SemaError!void { |
| 38334 | 38358 | const zcu = pt.zcu; |
| 38335 | 38359 | 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 | 38360 | |
| 38340 | 38361 | 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 | 38362 | |
| 38343 | | const anal_unit = AnalUnit.wrap(.{ .type = wip_ty.index }); |
| 38344 | | |
| 38345 | | var arena = std.heap.ArenaAllocator.init(gpa); |
| 38363 | var arena: std.heap.ArenaAllocator = .init(gpa); |
| 38346 | 38364 | defer arena.deinit(); |
| 38347 | 38365 | |
| 38348 | | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); |
| 38366 | var comptime_err_ret_trace: std.ArrayList(Zcu.LazySrcLoc) = .init(gpa); |
| 38349 | 38367 | defer comptime_err_ret_trace.deinit(); |
| 38350 | 38368 | |
| 38351 | 38369 | var sema: Sema = .{ |
| ... | ... | @@ -38353,7 +38371,7 @@ pub fn resolveDeclaredEnum( |
| 38353 | 38371 | .gpa = gpa, |
| 38354 | 38372 | .arena = arena.allocator(), |
| 38355 | 38373 | .code = zir, |
| 38356 | | .owner = anal_unit, |
| 38374 | .owner = .wrap(.{ .type = wip_ty.index }), |
| 38357 | 38375 | .func_index = .none, |
| 38358 | 38376 | .func_is_naked = false, |
| 38359 | 38377 | .fn_ret_ty = Type.void, |
| ... | ... | @@ -38379,15 +38397,66 @@ pub fn resolveDeclaredEnum( |
| 38379 | 38397 | }; |
| 38380 | 38398 | defer block.instructions.deinit(gpa); |
| 38381 | 38399 | |
| 38400 | sema.resolveDeclaredEnumInner( |
| 38401 | &block, |
| 38402 | wip_ty, |
| 38403 | inst, |
| 38404 | tracked_inst, |
| 38405 | src, |
| 38406 | small, |
| 38407 | body, |
| 38408 | tag_type_ref, |
| 38409 | any_values, |
| 38410 | fields_len, |
| 38411 | zir, |
| 38412 | body_end, |
| 38413 | ) catch |err| switch (err) { |
| 38414 | error.GenericPoison => unreachable, |
| 38415 | error.ComptimeBreak => unreachable, |
| 38416 | error.ComptimeReturn => unreachable, |
| 38417 | error.OutOfMemory => |e| return e, |
| 38418 | error.AnalysisFail => { |
| 38419 | if (!zcu.failed_analysis.contains(sema.owner)) { |
| 38420 | try zcu.transitive_failed_analysis.put(gpa, sema.owner, {}); |
| 38421 | } |
| 38422 | return error.AnalysisFail; |
| 38423 | }, |
| 38424 | }; |
| 38425 | } |
| 38426 | |
| 38427 | fn resolveDeclaredEnumInner( |
| 38428 | sema: *Sema, |
| 38429 | block: *Block, |
| 38430 | wip_ty: InternPool.WipEnumType, |
| 38431 | inst: Zir.Inst.Index, |
| 38432 | tracked_inst: InternPool.TrackedInst.Index, |
| 38433 | src: LazySrcLoc, |
| 38434 | small: Zir.Inst.EnumDecl.Small, |
| 38435 | body: []const Zir.Inst.Index, |
| 38436 | tag_type_ref: Zir.Inst.Ref, |
| 38437 | any_values: bool, |
| 38438 | fields_len: u32, |
| 38439 | zir: Zir, |
| 38440 | body_end: usize, |
| 38441 | ) Zcu.CompileError!void { |
| 38442 | const pt = sema.pt; |
| 38443 | const zcu = pt.zcu; |
| 38444 | const gpa = zcu.gpa; |
| 38445 | const ip = &zcu.intern_pool; |
| 38446 | |
| 38447 | const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; |
| 38448 | |
| 38449 | const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } }; |
| 38450 | |
| 38382 | 38451 | const int_tag_ty = ty: { |
| 38383 | 38452 | if (body.len != 0) { |
| 38384 | | _ = try sema.analyzeInlineBody(&block, body, inst); |
| 38453 | _ = try sema.analyzeInlineBody(block, body, inst); |
| 38385 | 38454 | } |
| 38386 | 38455 | |
| 38387 | 38456 | if (tag_type_ref != .none) { |
| 38388 | | const ty = try sema.resolveType(&block, tag_ty_src, tag_type_ref); |
| 38457 | const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); |
| 38389 | 38458 | 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)}); |
| 38459 | return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)}); |
| 38391 | 38460 | } |
| 38392 | 38461 | break :ty ty; |
| 38393 | 38462 | } else if (fields_len == 0) { |
| ... | ... | @@ -38402,7 +38471,7 @@ pub fn resolveDeclaredEnum( |
| 38402 | 38471 | |
| 38403 | 38472 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { |
| 38404 | 38473 | 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", .{}); |
| 38474 | return sema.fail(block, src, "non-exhaustive enum specifies every value", .{}); |
| 38406 | 38475 | } |
| 38407 | 38476 | } |
| 38408 | 38477 | |
| ... | ... | @@ -38434,7 +38503,7 @@ pub fn resolveDeclaredEnum( |
| 38434 | 38503 | const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]); |
| 38435 | 38504 | extra_index += 1; |
| 38436 | 38505 | const tag_inst = try sema.resolveInst(tag_val_ref); |
| 38437 | | last_tag_val = try sema.resolveConstDefinedValue(&block, .{ |
| 38506 | last_tag_val = try sema.resolveConstDefinedValue(block, .{ |
| 38438 | 38507 | .base_node_inst = tracked_inst, |
| 38439 | 38508 | .offset = .{ .container_field_name = field_i }, |
| 38440 | 38509 | }, tag_inst, .{ .simple = .enum_field_tag_value }); |
| ... | ... | @@ -38447,12 +38516,12 @@ pub fn resolveDeclaredEnum( |
| 38447 | 38516 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38448 | 38517 | }; |
| 38449 | 38518 | const msg = msg: { |
| 38450 | | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, &sema)}); |
| 38519 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)}); |
| 38451 | 38520 | errdefer msg.destroy(gpa); |
| 38452 | 38521 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38453 | 38522 | break :msg msg; |
| 38454 | 38523 | }; |
| 38455 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38524 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38456 | 38525 | } |
| 38457 | 38526 | break :overflow false; |
| 38458 | 38527 | } else if (any_values) overflow: { |
| ... | ... | @@ -38469,12 +38538,12 @@ pub fn resolveDeclaredEnum( |
| 38469 | 38538 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38470 | 38539 | }; |
| 38471 | 38540 | const msg = msg: { |
| 38472 | | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, &sema)}); |
| 38541 | const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)}); |
| 38473 | 38542 | errdefer msg.destroy(gpa); |
| 38474 | 38543 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38475 | 38544 | break :msg msg; |
| 38476 | 38545 | }; |
| 38477 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38546 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38478 | 38547 | } |
| 38479 | 38548 | break :overflow false; |
| 38480 | 38549 | } else overflow: { |
| ... | ... | @@ -38487,9 +38556,9 @@ pub fn resolveDeclaredEnum( |
| 38487 | 38556 | |
| 38488 | 38557 | if (tag_overflow) { |
| 38489 | 38558 | 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), |
| 38559 | last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt), |
| 38491 | 38560 | }); |
| 38492 | | return sema.failWithOwnedErrorMsg(&block, msg); |
| 38561 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38493 | 38562 | } |
| 38494 | 38563 | } |
| 38495 | 38564 | } |