| ... | @@ -3190,6 +3190,15 @@ fn zirEnumDecl( | ... | @@ -3190,6 +3190,15 @@ fn zirEnumDecl( |
| 3190 | | 3190 | |
| 3191 | try sema.declareDependency(.{ .interned = new_ty }); | 3191 | try sema.declareDependency(.{ .interned = new_ty }); |
| 3192 | try sema.addTypeReferenceEntry(src, new_ty); | 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 | return Air.internedToRef(new_ty); | 3202 | return Air.internedToRef(new_ty); |
| 3194 | }, | 3203 | }, |
| 3195 | .wip => |wip| wip, | 3204 | .wip => |wip| wip, |
| ... | @@ -17801,12 +17810,23 @@ fn zirThis( | ... | @@ -17801,12 +17810,23 @@ fn zirThis( |
| 17801 | ) CompileError!Air.Inst.Ref { | 17810 | ) CompileError!Air.Inst.Ref { |
| 17802 | _ = extended; | 17811 | _ = extended; |
| 17803 | const pt = sema.pt; | 17812 | const pt = sema.pt; |
| | 17813 | const zcu = pt.zcu; |
| 17804 | const namespace = pt.zcu.namespacePtr(block.namespace); | 17814 | const namespace = pt.zcu.namespacePtr(block.namespace); |
| 17805 | | 17815 | |
| 17806 | const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type); | 17816 | const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type); |
| 17807 | | 17817 | |
| 17808 | switch (pt.zcu.intern_pool.indexToKey(new_ty)) { | 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 | .opaque_type => {}, | 17830 | .opaque_type => {}, |
| 17811 | else => unreachable, | 17831 | else => unreachable, |
| 17812 | } | 17832 | } |
| ... | @@ -28478,6 +28498,10 @@ fn unionFieldPtr( | ... | @@ -28478,6 +28498,10 @@ fn unionFieldPtr( |
| 28478 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: { | 28498 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: { |
| 28479 | switch (union_obj.flagsUnordered(ip).layout) { | 28499 | switch (union_obj.flagsUnordered(ip).layout) { |
| 28480 | .auto => if (initializing) { | 28500 | .auto => if (initializing) { |
| | 28501 | if (!sema.isComptimeMutablePtr(union_ptr_val)) { |
| | 28502 | // The initialization is a runtime operation. |
| | 28503 | break :ct; |
| | 28504 | } |
| 28481 | // Store to the union to initialize the tag. | 28505 | // Store to the union to initialize the tag. |
| 28482 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); | 28506 | const field_tag = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index); |
| 28483 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 28507 | const payload_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| ... | @@ -38330,22 +38354,16 @@ pub fn resolveDeclaredEnum( | ... | @@ -38330,22 +38354,16 @@ pub fn resolveDeclaredEnum( |
| 38330 | fields_len: u32, | 38354 | fields_len: u32, |
| 38331 | zir: Zir, | 38355 | zir: Zir, |
| 38332 | body_end: usize, | 38356 | body_end: usize, |
| 38333 | ) Zcu.CompileError!void { | 38357 | ) Zcu.SemaError!void { |
| 38334 | const zcu = pt.zcu; | 38358 | const zcu = pt.zcu; |
| 38335 | const gpa = zcu.gpa; | 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 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 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 }); | 38363 | var arena: std.heap.ArenaAllocator = .init(gpa); |
| 38344 | | | |
| 38345 | var arena = std.heap.ArenaAllocator.init(gpa); | | |
| 38346 | defer arena.deinit(); | 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 | defer comptime_err_ret_trace.deinit(); | 38367 | defer comptime_err_ret_trace.deinit(); |
| 38350 | | 38368 | |
| 38351 | var sema: Sema = .{ | 38369 | var sema: Sema = .{ |
| ... | @@ -38353,7 +38371,7 @@ pub fn resolveDeclaredEnum( | ... | @@ -38353,7 +38371,7 @@ pub fn resolveDeclaredEnum( |
| 38353 | .gpa = gpa, | 38371 | .gpa = gpa, |
| 38354 | .arena = arena.allocator(), | 38372 | .arena = arena.allocator(), |
| 38355 | .code = zir, | 38373 | .code = zir, |
| 38356 | .owner = anal_unit, | 38374 | .owner = .wrap(.{ .type = wip_ty.index }), |
| 38357 | .func_index = .none, | 38375 | .func_index = .none, |
| 38358 | .func_is_naked = false, | 38376 | .func_is_naked = false, |
| 38359 | .fn_ret_ty = Type.void, | 38377 | .fn_ret_ty = Type.void, |
| ... | @@ -38379,15 +38397,66 @@ pub fn resolveDeclaredEnum( | ... | @@ -38379,15 +38397,66 @@ pub fn resolveDeclaredEnum( |
| 38379 | }; | 38397 | }; |
| 38380 | defer block.instructions.deinit(gpa); | 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 | const int_tag_ty = ty: { | 38451 | const int_tag_ty = ty: { |
| 38383 | if (body.len != 0) { | 38452 | if (body.len != 0) { |
| 38384 | _ = try sema.analyzeInlineBody(&block, body, inst); | 38453 | _ = try sema.analyzeInlineBody(block, body, inst); |
| 38385 | } | 38454 | } |
| 38386 | | 38455 | |
| 38387 | if (tag_type_ref != .none) { | 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 | if (ty.zigTypeTag(zcu) != .int and ty.zigTypeTag(zcu) != .comptime_int) { | 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 | break :ty ty; | 38461 | break :ty ty; |
| 38393 | } else if (fields_len == 0) { | 38462 | } else if (fields_len == 0) { |
| ... | @@ -38402,7 +38471,7 @@ pub fn resolveDeclaredEnum( | ... | @@ -38402,7 +38471,7 @@ pub fn resolveDeclaredEnum( |
| 38402 | | 38471 | |
| 38403 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { | 38472 | if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) { |
| 38404 | if (fields_len > 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(zcu)) { | 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,7 +38503,7 @@ pub fn resolveDeclaredEnum( |
| 38434 | const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]); | 38503 | const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]); |
| 38435 | extra_index += 1; | 38504 | extra_index += 1; |
| 38436 | const tag_inst = try sema.resolveInst(tag_val_ref); | 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 | .base_node_inst = tracked_inst, | 38507 | .base_node_inst = tracked_inst, |
| 38439 | .offset = .{ .container_field_name = field_i }, | 38508 | .offset = .{ .container_field_name = field_i }, |
| 38440 | }, tag_inst, .{ .simple = .enum_field_tag_value }); | 38509 | }, tag_inst, .{ .simple = .enum_field_tag_value }); |
| ... | @@ -38447,12 +38516,12 @@ pub fn resolveDeclaredEnum( | ... | @@ -38447,12 +38516,12 @@ pub fn resolveDeclaredEnum( |
| 38447 | .offset = .{ .container_field_value = conflict.prev_field_idx }, | 38516 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38448 | }; | 38517 | }; |
| 38449 | const msg = msg: { | 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 | errdefer msg.destroy(gpa); | 38520 | errdefer msg.destroy(gpa); |
| 38452 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); | 38521 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38453 | break :msg msg; | 38522 | break :msg msg; |
| 38454 | }; | 38523 | }; |
| 38455 | return sema.failWithOwnedErrorMsg(&block, msg); | 38524 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38456 | } | 38525 | } |
| 38457 | break :overflow false; | 38526 | break :overflow false; |
| 38458 | } else if (any_values) overflow: { | 38527 | } else if (any_values) overflow: { |
| ... | @@ -38469,12 +38538,12 @@ pub fn resolveDeclaredEnum( | ... | @@ -38469,12 +38538,12 @@ pub fn resolveDeclaredEnum( |
| 38469 | .offset = .{ .container_field_value = conflict.prev_field_idx }, | 38538 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 38470 | }; | 38539 | }; |
| 38471 | const msg = msg: { | 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 | errdefer msg.destroy(gpa); | 38542 | errdefer msg.destroy(gpa); |
| 38474 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); | 38543 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 38475 | break :msg msg; | 38544 | break :msg msg; |
| 38476 | }; | 38545 | }; |
| 38477 | return sema.failWithOwnedErrorMsg(&block, msg); | 38546 | return sema.failWithOwnedErrorMsg(block, msg); |
| 38478 | } | 38547 | } |
| 38479 | break :overflow false; | 38548 | break :overflow false; |
| 38480 | } else overflow: { | 38549 | } else overflow: { |
| ... | @@ -38487,9 +38556,9 @@ pub fn resolveDeclaredEnum( | ... | @@ -38487,9 +38556,9 @@ pub fn resolveDeclaredEnum( |
| 38487 | | 38556 | |
| 38488 | if (tag_overflow) { | 38557 | if (tag_overflow) { |
| 38489 | const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{ | 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 | } |