authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-28 10:33:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:56-07:00
log3064d2aa7b9a8ea836cb70884b0640fe902ecc29
treea3e315a06c0912e03ddac6b04cbe23205872bd31
parent3b6ca1d35b950d67fff5964f0063dadf01f30e2d

behavior: additional llvm fixes


13 files changed, 160 insertions(+), 137 deletions(-)

src/InternPool.zig+20-15
...@@ -3131,7 +3131,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -3131,7 +3131,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
3131 },3131 },
31323132
3133 .enum_type => |enum_type| {3133 .enum_type => |enum_type| {
3134 assert(enum_type.tag_ty != .none);3134 assert(enum_type.tag_ty == .noreturn_type or ip.isIntegerType(enum_type.tag_ty));
3135 for (enum_type.values) |value| assert(ip.typeOf(value) == enum_type.tag_ty);
3135 assert(enum_type.names_map == .none);3136 assert(enum_type.names_map == .none);
3136 assert(enum_type.values_map == .none);3137 assert(enum_type.values_map == .none);
31373138
...@@ -3622,14 +3623,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -3622,14 +3623,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
3622 if (bytes.len != len) {3623 if (bytes.len != len) {
3623 assert(bytes.len == len_including_sentinel);3624 assert(bytes.len == len_including_sentinel);
3624 assert(bytes[len] == ip.indexToKey(sentinel).int.storage.u64);3625 assert(bytes[len] == ip.indexToKey(sentinel).int.storage.u64);
3625 unreachable;
3626 }3626 }
3627 },3627 },
3628 .elems => |elems| {3628 .elems => |elems| {
3629 if (elems.len != len) {3629 if (elems.len != len) {
3630 assert(elems.len == len_including_sentinel);3630 assert(elems.len == len_including_sentinel);
3631 assert(elems[len] == sentinel);3631 assert(elems[len] == sentinel);
3632 unreachable;
3633 }3632 }
3634 },3633 },
3635 .repeated_elem => |elem| {3634 .repeated_elem => |elem| {
...@@ -3832,7 +3831,7 @@ pub const IncompleteEnumType = struct {...@@ -3832,7 +3831,7 @@ pub const IncompleteEnumType = struct {
3832 values_start: u32,3831 values_start: u32,
38333832
3834 pub fn setTagType(self: @This(), ip: *InternPool, tag_ty: Index) void {3833 pub fn setTagType(self: @This(), ip: *InternPool, tag_ty: Index) void {
3835 assert(tag_ty != .none);3834 assert(tag_ty == .noreturn_type or ip.isIntegerType(tag_ty));
3836 ip.extra.items[self.tag_ty_index] = @enumToInt(tag_ty);3835 ip.extra.items[self.tag_ty_index] = @enumToInt(tag_ty);
3837 }3836 }
38383837
...@@ -3863,6 +3862,7 @@ pub const IncompleteEnumType = struct {...@@ -3863,6 +3862,7 @@ pub const IncompleteEnumType = struct {
3863 gpa: Allocator,3862 gpa: Allocator,
3864 value: Index,3863 value: Index,
3865 ) Allocator.Error!?u32 {3864 ) Allocator.Error!?u32 {
3865 assert(ip.typeOf(value) == @intToEnum(Index, ip.extra.items[self.tag_ty_index]));
3866 const map = &ip.maps.items[@enumToInt(self.values_map.unwrap().?)];3866 const map = &ip.maps.items[@enumToInt(self.values_map.unwrap().?)];
3867 const field_index = map.count();3867 const field_index = map.count();
3868 const indexes = ip.extra.items[self.values_start..][0..field_index];3868 const indexes = ip.extra.items[self.values_start..][0..field_index];
...@@ -4346,7 +4346,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {...@@ -4346,7 +4346,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
4346/// * ptr <=> ptr4346/// * ptr <=> ptr
4347/// * opt ptr <=> ptr4347/// * opt ptr <=> ptr
4348/// * opt ptr <=> opt ptr4348/// * opt ptr <=> opt ptr
4349/// * int => ptr4349/// * int <=> ptr
4350/// * null_value => opt4350/// * null_value => opt
4351/// * payload => opt4351/// * payload => opt
4352/// * error set <=> error set4352/// * error set <=> error set
...@@ -4386,18 +4386,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -4386,18 +4386,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4386 .ty = new_ty,4386 .ty = new_ty,
4387 .index = func.index,4387 .index = func.index,
4388 } }),4388 } }),
4389 .int => |int| if (ip.isIntegerType(new_ty))4389 .int => |int| switch (ip.indexToKey(new_ty)) {
4390 return getCoercedInts(ip, gpa, int, new_ty)4390 .enum_type => |enum_type| return ip.get(gpa, .{ .enum_tag = .{
4391 else if (ip.isEnumType(new_ty))
4392 return ip.get(gpa, .{ .enum_tag = .{
4393 .ty = new_ty,4391 .ty = new_ty,
4394 .int = val,4392 .int = try ip.getCoerced(gpa, val, enum_type.tag_ty),
4395 } })4393 } }),
4396 else if (ip.isPointerType(new_ty))4394 .ptr_type => return ip.get(gpa, .{ .ptr = .{
4397 return ip.get(gpa, .{ .ptr = .{
4398 .ty = new_ty,4395 .ty = new_ty,
4399 .addr = .{ .int = val },4396 .addr = .{ .int = try ip.getCoerced(gpa, val, .usize_type) },
4400 } }),4397 } }),
4398 else => if (ip.isIntegerType(new_ty))
4399 return getCoercedInts(ip, gpa, int, new_ty),
4400 },
4401 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))4401 .enum_tag => |enum_tag| if (ip.isIntegerType(new_ty))
4402 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty),4402 return getCoercedInts(ip, gpa, ip.indexToKey(enum_tag.int).int, new_ty),
4403 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {4403 .enum_literal => |enum_literal| switch (ip.indexToKey(new_ty)) {
...@@ -4421,7 +4421,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -4421,7 +4421,12 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
4421 .ty = new_ty,4421 .ty = new_ty,
4422 .addr = ptr.addr,4422 .addr = ptr.addr,
4423 .len = ptr.len,4423 .len = ptr.len,
4424 } }),4424 } })
4425 else if (ip.isIntegerType(new_ty))
4426 switch (ptr.addr) {
4427 .int => |int| return ip.getCoerced(gpa, int, new_ty),
4428 else => {},
4429 },
4425 .opt => |opt| if (ip.isPointerType(new_ty))4430 .opt => |opt| if (ip.isPointerType(new_ty))
4426 return switch (opt.val) {4431 return switch (opt.val) {
4427 .none => try ip.get(gpa, .{ .ptr = .{4432 .none => try ip.get(gpa, .{ .ptr = .{
src/Module.zig+5-1
...@@ -707,6 +707,10 @@ pub const Decl = struct {...@@ -707,6 +707,10 @@ pub const Decl = struct {
707 return TypedValue{ .ty = decl.ty, .val = decl.val };707 return TypedValue{ .ty = decl.ty, .val = decl.val };
708 }708 }
709709
710 pub fn internValue(decl: Decl, mod: *Module) Allocator.Error!InternPool.Index {
711 return decl.val.intern(decl.ty, mod);
712 }
713
710 pub fn isFunction(decl: Decl, mod: *const Module) !bool {714 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
711 const tv = try decl.typedValue();715 const tv = try decl.typedValue();
712 return tv.ty.zigTypeTag(mod) == .Fn;716 return tv.ty.zigTypeTag(mod) == .Fn;
...@@ -7073,7 +7077,7 @@ pub fn atomicPtrAlignment(...@@ -7073,7 +7077,7 @@ pub fn atomicPtrAlignment(
70737077
7074 const int_ty = switch (ty.zigTypeTag(mod)) {7078 const int_ty = switch (ty.zigTypeTag(mod)) {
7075 .Int => ty,7079 .Int => ty,
7076 .Enum => try ty.intTagType(mod),7080 .Enum => ty.intTagType(mod),
7077 .Float => {7081 .Float => {
7078 const bit_count = ty.floatBits(target);7082 const bit_count = ty.floatBits(target);
7079 if (bit_count > max_atomic_bits) {7083 if (bit_count > max_atomic_bits) {
src/Sema.zig+67-66
...@@ -3291,7 +3291,8 @@ fn zirErrorSetDecl(...@@ -3291,7 +3291,8 @@ fn zirErrorSetDecl(
3291 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string3291 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
3292 const str_index = sema.code.extra[extra_index];3292 const str_index = sema.code.extra[extra_index];
3293 const name = sema.code.nullTerminatedString(str_index);3293 const name = sema.code.nullTerminatedString(str_index);
3294 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);3294 const kv = try mod.getErrorValue(name);
3295 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
3295 const result = names.getOrPutAssumeCapacity(name_ip);3296 const result = names.getOrPutAssumeCapacity(name_ip);
3296 assert(!result.found_existing); // verified in AstGen3297 assert(!result.found_existing); // verified in AstGen
3297 }3298 }
...@@ -6409,7 +6410,7 @@ fn zirCall(...@@ -6409,7 +6410,7 @@ fn zirCall(
64096410
6410 // Generate args to comptime params in comptime block.6411 // Generate args to comptime params in comptime block.
6411 defer block.is_comptime = parent_comptime;6412 defer block.is_comptime = parent_comptime;
6412 if (arg_index < fn_params_len and func_ty_info.paramIsComptime(@intCast(u5, arg_index))) {6413 if (arg_index < @min(fn_params_len, 32) and func_ty_info.paramIsComptime(@intCast(u5, arg_index))) {
6413 block.is_comptime = true;6414 block.is_comptime = true;
6414 // TODO set comptime_reason6415 // TODO set comptime_reason
6415 }6416 }
...@@ -7077,14 +7078,13 @@ fn analyzeCall(...@@ -7077,14 +7078,13 @@ fn analyzeCall(
7077 assert(!func_ty_info.is_generic);7078 assert(!func_ty_info.is_generic);
70787079
7079 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);7080 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
7080 const fn_info = mod.typeToFunc(func_ty).?;
7081 for (uncasted_args, 0..) |uncasted_arg, i| {7081 for (uncasted_args, 0..) |uncasted_arg, i| {
7082 if (i < fn_params_len) {7082 if (i < fn_params_len) {
7083 const opts: CoerceOpts = .{ .param_src = .{7083 const opts: CoerceOpts = .{ .param_src = .{
7084 .func_inst = func,7084 .func_inst = func,
7085 .param_i = @intCast(u32, i),7085 .param_i = @intCast(u32, i),
7086 } };7086 } };
7087 const param_ty = fn_info.param_types[i].toType();7087 const param_ty = mod.typeToFunc(func_ty).?.param_types[i].toType();
7088 args[i] = sema.analyzeCallArg(7088 args[i] = sema.analyzeCallArg(
7089 block,7089 block,
7090 .unneeded,7090 .unneeded,
...@@ -8267,7 +8267,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8267,7 +8267,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8267 };8267 };
8268 const enum_tag_ty = sema.typeOf(enum_tag);8268 const enum_tag_ty = sema.typeOf(enum_tag);
82698269
8270 const int_tag_ty = try enum_tag_ty.intTagType(mod);8270 const int_tag_ty = enum_tag_ty.intTagType(mod);
82718271
8272 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {8272 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8273 return sema.addConstant(int_tag_ty, try mod.getCoerced(opv, int_tag_ty));8273 return sema.addConstant(int_tag_ty, try mod.getCoerced(opv, int_tag_ty));
...@@ -8299,12 +8299,9 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8299,12 +8299,9 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
82998299
8300 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {8300 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
8301 if (dest_ty.isNonexhaustiveEnum(mod)) {8301 if (dest_ty.isNonexhaustiveEnum(mod)) {
8302 const int_tag_ty = try dest_ty.intTagType(mod);8302 const int_tag_ty = dest_ty.intTagType(mod);
8303 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {8303 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8304 return sema.addConstant(dest_ty, (try mod.intern(.{ .enum_tag = .{8304 return sema.addConstant(dest_ty, try mod.getCoerced(int_val, dest_ty));
8305 .ty = dest_ty.toIntern(),
8306 .int = int_val.toIntern(),
8307 } })).toValue());
8308 }8305 }
8309 const msg = msg: {8306 const msg = msg: {
8310 const msg = try sema.errMsg(8307 const msg = try sema.errMsg(
...@@ -8336,7 +8333,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -8336,7 +8333,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
8336 };8333 };
8337 return sema.failWithOwnedErrorMsg(msg);8334 return sema.failWithOwnedErrorMsg(msg);
8338 }8335 }
8339 return sema.addConstant(dest_ty, int_val);8336 return sema.addConstant(dest_ty, try mod.getCoerced(int_val, dest_ty));
8340 }8337 }
83418338
8342 if (try sema.typeHasOnePossibleValue(dest_ty)) |opv| {8339 if (try sema.typeHasOnePossibleValue(dest_ty)) |opv| {
...@@ -9513,7 +9510,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9513,7 +9510,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9513 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});9510 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)});
9514 }9511 }
9515 if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| {9512 if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| {
9516 return sema.addConstant(Type.usize, ptr_val);9513 return sema.addConstant(Type.usize, try mod.getCoerced(ptr_val, Type.usize));
9517 }9514 }
9518 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);9515 try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src);
9519 return block.addUnOp(.ptrtoint, ptr);9516 return block.addUnOp(.ptrtoint, ptr);
...@@ -9651,7 +9648,7 @@ fn intCast(...@@ -9651,7 +9648,7 @@ fn intCast(
9651 // range shrinkage9648 // range shrinkage
9652 // requirement: int value fits into target type9649 // requirement: int value fits into target type
9653 if (wanted_value_bits < actual_value_bits) {9650 if (wanted_value_bits < actual_value_bits) {
9654 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_ty);9651 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_scalar_ty);
9655 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);9652 const dest_max_val = try sema.splat(operand_ty, dest_max_val_scalar);
9656 const dest_max = try sema.addConstant(operand_ty, dest_max_val);9653 const dest_max = try sema.addConstant(operand_ty, dest_max_val);
9657 const diff = try block.addBinOp(.subwrap, dest_max, operand);9654 const diff = try block.addBinOp(.subwrap, dest_max, operand);
...@@ -12848,7 +12845,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12848,7 +12845,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12848 if (res_sent_val) |sent_val| {12845 if (res_sent_val) |sent_val| {
12849 const elem_index = try sema.addIntUnsigned(Type.usize, result_len);12846 const elem_index = try sema.addIntUnsigned(Type.usize, result_len);
12850 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);12847 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
12851 const init = try sema.addConstant(lhs_info.elem_type, sent_val);12848 const init = try sema.addConstant(lhs_info.elem_type, try mod.getCoerced(sent_val, lhs_info.elem_type));
12852 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);12849 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
12853 }12850 }
1285412851
...@@ -19236,7 +19233,8 @@ fn zirReify(...@@ -19236,7 +19233,8 @@ fn zirReify(
19236 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);19233 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
1923719234
19238 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);19235 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
19239 const name_ip = try mod.intern_pool.getOrPutString(gpa, name_str);19236 const kv = try mod.getErrorValue(name_str);
19237 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
19240 const gop = names.getOrPutAssumeCapacity(name_ip);19238 const gop = names.getOrPutAssumeCapacity(name_ip);
19241 if (gop.found_existing) {19239 if (gop.found_existing) {
19242 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});19240 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
...@@ -19346,7 +19344,7 @@ fn zirReify(...@@ -19346,7 +19344,7 @@ fn zirReify(
19346 return sema.failWithOwnedErrorMsg(msg);19344 return sema.failWithOwnedErrorMsg(msg);
19347 }19345 }
1934819346
19349 if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, value_val.toIntern())) |other| {19347 if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, (try mod.getCoerced(value_val, int_tag_ty)).toIntern())) |other| {
19350 const msg = msg: {19348 const msg = msg: {
19351 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});19349 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
19352 errdefer msg.destroy(gpa);19350 errdefer msg.destroy(gpa);
...@@ -20263,7 +20261,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -20263,7 +20261,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
20263 }20261 }
20264 }20262 }
2026520263
20266 return sema.addConstant(dest_ty, val);20264 return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
20267 }20265 }
2026820266
20269 try sema.requireRuntimeBlock(block, src, operand_src);20267 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -20421,7 +20419,7 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -20421,7 +20419,7 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
20421 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);20419 const dest_ty = try Type.ptr(sema.arena, mod, ptr_info);
2042220420
20423 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {20421 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
20424 return sema.addConstant(dest_ty, operand_val);20422 return sema.addConstant(dest_ty, try mod.getCoerced(operand_val, dest_ty));
20425 }20423 }
2042620424
20427 try sema.requireRuntimeBlock(block, src, null);20425 try sema.requireRuntimeBlock(block, src, null);
...@@ -20624,7 +20622,7 @@ fn zirBitCount(...@@ -20624,7 +20622,7 @@ fn zirBitCount(
20624 for (elems, 0..) |*elem, i| {20622 for (elems, 0..) |*elem, i| {
20625 const elem_val = try val.elemValue(mod, i);20623 const elem_val = try val.elemValue(mod, i);
20626 const count = comptimeOp(elem_val, scalar_ty, mod);20624 const count = comptimeOp(elem_val, scalar_ty, mod);
20627 elem.* = (try mod.intValue(scalar_ty, count)).toIntern();20625 elem.* = (try mod.intValue(result_scalar_ty, count)).toIntern();
20628 }20626 }
20629 return sema.addConstant(result_ty, (try mod.intern(.{ .aggregate = .{20627 return sema.addConstant(result_ty, (try mod.intern(.{ .aggregate = .{
20630 .ty = result_ty.toIntern(),20628 .ty = result_ty.toIntern(),
...@@ -22385,7 +22383,9 @@ fn analyzeMinMax(...@@ -22385,7 +22383,9 @@ fn analyzeMinMax(
22385 if (std.debug.runtime_safety) {22383 if (std.debug.runtime_safety) {
22386 assert(try sema.intFitsInType(val, refined_ty, null));22384 assert(try sema.intFitsInType(val, refined_ty, null));
22387 }22385 }
22388 cur_minmax = try sema.addConstant(refined_ty, try mod.getCoerced(val, refined_ty));22386 cur_minmax = try sema.addConstant(refined_ty, (try sema.resolveMaybeUndefVal(
22387 try sema.coerceInMemory(block, val, orig_ty, refined_ty, src),
22388 )).?);
22389 }22389 }
2239022390
22391 break :refined refined_ty;22391 break :refined refined_ty;
...@@ -23684,7 +23684,7 @@ fn validateExternType(...@@ -23684,7 +23684,7 @@ fn validateExternType(
23684 return !target_util.fnCallConvAllowsZigTypes(target, ty.fnCallingConvention(mod));23684 return !target_util.fnCallConvAllowsZigTypes(target, ty.fnCallingConvention(mod));
23685 },23685 },
23686 .Enum => {23686 .Enum => {
23687 return sema.validateExternType(try ty.intTagType(mod), position);23687 return sema.validateExternType(ty.intTagType(mod), position);
23688 },23688 },
23689 .Struct, .Union => switch (ty.containerLayout(mod)) {23689 .Struct, .Union => switch (ty.containerLayout(mod)) {
23690 .Extern => return true,23690 .Extern => return true,
...@@ -23762,7 +23762,7 @@ fn explainWhyTypeIsNotExtern(...@@ -23762,7 +23762,7 @@ fn explainWhyTypeIsNotExtern(
23762 }23762 }
23763 },23763 },
23764 .Enum => {23764 .Enum => {
23765 const tag_ty = try ty.intTagType(mod);23765 const tag_ty = ty.intTagType(mod);
23766 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});23766 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
23767 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);23767 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
23768 },23768 },
...@@ -25412,7 +25412,8 @@ fn elemVal(...@@ -25412,7 +25412,8 @@ fn elemVal(
25412 const elem_ptr_ty = try sema.elemPtrType(indexable_ty, index);25412 const elem_ptr_ty = try sema.elemPtrType(indexable_ty, index);
25413 const elem_ptr_val = try indexable_val.elemPtr(elem_ptr_ty, index, mod);25413 const elem_ptr_val = try indexable_val.elemPtr(elem_ptr_ty, index, mod);
25414 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {25414 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
25415 return sema.addConstant(indexable_ty.elemType2(mod), elem_val);25415 const result_ty = indexable_ty.elemType2(mod);
25416 return sema.addConstant(result_ty, try mod.getCoerced(elem_val, result_ty));
25416 }25417 }
25417 break :rs indexable_src;25418 break :rs indexable_src;
25418 };25419 };
...@@ -26603,6 +26604,10 @@ fn coerceInMemory(...@@ -26603,6 +26604,10 @@ fn coerceInMemory(
26603 .storage = .{ .elems = dest_elems },26604 .storage = .{ .elems = dest_elems },
26604 } })).toValue());26605 } })).toValue());
26605 },26606 },
26607 .float => |float| return sema.addConstant(dst_ty, (try mod.intern(.{ .float = .{
26608 .ty = dst_ty.toIntern(),
26609 .storage = float.storage,
26610 } })).toValue()),
26606 else => return sema.addConstant(dst_ty, try mod.getCoerced(val, dst_ty)),26611 else => return sema.addConstant(dst_ty, try mod.getCoerced(val, dst_ty)),
26607 }26612 }
26608}26613}
...@@ -26983,8 +26988,11 @@ fn coerceInMemoryAllowed(...@@ -26983,8 +26988,11 @@ fn coerceInMemoryAllowed(
26983 if (dest_ty.eql(src_ty, mod))26988 if (dest_ty.eql(src_ty, mod))
26984 return .ok;26989 return .ok;
2698526990
26991 const dest_tag = dest_ty.zigTypeTag(mod);
26992 const src_tag = src_ty.zigTypeTag(mod);
26993
26986 // Differently-named integers with the same number of bits.26994 // Differently-named integers with the same number of bits.
26987 if (dest_ty.zigTypeTag(mod) == .Int and src_ty.zigTypeTag(mod) == .Int) {26995 if (dest_tag == .Int and src_tag == .Int) {
26988 const dest_info = dest_ty.intInfo(mod);26996 const dest_info = dest_ty.intInfo(mod);
26989 const src_info = src_ty.intInfo(mod);26997 const src_info = src_ty.intInfo(mod);
2699026998
...@@ -27009,7 +27017,7 @@ fn coerceInMemoryAllowed(...@@ -27009,7 +27017,7 @@ fn coerceInMemoryAllowed(
27009 }27017 }
2701027018
27011 // Differently-named floats with the same number of bits.27019 // Differently-named floats with the same number of bits.
27012 if (dest_ty.zigTypeTag(mod) == .Float and src_ty.zigTypeTag(mod) == .Float) {27020 if (dest_tag == .Float and src_tag == .Float) {
27013 const dest_bits = dest_ty.floatBits(target);27021 const dest_bits = dest_ty.floatBits(target);
27014 const src_bits = src_ty.floatBits(target);27022 const src_bits = src_ty.floatBits(target);
27015 if (dest_bits == src_bits) {27023 if (dest_bits == src_bits) {
...@@ -27031,9 +27039,6 @@ fn coerceInMemoryAllowed(...@@ -27031,9 +27039,6 @@ fn coerceInMemoryAllowed(
27031 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);27039 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
27032 }27040 }
2703327041
27034 const dest_tag = dest_ty.zigTypeTag(mod);
27035 const src_tag = src_ty.zigTypeTag(mod);
27036
27037 // Functions27042 // Functions
27038 if (dest_tag == .Fn and src_tag == .Fn) {27043 if (dest_tag == .Fn and src_tag == .Fn) {
27039 return try sema.coerceInMemoryAllowedFns(block, dest_ty, src_ty, target, dest_src, src_src);27044 return try sema.coerceInMemoryAllowedFns(block, dest_ty, src_ty, target, dest_src, src_src);
...@@ -27808,7 +27813,7 @@ fn beginComptimePtrMutation(...@@ -27808,7 +27813,7 @@ fn beginComptimePtrMutation(
27808 .comptime_field => |comptime_field| {27813 .comptime_field => |comptime_field| {
27809 const duped = try sema.arena.create(Value);27814 const duped = try sema.arena.create(Value);
27810 duped.* = comptime_field.toValue();27815 duped.* = comptime_field.toValue();
27811 return sema.beginComptimePtrMutationInner(block, src, mod.intern_pool.typeOf(ptr_val.toIntern()).toType(), duped, ptr_elem_ty, .{27816 return sema.beginComptimePtrMutationInner(block, src, mod.intern_pool.typeOf(comptime_field).toType(), duped, ptr_elem_ty, .{
27812 .decl = undefined,27817 .decl = undefined,
27813 .runtime_index = .comptime_field_ptr,27818 .runtime_index = .comptime_field_ptr,
27814 });27819 });
...@@ -27864,7 +27869,21 @@ fn beginComptimePtrMutation(...@@ -27864,7 +27869,21 @@ fn beginComptimePtrMutation(
27864 .direct => |val_ptr| {27869 .direct => |val_ptr| {
27865 const payload_ty = parent.ty.optionalChild(mod);27870 const payload_ty = parent.ty.optionalChild(mod);
27866 switch (val_ptr.ip_index) {27871 switch (val_ptr.ip_index) {
27867 .undef, .null_value => {27872 .none => return ComptimePtrMutationKit{
27873 .mut_decl = parent.mut_decl,
27874 .pointee = .{ .direct = &val_ptr.castTag(.opt_payload).?.data },
27875 .ty = payload_ty,
27876 },
27877 else => {
27878 const payload_val = switch (mod.intern_pool.indexToKey(val_ptr.ip_index)) {
27879 .undef => try mod.intern(.{ .undef = payload_ty.toIntern() }),
27880 .opt => |opt| switch (opt.val) {
27881 .none => try mod.intern(.{ .undef = payload_ty.toIntern() }),
27882 else => opt.val,
27883 },
27884 else => unreachable,
27885 };
27886
27868 // An optional has been initialized to undefined at comptime and now we27887 // An optional has been initialized to undefined at comptime and now we
27869 // are for the first time setting the payload. We must change the27888 // are for the first time setting the payload. We must change the
27870 // representation of the optional from `undef` to `opt_payload`.27889 // representation of the optional from `undef` to `opt_payload`.
...@@ -27874,7 +27893,7 @@ fn beginComptimePtrMutation(...@@ -27874,7 +27893,7 @@ fn beginComptimePtrMutation(
27874 const payload = try arena.create(Value.Payload.SubValue);27893 const payload = try arena.create(Value.Payload.SubValue);
27875 payload.* = .{27894 payload.* = .{
27876 .base = .{ .tag = .opt_payload },27895 .base = .{ .tag = .opt_payload },
27877 .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(),27896 .data = payload_val.toValue(),
27878 };27897 };
2787927898
27880 val_ptr.* = Value.initPayload(&payload.base);27899 val_ptr.* = Value.initPayload(&payload.base);
...@@ -27885,24 +27904,6 @@ fn beginComptimePtrMutation(...@@ -27885,24 +27904,6 @@ fn beginComptimePtrMutation(
27885 .ty = payload_ty,27904 .ty = payload_ty,
27886 };27905 };
27887 },27906 },
27888 .none => switch (val_ptr.tag()) {
27889 .opt_payload => return ComptimePtrMutationKit{
27890 .mut_decl = parent.mut_decl,
27891 .pointee = .{ .direct = &val_ptr.castTag(.opt_payload).?.data },
27892 .ty = payload_ty,
27893 },
27894
27895 else => return ComptimePtrMutationKit{
27896 .mut_decl = parent.mut_decl,
27897 .pointee = .{ .direct = val_ptr },
27898 .ty = payload_ty,
27899 },
27900 },
27901 else => return ComptimePtrMutationKit{
27902 .mut_decl = parent.mut_decl,
27903 .pointee = .{ .direct = val_ptr },
27904 .ty = payload_ty,
27905 },
27906 }27907 }
27907 },27908 },
27908 .bad_decl_ty, .bad_ptr_ty => return parent,27909 .bad_decl_ty, .bad_ptr_ty => return parent,
...@@ -33339,16 +33340,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33339,16 +33340,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3333933340
33340 return null;33341 return null;
33341 },33342 },
33342 .auto, .explicit => switch (enum_type.names.len) {33343 .auto, .explicit => {
33343 0 => return Value.@"unreachable",33344 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
33344 1 => return try mod.getCoerced((if (enum_type.values.len == 0)33345
33345 try mod.intern(.{ .int = .{33346 switch (enum_type.names.len) {
33346 .ty = enum_type.tag_ty,33347 0 => return Value.@"unreachable",
33347 .storage = .{ .u64 = 0 },33348 1 => return try mod.getCoerced((if (enum_type.values.len == 0)
33348 } })33349 try mod.intern(.{ .int = .{
33349 else33350 .ty = enum_type.tag_ty,
33350 enum_type.values[0]).toValue(), ty),33351 .storage = .{ .u64 = 0 },
33351 else => return null,33352 } })
33353 else
33354 enum_type.values[0]).toValue(), ty),
33355 else => return null,
33356 }
33352 },33357 },
33353 },33358 },
3335433359
...@@ -34241,13 +34246,9 @@ fn intFitsInType(...@@ -34241,13 +34246,9 @@ fn intFitsInType(
34241 if (ty.toIntern() == .comptime_int_type) return true;34246 if (ty.toIntern() == .comptime_int_type) return true;
34242 const info = ty.intInfo(mod);34247 const info = ty.intInfo(mod);
34243 switch (val.toIntern()) {34248 switch (val.toIntern()) {
34244 .undef,34249 .zero_usize, .zero_u8 => return true,
34245 .zero,
34246 .zero_usize,
34247 .zero_u8,
34248 => return true,
34249
34250 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {34250 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
34251 .undef => return true,
34251 .variable, .extern_func, .func, .ptr => {34252 .variable, .extern_func, .func, .ptr => {
34252 const target = mod.getTarget();34253 const target = mod.getTarget();
34253 const ptr_bits = target.ptrBitWidth();34254 const ptr_bits = target.ptrBitWidth();
...@@ -34553,7 +34554,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {...@@ -34553,7 +34554,7 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {
34553 return sema.typeOf(ref).isNoReturn(sema.mod);34554 return sema.typeOf(ref).isNoReturn(sema.mod);
34554}34555}
3455534556
34556/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain type.34557/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.
34557fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool {34558fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool {
34558 if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) {34559 if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) {
34559 .inferred_alloc, .inferred_alloc_comptime => return false,34560 .inferred_alloc, .inferred_alloc_comptime => return false,
src/TypedValue.zig+8-4
...@@ -302,10 +302,14 @@ fn printAggregate(...@@ -302,10 +302,14 @@ fn printAggregate(
302 var i: u32 = 0;302 var i: u32 = 0;
303 while (i < max_len) : (i += 1) {303 while (i < max_len) : (i += 1) {
304 if (i != 0) try writer.writeAll(", ");304 if (i != 0) try writer.writeAll(", ");
305 switch (mod.intern_pool.indexToKey(ty.toIntern())) {305 if (switch (mod.intern_pool.indexToKey(ty.toIntern())) {
306 .struct_type, .anon_struct_type => try writer.print(".{s} = ", .{ty.structFieldName(i, mod)}),306 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[i],
307 else => {},307 .anon_struct_type => |anon_struct_type| if (anon_struct_type.isTuple())
308 }308 null
309 else
310 mod.intern_pool.stringToSlice(anon_struct_type.names[i]),
311 else => unreachable,
312 }) |field_name| try writer.print(".{s} = ", .{field_name});
309 try print(.{313 try print(.{
310 .ty = ty.structFieldType(i, mod),314 .ty = ty.structFieldType(i, mod),
311 .val = try val.fieldValue(mod, i),315 .val = try val.fieldValue(mod, i),
src/arch/aarch64/CodeGen.zig+1-1
...@@ -4527,7 +4527,7 @@ fn cmp(...@@ -4527,7 +4527,7 @@ fn cmp(
4527 }4527 }
4528 },4528 },
4529 .Float => return self.fail("TODO ARM cmp floats", .{}),4529 .Float => return self.fail("TODO ARM cmp floats", .{}),
4530 .Enum => try lhs_ty.intTagType(mod),4530 .Enum => lhs_ty.intTagType(mod),
4531 .Int => lhs_ty,4531 .Int => lhs_ty,
4532 .Bool => Type.u1,4532 .Bool => Type.u1,
4533 .Pointer => Type.usize,4533 .Pointer => Type.usize,
src/arch/arm/CodeGen.zig+1-1
...@@ -4475,7 +4475,7 @@ fn cmp(...@@ -4475,7 +4475,7 @@ fn cmp(
4475 }4475 }
4476 },4476 },
4477 .Float => return self.fail("TODO ARM cmp floats", .{}),4477 .Float => return self.fail("TODO ARM cmp floats", .{}),
4478 .Enum => try lhs_ty.intTagType(mod),4478 .Enum => lhs_ty.intTagType(mod),
4479 .Int => lhs_ty,4479 .Int => lhs_ty,
4480 .Bool => Type.u1,4480 .Bool => Type.u1,
4481 .Pointer => Type.usize,4481 .Pointer => Type.usize,
src/arch/sparc64/CodeGen.zig+1-1
...@@ -1435,7 +1435,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1435,7 +1435,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14351435
1436 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {1436 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
1437 .Vector => unreachable, // Handled by cmp_vector.1437 .Vector => unreachable, // Handled by cmp_vector.
1438 .Enum => try lhs_ty.intTagType(mod),1438 .Enum => lhs_ty.intTagType(mod),
1439 .Int => lhs_ty,1439 .Int => lhs_ty,
1440 .Bool => Type.u1,1440 .Bool => Type.u1,
1441 .Pointer => Type.usize,1441 .Pointer => Type.usize,
src/arch/wasm/CodeGen.zig+1-1
...@@ -6883,7 +6883,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6883,7 +6883,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6883 return loc.index;6883 return loc.index;
6884 }6884 }
68856885
6886 const int_tag_ty = try enum_ty.intTagType(mod);6886 const int_tag_ty = enum_ty.intTagType(mod);
68876887
6888 if (int_tag_ty.bitSize(mod) > 64) {6888 if (int_tag_ty.bitSize(mod) > 64) {
6889 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});6889 return func.fail("TODO: Implement @tagName for enums with tag size larger than 64 bits", .{});
src/codegen.zig+1-1
...@@ -312,7 +312,7 @@ pub fn generateSymbol(...@@ -312,7 +312,7 @@ pub fn generateSymbol(
312 }312 }
313 },313 },
314 .enum_tag => |enum_tag| {314 .enum_tag => |enum_tag| {
315 const int_tag_ty = try typed_value.ty.intTagType(mod);315 const int_tag_ty = typed_value.ty.intTagType(mod);
316 switch (try generateSymbol(bin_file, src_loc, .{316 switch (try generateSymbol(bin_file, src_loc, .{
317 .ty = int_tag_ty,317 .ty = int_tag_ty,
318 .val = try mod.getCoerced(enum_tag.int.toValue(), int_tag_ty),318 .val = try mod.getCoerced(enum_tag.int.toValue(), int_tag_ty),
src/codegen/llvm.zig+3-5
...@@ -2773,7 +2773,7 @@ pub const DeclGen = struct {...@@ -2773,7 +2773,7 @@ pub const DeclGen = struct {
2773 return dg.context.intType(info.bits);2773 return dg.context.intType(info.bits);
2774 },2774 },
2775 .Enum => {2775 .Enum => {
2776 const int_ty = try t.intTagType(mod);2776 const int_ty = t.intTagType(mod);
2777 const bit_count = int_ty.intInfo(mod).bits;2777 const bit_count = int_ty.intInfo(mod).bits;
2778 assert(bit_count != 0);2778 assert(bit_count != 0);
2779 return dg.context.intType(bit_count);2779 return dg.context.intType(bit_count);
...@@ -4148,9 +4148,7 @@ pub const DeclGen = struct {...@@ -4148,9 +4148,7 @@ pub const DeclGen = struct {
4148 const mod = dg.module;4148 const mod = dg.module;
4149 const int_ty = switch (ty.zigTypeTag(mod)) {4149 const int_ty = switch (ty.zigTypeTag(mod)) {
4150 .Int => ty,4150 .Int => ty,
4151 .Enum => ty.intTagType(mod) catch |err| switch (err) {4151 .Enum => ty.intTagType(mod),
4152 error.OutOfMemory => @panic("OOM"),
4153 },
4154 .Float => {4152 .Float => {
4155 if (!is_rmw_xchg) return null;4153 if (!is_rmw_xchg) return null;
4156 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));4154 return dg.context.intType(@intCast(c_uint, ty.abiSize(mod) * 8));
...@@ -5100,7 +5098,7 @@ pub const FuncGen = struct {...@@ -5100,7 +5098,7 @@ pub const FuncGen = struct {
5100 const mod = self.dg.module;5098 const mod = self.dg.module;
5101 const scalar_ty = operand_ty.scalarType(mod);5099 const scalar_ty = operand_ty.scalarType(mod);
5102 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {5100 const int_ty = switch (scalar_ty.zigTypeTag(mod)) {
5103 .Enum => try scalar_ty.intTagType(mod),5101 .Enum => scalar_ty.intTagType(mod),
5104 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,5102 .Int, .Bool, .Pointer, .ErrorSet => scalar_ty,
5105 .Optional => blk: {5103 .Optional => blk: {
5106 const payload_ty = operand_ty.optionalChild(mod);5104 const payload_ty = operand_ty.optionalChild(mod);
src/codegen/spirv.zig+3-3
...@@ -700,7 +700,7 @@ pub const DeclGen = struct {...@@ -700,7 +700,7 @@ pub const DeclGen = struct {
700 .enum_tag => {700 .enum_tag => {
701 const int_val = try val.enumToInt(ty, mod);701 const int_val = try val.enumToInt(ty, mod);
702702
703 const int_ty = try ty.intTagType(mod);703 const int_ty = ty.intTagType(mod);
704704
705 try self.lower(int_ty, int_val);705 try self.lower(int_ty, int_val);
706 },706 },
...@@ -1156,7 +1156,7 @@ pub const DeclGen = struct {...@@ -1156,7 +1156,7 @@ pub const DeclGen = struct {
1156 return try self.intType(int_info.signedness, int_info.bits);1156 return try self.intType(int_info.signedness, int_info.bits);
1157 },1157 },
1158 .Enum => {1158 .Enum => {
1159 const tag_ty = try ty.intTagType(mod);1159 const tag_ty = ty.intTagType(mod);
1160 return self.resolveType(tag_ty, repr);1160 return self.resolveType(tag_ty, repr);
1161 },1161 },
1162 .Float => {1162 .Float => {
...@@ -3053,7 +3053,7 @@ pub const DeclGen = struct {...@@ -3053,7 +3053,7 @@ pub const DeclGen = struct {
3053 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;3053 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
3054 },3054 },
3055 .Enum => blk: {3055 .Enum => blk: {
3056 const int_ty = try cond_ty.intTagType(mod);3056 const int_ty = cond_ty.intTagType(mod);
3057 const int_info = int_ty.intInfo(mod);3057 const int_info = int_ty.intInfo(mod);
3058 const backing_bits = self.backingIntBits(int_info.bits) orelse {3058 const backing_bits = self.backingIntBits(int_info.bits) orelse {
3059 return self.todo("implement composite int switch", .{});3059 return self.todo("implement composite int switch", .{});
src/type.zig+28-26
...@@ -1842,17 +1842,15 @@ pub const Type = struct {...@@ -1842,17 +1842,15 @@ pub const Type = struct {
1842 /// See also `isPtrLikeOptional`.1842 /// See also `isPtrLikeOptional`.
1843 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {1843 pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
1844 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {1844 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
1845 .opt_type => |child| switch (child.toType().zigTypeTag(mod)) {1845 .opt_type => |child_type| switch (mod.intern_pool.indexToKey(child_type)) {
1846 .Pointer => {1846 .ptr_type => |ptr_type| switch (ptr_type.size) {
1847 const info = child.toType().ptrInfo(mod);1847 .C => false,
1848 return switch (info.size) {1848 .Slice, .Many, .One => !ptr_type.is_allowzero,
1849 .C => false,
1850 else => !info.@"allowzero",
1851 };
1852 },1849 },
1853 .ErrorSet => true,1850 .error_set_type => true,
1854 else => false,1851 else => false,
1855 },1852 },
1853 .ptr_type => |ptr_type| ptr_type.size == .C,
1856 else => false,1854 else => false,
1857 };1855 };
1858 }1856 }
...@@ -2570,23 +2568,27 @@ pub const Type = struct {...@@ -2570,23 +2568,27 @@ pub const Type = struct {
25702568
2571 return null;2569 return null;
2572 },2570 },
2573 .auto, .explicit => switch (enum_type.names.len) {2571 .auto, .explicit => {
2574 0 => return Value.@"unreachable",2572 if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null;
2575 1 => {2573
2576 if (enum_type.values.len == 0) {2574 switch (enum_type.names.len) {
2577 const only = try mod.intern(.{ .enum_tag = .{2575 0 => return Value.@"unreachable",
2578 .ty = ty.toIntern(),2576 1 => {
2579 .int = try mod.intern(.{ .int = .{2577 if (enum_type.values.len == 0) {
2580 .ty = enum_type.tag_ty,2578 const only = try mod.intern(.{ .enum_tag = .{
2581 .storage = .{ .u64 = 0 },2579 .ty = ty.toIntern(),
2582 } }),2580 .int = try mod.intern(.{ .int = .{
2583 } });2581 .ty = enum_type.tag_ty,
2584 return only.toValue();2582 .storage = .{ .u64 = 0 },
2585 } else {2583 } }),
2586 return enum_type.values[0].toValue();2584 } });
2587 }2585 return only.toValue();
2588 },2586 } else {
2589 else => return null,2587 return enum_type.values[0].toValue();
2588 }
2589 },
2590 else => return null,
2591 }
2590 },2592 },
2591 },2593 },
25922594
...@@ -2887,7 +2889,7 @@ pub const Type = struct {...@@ -2887,7 +2889,7 @@ pub const Type = struct {
2887 }2889 }
28882890
2889 /// Asserts the type is an enum or a union.2891 /// Asserts the type is an enum or a union.
2890 pub fn intTagType(ty: Type, mod: *Module) !Type {2892 pub fn intTagType(ty: Type, mod: *Module) Type {
2891 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {2893 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
2892 .union_type => |union_type| mod.unionPtr(union_type.index).tag_ty.intTagType(mod),2894 .union_type => |union_type| mod.unionPtr(union_type.index).tag_ty.intTagType(mod),
2893 .enum_type => |enum_type| enum_type.tag_ty.toType(),2895 .enum_type => |enum_type| enum_type.tag_ty.toType(),
src/value.zig+21-12
...@@ -673,7 +673,7 @@ pub const Value = struct {...@@ -673,7 +673,7 @@ pub const Value = struct {
673 while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) {673 while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) {
674 .ptr => |ptr| switch (ptr.addr) {674 .ptr => |ptr| switch (ptr.addr) {
675 .decl, .mut_decl, .comptime_field => return true,675 .decl, .mut_decl, .comptime_field => return true,
676 .eu_payload, .opt_payload => |index| check = index.toValue(),676 .eu_payload, .opt_payload => |base| check = base.toValue(),
677 .elem, .field => |base_index| check = base_index.base.toValue(),677 .elem, .field => |base_index| check = base_index.base.toValue(),
678 else => return false,678 else => return false,
679 },679 },
...@@ -943,22 +943,27 @@ pub const Value = struct {...@@ -943,22 +943,27 @@ pub const Value = struct {
943 return Value.true;943 return Value.true;
944 }944 }
945 },945 },
946 .Int, .Enum => {946 .Int, .Enum => |ty_tag| {
947 const int_info = ty.intInfo(mod);947 const int_ty = switch (ty_tag) {
948 .Int => ty,
949 .Enum => ty.intTagType(mod),
950 else => unreachable,
951 };
952 const int_info = int_ty.intInfo(mod);
948 const bits = int_info.bits;953 const bits = int_info.bits;
949 const byte_count = (bits + 7) / 8;954 const byte_count = (bits + 7) / 8;
950 if (bits == 0 or buffer.len == 0) return mod.intValue(ty, 0);955 if (bits == 0 or buffer.len == 0) return mod.getCoerced(try mod.intValue(int_ty, 0), ty);
951956
952 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64957 if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64
953 .signed => {958 .signed => {
954 const val = std.mem.readVarInt(i64, buffer[0..byte_count], endian);959 const val = std.mem.readVarInt(i64, buffer[0..byte_count], endian);
955 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);960 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);
956 return mod.intValue(ty, result);961 return mod.getCoerced(try mod.intValue(int_ty, result), ty);
957 },962 },
958 .unsigned => {963 .unsigned => {
959 const val = std.mem.readVarInt(u64, buffer[0..byte_count], endian);964 const val = std.mem.readVarInt(u64, buffer[0..byte_count], endian);
960 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);965 const result = (val << @intCast(u6, 64 - bits)) >> @intCast(u6, 64 - bits);
961 return mod.intValue(ty, result);966 return mod.getCoerced(try mod.intValue(int_ty, result), ty);
962 },967 },
963 } else { // Slow path, we have to construct a big-int968 } else { // Slow path, we have to construct a big-int
964 const Limb = std.math.big.Limb;969 const Limb = std.math.big.Limb;
...@@ -967,7 +972,7 @@ pub const Value = struct {...@@ -967,7 +972,7 @@ pub const Value = struct {
967972
968 var bigint = BigIntMutable.init(limbs_buffer, 0);973 var bigint = BigIntMutable.init(limbs_buffer, 0);
969 bigint.readTwosComplement(buffer[0..byte_count], bits, endian, int_info.signedness);974 bigint.readTwosComplement(buffer[0..byte_count], bits, endian, int_info.signedness);
970 return mod.intValue_big(ty, bigint.toConst());975 return mod.getCoerced(try mod.intValue_big(int_ty, bigint.toConst()), ty);
971 }976 }
972 },977 },
973 .Float => return (try mod.intern(.{ .float = .{978 .Float => return (try mod.intern(.{ .float = .{
...@@ -1583,7 +1588,7 @@ pub const Value = struct {...@@ -1583,7 +1588,7 @@ pub const Value = struct {
1583 .Enum => {1588 .Enum => {
1584 const a_val = try a.enumToInt(ty, mod);1589 const a_val = try a.enumToInt(ty, mod);
1585 const b_val = try b.enumToInt(ty, mod);1590 const b_val = try b.enumToInt(ty, mod);
1586 const int_ty = try ty.intTagType(mod);1591 const int_ty = ty.intTagType(mod);
1587 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);1592 return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema);
1588 },1593 },
1589 .Array, .Vector => {1594 .Array, .Vector => {
...@@ -1835,7 +1840,8 @@ pub const Value = struct {...@@ -1835,7 +1840,8 @@ pub const Value = struct {
1835 })).toValue(),1840 })).toValue(),
1836 .ptr => |ptr| switch (ptr.addr) {1841 .ptr => |ptr| switch (ptr.addr) {
1837 .decl => |decl| mod.declPtr(decl).val.elemValue(mod, index),1842 .decl => |decl| mod.declPtr(decl).val.elemValue(mod, index),
1838 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).val.elemValue(mod, index),1843 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod))
1844 .toValue().elemValue(mod, index),
1839 .int, .eu_payload, .opt_payload => unreachable,1845 .int, .eu_payload, .opt_payload => unreachable,
1840 .comptime_field => |field_val| field_val.toValue().elemValue(mod, index),1846 .comptime_field => |field_val| field_val.toValue().elemValue(mod, index),
1841 .elem => |elem| elem.base.toValue().elemValue(mod, index + elem.index),1847 .elem => |elem| elem.base.toValue().elemValue(mod, index + elem.index),
...@@ -1946,9 +1952,12 @@ pub const Value = struct {...@@ -1946,9 +1952,12 @@ pub const Value = struct {
1946 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1952 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1947 .ptr => |ptr| switch (ptr.addr) {1953 .ptr => |ptr| switch (ptr.addr) {
1948 .decl => |decl| try mod.declPtr(decl).val.sliceArray(mod, arena, start, end),1954 .decl => |decl| try mod.declPtr(decl).val.sliceArray(mod, arena, start, end),
1949 .mut_decl => |mut_decl| try mod.declPtr(mut_decl.decl).val.sliceArray(mod, arena, start, end),1955 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod)).toValue()
1950 .comptime_field => |comptime_field| try comptime_field.toValue().sliceArray(mod, arena, start, end),1956 .sliceArray(mod, arena, start, end),
1951 .elem => |elem| try elem.base.toValue().sliceArray(mod, arena, start + elem.index, end + elem.index),1957 .comptime_field => |comptime_field| comptime_field.toValue()
1958 .sliceArray(mod, arena, start, end),
1959 .elem => |elem| elem.base.toValue()
1960 .sliceArray(mod, arena, start + elem.index, end + elem.index),
1952 else => unreachable,1961 else => unreachable,
1953 },1962 },
1954 .aggregate => |aggregate| (try mod.intern(.{ .aggregate = .{1963 .aggregate => |aggregate| (try mod.intern(.{ .aggregate = .{