authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-25 07:08:48-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
log72e4ea38216aab7e7ed05978d04c5d32de44b5ce
tree9b11f31d39590a767d420dd036682438a6ede634
parent1a4626d2cf8b9985833f97b6fea6ea03011ada4e

InternPool: fix crashes up to in progress comptime mutation


4 files changed, 132 insertions(+), 91 deletions(-)

src/InternPool.zig+29-16
...@@ -730,21 +730,11 @@ pub const Key = union(enum) {...@@ -730,21 +730,11 @@ pub const Key = union(enum) {
730730
731 switch (aggregate.storage) {731 switch (aggregate.storage) {
732 .bytes => unreachable,732 .bytes => unreachable,
733 .elems => |elems| {733 .elems => |elems| for (elems) |elem| std.hash.autoHash(hasher, elem),
734 var buffer: Key.Int.Storage.BigIntSpace = undefined;
735 for (elems) |elem| std.hash.autoHash(
736 hasher,
737 ip.indexToKey(elem).int.storage.toBigInt(&buffer).to(u8) catch
738 unreachable,
739 );
740 },
741 .repeated_elem => |elem| {734 .repeated_elem => |elem| {
742 const len = ip.aggregateTypeLen(aggregate.ty);735 const len = ip.aggregateTypeLen(aggregate.ty);
743 var buffer: Key.Int.Storage.BigIntSpace = undefined;
744 const byte = ip.indexToKey(elem).int.storage.toBigInt(&buffer).to(u8) catch
745 unreachable;
746 var i: u64 = 0;736 var i: u64 = 0;
747 while (i < len) : (i += 1) std.hash.autoHash(hasher, byte);737 while (i < len) : (i += 1) std.hash.autoHash(hasher, elem);
748 },738 },
749 }739 }
750 },740 },
...@@ -2044,6 +2034,10 @@ pub const Alignment = enum(u6) {...@@ -2044,6 +2034,10 @@ pub const Alignment = enum(u6) {
2044 assert(n != 0);2034 assert(n != 0);
2045 return fromByteUnits(n);2035 return fromByteUnits(n);
2046 }2036 }
2037
2038 pub fn min(a: Alignment, b: Alignment) Alignment {
2039 return @intToEnum(Alignment, @min(@enumToInt(a), @enumToInt(b)));
2040 }
2047};2041};
20482042
2049/// Used for non-sentineled arrays that have length fitting in u32, as well as2043/// Used for non-sentineled arrays that have length fitting in u32, as well as
...@@ -3514,16 +3508,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -3514,16 +3508,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
3514 const ty_key = ip.indexToKey(aggregate.ty);3508 const ty_key = ip.indexToKey(aggregate.ty);
3515 const aggregate_len = ip.aggregateTypeLen(aggregate.ty);3509 const aggregate_len = ip.aggregateTypeLen(aggregate.ty);
3516 switch (aggregate.storage) {3510 switch (aggregate.storage) {
3517 .bytes => {3511 .bytes => |bytes| {
3518 assert(ty_key.array_type.child == .u8_type);3512 assert(ty_key.array_type.child == .u8_type);
3513 assert(bytes.len == aggregate_len);
3519 },3514 },
3520 .elems => |elems| {3515 .elems => |elems| {
3521 assert(elems.len == aggregate_len);3516 assert(elems.len == aggregate_len);
3522 for (elems) |elem| assert(elem != .none);
3523 },3517 },
3524 .repeated_elem => |elem| {3518 .repeated_elem => {},
3525 assert(elem != .none);3519 }
3520 switch (ty_key) {
3521 inline .array_type, .vector_type => |seq_type| {
3522 for (aggregate.storage.values()) |elem| {
3523 assert(ip.typeOf(elem) == seq_type.child);
3524 }
3525 },
3526 .struct_type => |struct_type| {
3527 for (
3528 aggregate.storage.values(),
3529 ip.structPtrUnwrapConst(struct_type.index).?.fields.values(),
3530 ) |elem, field| {
3531 assert(ip.typeOf(elem) == field.ty.toIntern());
3532 }
3533 },
3534 .anon_struct_type => |anon_struct_type| {
3535 for (aggregate.storage.values(), anon_struct_type.types) |elem, ty| {
3536 assert(ip.typeOf(elem) == ty);
3537 }
3526 },3538 },
3539 else => unreachable,
3527 }3540 }
35283541
3529 if (aggregate_len == 0) {3542 if (aggregate_len == 0) {
src/Sema.zig+70-70
...@@ -10252,7 +10252,7 @@ fn zirSwitchCapture(...@@ -10252,7 +10252,7 @@ fn zirSwitchCapture(
10252 if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {10252 if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {
10253 return sema.addConstant(10253 return sema.addConstant(
10254 first_field.ty,10254 first_field.ty,
10255 operand_val.castTag(.@"union").?.data.val,10255 mod.intern_pool.indexToKey(operand_val.toIntern()).un.val.toValue(),
10256 );10256 );
10257 }10257 }
10258 try sema.requireRuntimeBlock(block, operand_src, null);10258 try sema.requireRuntimeBlock(block, operand_src, null);
...@@ -19042,10 +19042,10 @@ fn zirReify(...@@ -19042,10 +19042,10 @@ fn zirReify(
19042 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };19042 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
19043 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);19043 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
19044 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");19044 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");
19045 const union_val = val.cast(Value.Payload.Union).?.data;19045 const union_val = mod.intern_pool.indexToKey(val.toIntern()).un;
19046 const target = mod.getTarget();19046 const target = mod.getTarget();
19047 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag, mod).?;19047 if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
19048 if (try union_val.val.anyUndef(mod)) return sema.failWithUseOfUndef(block, src);19048 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;
19049 const ip = &mod.intern_pool;19049 const ip = &mod.intern_pool;
19050 switch (@intToEnum(std.builtin.TypeId, tag_index)) {19050 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
19051 .Type => return Air.Inst.Ref.type_type,19051 .Type => return Air.Inst.Ref.type_type,
...@@ -19059,9 +19059,9 @@ fn zirReify(...@@ -19059,9 +19059,9 @@ fn zirReify(
19059 .AnyFrame => return sema.failWithUseOfAsync(block, src),19059 .AnyFrame => return sema.failWithUseOfAsync(block, src),
19060 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,19060 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
19061 .Int => {19061 .Int => {
19062 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19062 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19063 const signedness_val = try union_val.val.fieldValue(mod, fields.getIndex("signedness").?);19063 const signedness_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("signedness").?);
19064 const bits_val = try union_val.val.fieldValue(mod, fields.getIndex("bits").?);19064 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
1906519065
19066 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);19066 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
19067 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));19067 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
...@@ -19069,9 +19069,9 @@ fn zirReify(...@@ -19069,9 +19069,9 @@ fn zirReify(
19069 return sema.addType(ty);19069 return sema.addType(ty);
19070 },19070 },
19071 .Vector => {19071 .Vector => {
19072 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19072 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19073 const len_val = try union_val.val.fieldValue(mod, fields.getIndex("len").?);19073 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
19074 const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);19074 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
1907519075
19076 const len = @intCast(u32, len_val.toUnsignedInt(mod));19076 const len = @intCast(u32, len_val.toUnsignedInt(mod));
19077 const child_ty = child_val.toType();19077 const child_ty = child_val.toType();
...@@ -19085,8 +19085,8 @@ fn zirReify(...@@ -19085,8 +19085,8 @@ fn zirReify(
19085 return sema.addType(ty);19085 return sema.addType(ty);
19086 },19086 },
19087 .Float => {19087 .Float => {
19088 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19088 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19089 const bits_val = try union_val.val.fieldValue(mod, fields.getIndex("bits").?);19089 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
1909019090
19091 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));19091 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
19092 const ty = switch (bits) {19092 const ty = switch (bits) {
...@@ -19100,15 +19100,15 @@ fn zirReify(...@@ -19100,15 +19100,15 @@ fn zirReify(
19100 return sema.addType(ty);19100 return sema.addType(ty);
19101 },19101 },
19102 .Pointer => {19102 .Pointer => {
19103 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19103 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19104 const size_val = try union_val.val.fieldValue(mod, fields.getIndex("size").?);19104 const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("size").?);
19105 const is_const_val = try union_val.val.fieldValue(mod, fields.getIndex("is_const").?);19105 const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_const").?);
19106 const is_volatile_val = try union_val.val.fieldValue(mod, fields.getIndex("is_volatile").?);19106 const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_volatile").?);
19107 const alignment_val = try union_val.val.fieldValue(mod, fields.getIndex("alignment").?);19107 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
19108 const address_space_val = try union_val.val.fieldValue(mod, fields.getIndex("address_space").?);19108 const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("address_space").?);
19109 const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);19109 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19110 const is_allowzero_val = try union_val.val.fieldValue(mod, fields.getIndex("is_allowzero").?);19110 const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_allowzero").?);
19111 const sentinel_val = try union_val.val.fieldValue(mod, fields.getIndex("sentinel").?);19111 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
1911219112
19113 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19113 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19114 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19114 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
...@@ -19191,10 +19191,10 @@ fn zirReify(...@@ -19191,10 +19191,10 @@ fn zirReify(
19191 return sema.addType(ty);19191 return sema.addType(ty);
19192 },19192 },
19193 .Array => {19193 .Array => {
19194 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19194 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19195 const len_val = try union_val.val.fieldValue(mod, fields.getIndex("len").?);19195 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
19196 const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);19196 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19197 const sentinel_val = try union_val.val.fieldValue(mod, fields.getIndex("sentinel").?);19197 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
1919819198
19199 const len = len_val.toUnsignedInt(mod);19199 const len = len_val.toUnsignedInt(mod);
19200 const child_ty = child_val.toType();19200 const child_ty = child_val.toType();
...@@ -19210,8 +19210,8 @@ fn zirReify(...@@ -19210,8 +19210,8 @@ fn zirReify(
19210 return sema.addType(ty);19210 return sema.addType(ty);
19211 },19211 },
19212 .Optional => {19212 .Optional => {
19213 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19213 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19214 const child_val = try union_val.val.fieldValue(mod, fields.getIndex("child").?);19214 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
1921519215
19216 const child_ty = child_val.toType();19216 const child_ty = child_val.toType();
1921719217
...@@ -19219,9 +19219,9 @@ fn zirReify(...@@ -19219,9 +19219,9 @@ fn zirReify(
19219 return sema.addType(ty);19219 return sema.addType(ty);
19220 },19220 },
19221 .ErrorUnion => {19221 .ErrorUnion => {
19222 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19222 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19223 const error_set_val = try union_val.val.fieldValue(mod, fields.getIndex("error_set").?);19223 const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("error_set").?);
19224 const payload_val = try union_val.val.fieldValue(mod, fields.getIndex("payload").?);19224 const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("payload").?);
1922519225
19226 const error_set_ty = error_set_val.toType();19226 const error_set_ty = error_set_val.toType();
19227 const payload_ty = payload_val.toType();19227 const payload_ty = payload_val.toType();
...@@ -19234,7 +19234,7 @@ fn zirReify(...@@ -19234,7 +19234,7 @@ fn zirReify(
19234 return sema.addType(ty);19234 return sema.addType(ty);
19235 },19235 },
19236 .ErrorSet => {19236 .ErrorSet => {
19237 const payload_val = union_val.val.optionalValue(mod) orelse19237 const payload_val = union_val.val.toValue().optionalValue(mod) orelse
19238 return sema.addType(Type.anyerror);19238 return sema.addType(Type.anyerror);
1923919239
19240 const len = try sema.usizeCast(block, src, payload_val.sliceLen(mod));19240 const len = try sema.usizeCast(block, src, payload_val.sliceLen(mod));
...@@ -19258,12 +19258,12 @@ fn zirReify(...@@ -19258,12 +19258,12 @@ fn zirReify(
19258 return sema.addType(ty);19258 return sema.addType(ty);
19259 },19259 },
19260 .Struct => {19260 .Struct => {
19261 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19261 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19262 const layout_val = try union_val.val.fieldValue(mod, fields.getIndex("layout").?);19262 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
19263 const backing_integer_val = try union_val.val.fieldValue(mod, fields.getIndex("backing_integer").?);19263 const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("backing_integer").?);
19264 const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);19264 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19265 const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);19265 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19266 const is_tuple_val = try union_val.val.fieldValue(mod, fields.getIndex("is_tuple").?);19266 const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_tuple").?);
1926719267
19268 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);19268 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1926919269
...@@ -19279,11 +19279,11 @@ fn zirReify(...@@ -19279,11 +19279,11 @@ fn zirReify(
19279 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));19279 return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod));
19280 },19280 },
19281 .Enum => {19281 .Enum => {
19282 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19282 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19283 const tag_type_val = try union_val.val.fieldValue(mod, fields.getIndex("tag_type").?);19283 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
19284 const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);19284 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19285 const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);19285 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19286 const is_exhaustive_val = try union_val.val.fieldValue(mod, fields.getIndex("is_exhaustive").?);19286 const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_exhaustive").?);
1928719287
19288 // Decls19288 // Decls
19289 if (decls_val.sliceLen(mod) > 0) {19289 if (decls_val.sliceLen(mod) > 0) {
...@@ -19318,7 +19318,7 @@ fn zirReify(...@@ -19318,7 +19318,7 @@ fn zirReify(
19318 .nonexhaustive19318 .nonexhaustive
19319 else19319 else
19320 .explicit,19320 .explicit,
19321 .tag_ty = int_tag_ty.ip_index,19321 .tag_ty = int_tag_ty.toIntern(),
19322 });19322 });
19323 errdefer mod.intern_pool.remove(incomplete_enum.index);19323 errdefer mod.intern_pool.remove(incomplete_enum.index);
1932419324
...@@ -19360,7 +19360,7 @@ fn zirReify(...@@ -19360,7 +19360,7 @@ fn zirReify(
19360 return sema.failWithOwnedErrorMsg(msg);19360 return sema.failWithOwnedErrorMsg(msg);
19361 }19361 }
1936219362
19363 if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, value_val.ip_index)) |other| {19363 if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, value_val.toIntern())) |other| {
19364 const msg = msg: {19364 const msg = msg: {
19365 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});19365 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
19366 errdefer msg.destroy(gpa);19366 errdefer msg.destroy(gpa);
...@@ -19375,8 +19375,8 @@ fn zirReify(...@@ -19375,8 +19375,8 @@ fn zirReify(
19375 return sema.analyzeDeclVal(block, src, new_decl_index);19375 return sema.analyzeDeclVal(block, src, new_decl_index);
19376 },19376 },
19377 .Opaque => {19377 .Opaque => {
19378 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);19378 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19379 const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);19379 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
1938019380
19381 // Decls19381 // Decls
19382 if (decls_val.sliceLen(mod) > 0) {19382 if (decls_val.sliceLen(mod) > 0) {
...@@ -19419,11 +19419,11 @@ fn zirReify(...@@ -19419,11 +19419,11 @@ fn zirReify(
19419 return sema.analyzeDeclVal(block, src, new_decl_index);19419 return sema.analyzeDeclVal(block, src, new_decl_index);
19420 },19420 },
19421 .Union => {19421 .Union => {
19422 const fields = ip.typeOf(union_val.val.ip_index).toType().structFields(mod);19422 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19423 const layout_val = try union_val.val.fieldValue(mod, fields.getIndex("layout").?);19423 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
19424 const tag_type_val = try union_val.val.fieldValue(mod, fields.getIndex("tag_type").?);19424 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
19425 const fields_val = try union_val.val.fieldValue(mod, fields.getIndex("fields").?);19425 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19426 const decls_val = try union_val.val.fieldValue(mod, fields.getIndex("decls").?);19426 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
1942719427
19428 // Decls19428 // Decls
19429 if (decls_val.sliceLen(mod) > 0) {19429 if (decls_val.sliceLen(mod) > 0) {
...@@ -19491,7 +19491,7 @@ fn zirReify(...@@ -19491,7 +19491,7 @@ fn zirReify(
19491 if (tag_type_val.optionalValue(mod)) |payload_val| {19491 if (tag_type_val.optionalValue(mod)) |payload_val| {
19492 union_obj.tag_ty = payload_val.toType();19492 union_obj.tag_ty = payload_val.toType();
1949319493
19494 const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.ip_index)) {19494 const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
19495 .enum_type => |x| x,19495 .enum_type => |x| x,
19496 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),19496 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
19497 };19497 };
...@@ -19620,13 +19620,13 @@ fn zirReify(...@@ -19620,13 +19620,13 @@ fn zirReify(
19620 return sema.analyzeDeclVal(block, src, new_decl_index);19620 return sema.analyzeDeclVal(block, src, new_decl_index);
19621 },19621 },
19622 .Fn => {19622 .Fn => {
19623 const fields = ip.typeOf(union_val.val.toIntern()).toType().structFields(mod);19623 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19624 const calling_convention_val = try union_val.val.fieldValue(mod, fields.getIndex("calling_convention").?);19624 const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("calling_convention").?);
19625 const alignment_val = try union_val.val.fieldValue(mod, fields.getIndex("alignment").?);19625 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
19626 const is_generic_val = try union_val.val.fieldValue(mod, fields.getIndex("is_generic").?);19626 const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_generic").?);
19627 const is_var_args_val = try union_val.val.fieldValue(mod, fields.getIndex("is_var_args").?);19627 const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_var_args").?);
19628 const return_type_val = try union_val.val.fieldValue(mod, fields.getIndex("return_type").?);19628 const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?);
19629 const params_val = try union_val.val.fieldValue(mod, fields.getIndex("params").?);19629 const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?);
1963019630
19631 const is_generic = is_generic_val.toBool(mod);19631 const is_generic = is_generic_val.toBool(mod);
19632 if (is_generic) {19632 if (is_generic) {
...@@ -25204,12 +25204,12 @@ fn unionFieldPtr(...@@ -25204,12 +25204,12 @@ fn unionFieldPtr(
25204 if (union_val.isUndef(mod)) {25204 if (union_val.isUndef(mod)) {
25205 return sema.failWithUseOfUndef(block, src);25205 return sema.failWithUseOfUndef(block, src);
25206 }25206 }
25207 const tag_and_val = union_val.castTag(.@"union").?.data;25207 const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
25208 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);25208 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
25209 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);25209 const tag_matches = un.tag == field_tag.toIntern();
25210 if (!tag_matches) {25210 if (!tag_matches) {
25211 const msg = msg: {25211 const msg = msg: {
25212 const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;25212 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
25213 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25213 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25214 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });25214 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25215 errdefer msg.destroy(sema.gpa);25215 errdefer msg.destroy(sema.gpa);
...@@ -25269,16 +25269,16 @@ fn unionFieldVal(...@@ -25269,16 +25269,16 @@ fn unionFieldVal(
25269 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {25269 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
25270 if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);25270 if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);
2527125271
25272 const tag_and_val = union_val.castTag(.@"union").?.data;25272 const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
25273 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);25273 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
25274 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, mod);25274 const tag_matches = un.tag == field_tag.toIntern();
25275 switch (union_obj.layout) {25275 switch (union_obj.layout) {
25276 .Auto => {25276 .Auto => {
25277 if (tag_matches) {25277 if (tag_matches) {
25278 return sema.addConstant(field.ty, tag_and_val.val);25278 return sema.addConstant(field.ty, un.val.toValue());
25279 } else {25279 } else {
25280 const msg = msg: {25280 const msg = msg: {
25281 const active_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, mod).?;25281 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
25282 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25282 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25283 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });25283 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25284 errdefer msg.destroy(sema.gpa);25284 errdefer msg.destroy(sema.gpa);
...@@ -25290,10 +25290,10 @@ fn unionFieldVal(...@@ -25290,10 +25290,10 @@ fn unionFieldVal(
25290 },25290 },
25291 .Packed, .Extern => {25291 .Packed, .Extern => {
25292 if (tag_matches) {25292 if (tag_matches) {
25293 return sema.addConstant(field.ty, tag_and_val.val);25293 return sema.addConstant(field.ty, un.val.toValue());
25294 } else {25294 } else {
25295 const old_ty = union_ty.unionFieldType(tag_and_val.tag, mod);25295 const old_ty = union_ty.unionFieldType(un.tag.toValue(), mod);
25296 if (try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0)) |new_val| {25296 if (try sema.bitCastVal(block, src, un.val.toValue(), old_ty, field.ty, 0)) |new_val| {
25297 return sema.addConstant(field.ty, new_val);25297 return sema.addConstant(field.ty, new_val);
25298 }25298 }
25299 }25299 }
...@@ -27626,7 +27626,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -27626,7 +27626,7 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
27626 // allocations is relevant to this function, or why it would have27626 // allocations is relevant to this function, or why it would have
27627 // different behavior depending on whether the types were inferred.27627 // different behavior depending on whether the types were inferred.
27628 // Something seems wrong here.27628 // Something seems wrong here.
27629 switch (prev_ptr_ty.ip_index) {27629 switch (prev_ptr_ty.toIntern()) {
27630 .inferred_alloc_mut_type, .inferred_alloc_const_type => return null,27630 .inferred_alloc_mut_type, .inferred_alloc_const_type => return null,
27631 else => {},27631 else => {},
27632 }27632 }
src/codegen/llvm.zig+12-3
...@@ -3208,7 +3208,8 @@ pub const DeclGen = struct {...@@ -3208,7 +3208,8 @@ pub const DeclGen = struct {
3208 return llvm_type.getUndef();3208 return llvm_type.getUndef();
3209 }3209 }
32103210
3211 switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {3211 const val_key = mod.intern_pool.indexToKey(tv.val.toIntern());
3212 switch (val_key) {
3212 .int_type,3213 .int_type,
3213 .ptr_type,3214 .ptr_type,
3214 .array_type,3215 .array_type,
...@@ -3242,10 +3243,18 @@ pub const DeclGen = struct {...@@ -3242,10 +3243,18 @@ pub const DeclGen = struct {
3242 },3243 },
3243 },3244 },
3244 .variable,3245 .variable,
3245 .extern_func,
3246 .func,
3247 .enum_literal,3246 .enum_literal,
3248 => unreachable, // non-runtime values3247 => unreachable, // non-runtime values
3248 .extern_func, .func => {
3249 const fn_decl_index = switch (val_key) {
3250 .extern_func => |extern_func| extern_func.decl,
3251 .func => |func| mod.funcPtr(func.index).owner_decl,
3252 else => unreachable,
3253 };
3254 const fn_decl = dg.module.declPtr(fn_decl_index);
3255 dg.module.markDeclAlive(fn_decl);
3256 return dg.resolveLlvmFunction(fn_decl_index);
3257 },
3249 .int => |int| {3258 .int => |int| {
3250 var bigint_space: Value.BigIntSpace = undefined;3259 var bigint_space: Value.BigIntSpace = undefined;
3251 const bigint = int.storage.toBigInt(&bigint_space);3260 const bigint = int.storage.toBigInt(&bigint_space);
src/value.zig+21-2
...@@ -1961,12 +1961,31 @@ pub const Value = struct {...@@ -1961,12 +1961,31 @@ pub const Value = struct {
1961 mod: *Module,1961 mod: *Module,
1962 ) Allocator.Error!Value {1962 ) Allocator.Error!Value {
1963 const elem_ty = ty.elemType2(mod);1963 const elem_ty = ty.elemType2(mod);
1964 const ptr_ty_key = mod.intern_pool.indexToKey(ty.toIntern()).ptr_type;
1965 assert(ptr_ty_key.host_size == 0);
1966 assert(ptr_ty_key.bit_offset == 0);
1967 assert(ptr_ty_key.vector_index == .none);
1968 const elem_alignment = InternPool.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));
1969 const alignment = switch (ptr_ty_key.alignment) {
1970 .none => .none,
1971 else => ptr_ty_key.alignment.min(
1972 @intToEnum(InternPool.Alignment, @ctz(index * elem_ty.abiSize(mod))),
1973 ),
1974 };
1975 const ptr_ty = try mod.ptrType(.{
1976 .elem_type = elem_ty.toIntern(),
1977 .alignment = if (alignment == elem_alignment) .none else alignment,
1978 .is_const = ptr_ty_key.is_const,
1979 .is_volatile = ptr_ty_key.is_volatile,
1980 .is_allowzero = ptr_ty_key.is_allowzero,
1981 .address_space = ptr_ty_key.address_space,
1982 });
1964 const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {1983 const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) {
1965 .ptr => |ptr| ptr: {1984 .ptr => |ptr| ptr: {
1966 switch (ptr.addr) {1985 switch (ptr.addr) {
1967 .elem => |elem| if (mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).eql(elem_ty, mod))1986 .elem => |elem| if (mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).eql(elem_ty, mod))
1968 return (try mod.intern(.{ .ptr = .{1987 return (try mod.intern(.{ .ptr = .{
1969 .ty = ty.toIntern(),1988 .ty = ptr_ty.toIntern(),
1970 .addr = .{ .elem = .{1989 .addr = .{ .elem = .{
1971 .base = elem.base,1990 .base = elem.base,
1972 .index = elem.index + index,1991 .index = elem.index + index,
...@@ -1982,7 +2001,7 @@ pub const Value = struct {...@@ -1982,7 +2001,7 @@ pub const Value = struct {
1982 else => val,2001 else => val,
1983 };2002 };
1984 return (try mod.intern(.{ .ptr = .{2003 return (try mod.intern(.{ .ptr = .{
1985 .ty = ty.toIntern(),2004 .ty = ptr_ty.toIntern(),
1986 .addr = .{ .elem = .{2005 .addr = .{ .elem = .{
1987 .base = ptr_val.toIntern(),2006 .base = ptr_val.toIntern(),
1988 .index = index,2007 .index = index,