| author | |
| committer | |
| log | 3064d2aa7b9a8ea836cb70884b0640fe902ecc29 |
| tree | a3e315a06c0912e03ddac6b04cbe23205872bd31 |
| parent | 3b6ca1d35b950d67fff5964f0063dadf01f30e2d |
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 | }, |
| 3132 | 3132 | ||
| 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); |
| 3137 | 3138 | ||
| ... | @@ -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, |
| 3833 | 3832 | ||
| 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 | } |
| 3838 | 3837 | ||
| ... | @@ -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 <=> ptr | 4346 | /// * ptr <=> ptr |
| 4347 | /// * opt ptr <=> ptr | 4347 | /// * opt ptr <=> ptr |
| 4348 | /// * opt ptr <=> opt ptr | 4348 | /// * opt ptr <=> opt ptr |
| 4349 | /// * int => ptr | 4349 | /// * int <=> ptr |
| 4350 | /// * null_value => opt | 4350 | /// * null_value => opt |
| 4351 | /// * payload => opt | 4351 | /// * payload => opt |
| 4352 | /// * error set <=> error set | 4352 | /// * 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 | } |
| 709 | 709 | ||
| 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( |
| 7073 | 7077 | ||
| 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_string | 3291 | 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 AstGen | 3297 | assert(!result.found_existing); // verified in AstGen |
| 3297 | } | 3298 | } |
| ... | @@ -6409,7 +6410,7 @@ fn zirCall( | ... | @@ -6409,7 +6410,7 @@ fn zirCall( |
| 6409 | 6410 | ||
| 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_reason | 6415 | // 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); |
| 7078 | 7079 | ||
| 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); |
| 8269 | 8269 | ||
| 8270 | const int_tag_ty = try enum_tag_ty.intTagType(mod); | 8270 | const int_tag_ty = enum_tag_ty.intTagType(mod); |
| 8271 | 8271 | ||
| 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 |
| 8299 | 8299 | ||
| 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 | } |
| 8341 | 8338 | ||
| 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 shrinkage | 9648 | // range shrinkage |
| 9652 | // requirement: int value fits into target type | 9649 | // 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 | } |
| 12854 | 12851 | ||
| ... | @@ -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").?); |
| 19237 | 19234 | ||
| 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 | } |
| 19348 | 19346 | ||
| 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 | } |
| 20265 | 20263 | ||
| 20266 | return sema.addConstant(dest_ty, val); | 20264 | return sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty)); |
| 20267 | } | 20265 | } |
| 20268 | 20266 | ||
| 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); |
| 20422 | 20420 | ||
| 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 | } |
| 20426 | 20424 | ||
| 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 | } |
| 22390 | 22390 | ||
| 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; |
| 26985 | 26990 | ||
| 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); |
| 26990 | 26998 | ||
| ... | @@ -27009,7 +27017,7 @@ fn coerceInMemoryAllowed( | ... | @@ -27009,7 +27017,7 @@ fn coerceInMemoryAllowed( |
| 27009 | } | 27017 | } |
| 27010 | 27018 | ||
| 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 | } |
| 27033 | 27041 | ||
| 27034 | const dest_tag = dest_ty.zigTypeTag(mod); | ||
| 27035 | const src_tag = src_ty.zigTypeTag(mod); | ||
| 27036 | |||
| 27037 | // Functions | 27042 | // 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 we | 27887 | // An optional has been initialized to undefined at comptime and now we |
| 27869 | // are for the first time setting the payload. We must change the | 27888 | // 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 | }; |
| 27879 | 27898 | ||
| 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 { |
| 33339 | 33340 | ||
| 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 | else | 33350 | .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 | }, |
| 33354 | 33359 | ||
| ... | @@ -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 | } |
| 34555 | 34556 | ||
| 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. |
| 34557 | fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool { | 34558 | fn 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 { |
| 1435 | 1435 | ||
| 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 | } |
| 6885 | 6885 | ||
| 6886 | const int_tag_ty = try enum_ty.intTagType(mod); | 6886 | const int_tag_ty = enum_ty.intTagType(mod); |
| 6887 | 6887 | ||
| 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); |
| 702 | 702 | ||
| 703 | const int_ty = try ty.intTagType(mod); | 703 | const int_ty = ty.intTagType(mod); |
| 704 | 704 | ||
| 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 { |
| 2570 | 2568 | ||
| 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 | }, |
| 2592 | 2594 | ||
| ... | @@ -2887,7 +2889,7 @@ pub const Type = struct { | ... | @@ -2887,7 +2889,7 @@ pub const Type = struct { |
| 2887 | } | 2889 | } |
| 2888 | 2890 | ||
| 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); |
| 951 | 956 | ||
| 952 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 | 957 | 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-int | 968 | } 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 { |
| 967 | 972 | ||
| 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 = .{ |