| author | |
| committer | |
| log | a5fb16959423005de999fb541d5d5e9aebb8e09e |
| tree | 87d4217e104cb9a1902ee34fb09a19fa5e583c96 |
| parent | 8699cdc3dfcf3a3a6f09a64ea9c67be2459e1240 |
6 files changed, 92 insertions(+), 68 deletions(-)
src/Sema.zig+32-32| ... | @@ -1746,8 +1746,9 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { | ... | @@ -1746,8 +1746,9 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { |
| 1746 | if (i < InternPool.static_len) return @intToEnum(Air.Inst.Ref, i); | 1746 | if (i < InternPool.static_len) return @intToEnum(Air.Inst.Ref, i); |
| 1747 | // The last section of indexes refers to the map of ZIR => AIR. | 1747 | // The last section of indexes refers to the map of ZIR => AIR. |
| 1748 | const inst = sema.inst_map.get(i - InternPool.static_len).?; | 1748 | const inst = sema.inst_map.get(i - InternPool.static_len).?; |
| 1749 | if (inst == .generic_poison) return error.GenericPoison; | ||
| 1749 | const ty = sema.typeOf(inst); | 1750 | const ty = sema.typeOf(inst); |
| 1750 | if (ty.isGenericPoison()) return error.GenericPoison; | 1751 | assert(!ty.isGenericPoison()); |
| 1751 | return inst; | 1752 | return inst; |
| 1752 | } | 1753 | } |
| 1753 | 1754 | ||
| ... | @@ -2000,7 +2001,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime( | ... | @@ -2000,7 +2001,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime( |
| 2000 | .constant => { | 2001 | .constant => { |
| 2001 | const ty_pl = air_datas[i].ty_pl; | 2002 | const ty_pl = air_datas[i].ty_pl; |
| 2002 | const val = sema.air_values.items[ty_pl.payload]; | 2003 | const val = sema.air_values.items[ty_pl.payload]; |
| 2003 | if (val.tag() == .runtime_value) make_runtime.* = true; | 2004 | if (val.isRuntimeValue()) make_runtime.* = true; |
| 2004 | if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true; | 2005 | if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true; |
| 2005 | return val; | 2006 | return val; |
| 2006 | }, | 2007 | }, |
| ... | @@ -9688,7 +9689,7 @@ fn intCast( | ... | @@ -9688,7 +9689,7 @@ fn intCast( |
| 9688 | // range shrinkage | 9689 | // range shrinkage |
| 9689 | // requirement: int value fits into target type | 9690 | // requirement: int value fits into target type |
| 9690 | if (wanted_value_bits < actual_value_bits) { | 9691 | if (wanted_value_bits < actual_value_bits) { |
| 9691 | const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod); | 9692 | const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_ty); |
| 9692 | const dest_max_val = if (is_vector) | 9693 | const dest_max_val = if (is_vector) |
| 9693 | try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar) | 9694 | try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar) |
| 9694 | else | 9695 | else |
| ... | @@ -10831,7 +10832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10831,7 +10832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10831 | defer arena.deinit(); | 10832 | defer arena.deinit(); |
| 10832 | 10833 | ||
| 10833 | const min_int = try operand_ty.minInt(arena.allocator(), mod); | 10834 | const min_int = try operand_ty.minInt(arena.allocator(), mod); |
| 10834 | const max_int = try operand_ty.maxIntScalar(mod); | 10835 | const max_int = try operand_ty.maxIntScalar(mod, Type.comptime_int); |
| 10835 | if (try range_set.spans(min_int, max_int, operand_ty)) { | 10836 | if (try range_set.spans(min_int, max_int, operand_ty)) { |
| 10836 | if (special_prong == .@"else") { | 10837 | if (special_prong == .@"else") { |
| 10837 | return sema.fail( | 10838 | return sema.fail( |
| ... | @@ -11683,7 +11684,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -11683,7 +11684,7 @@ const RangeSetUnhandledIterator = struct { |
| 11683 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { | 11684 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { |
| 11684 | const mod = sema.mod; | 11685 | const mod = sema.mod; |
| 11685 | const min = try ty.minInt(sema.arena, mod); | 11686 | const min = try ty.minInt(sema.arena, mod); |
| 11686 | const max = try ty.maxIntScalar(mod); | 11687 | const max = try ty.maxIntScalar(mod, Type.comptime_int); |
| 11687 | 11688 | ||
| 11688 | return RangeSetUnhandledIterator{ | 11689 | return RangeSetUnhandledIterator{ |
| 11689 | .sema = sema, | 11690 | .sema = sema, |
| ... | @@ -12294,7 +12295,7 @@ fn zirShl( | ... | @@ -12294,7 +12295,7 @@ fn zirShl( |
| 12294 | { | 12295 | { |
| 12295 | const max_int = try sema.addConstant( | 12296 | const max_int = try sema.addConstant( |
| 12296 | lhs_ty, | 12297 | lhs_ty, |
| 12297 | try lhs_ty.maxInt(sema.arena, mod), | 12298 | try lhs_ty.maxInt(sema.arena, mod, lhs_ty), |
| 12298 | ); | 12299 | ); |
| 12299 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src }); | 12300 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src }); |
| 12300 | break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false); | 12301 | break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false); |
| ... | @@ -16503,7 +16504,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16503,7 +16504,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16503 | else | 16504 | else |
| 16504 | try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); | 16505 | try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); |
| 16505 | const new_decl = try anon_decl.finish( | 16506 | const new_decl = try anon_decl.finish( |
| 16506 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), | 16507 | try Type.array(anon_decl.arena(), bytes.len, Value.zero_u8, Type.u8, mod), |
| 16507 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16508 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16508 | 0, // default alignment | 16509 | 0, // default alignment |
| 16509 | ); | 16510 | ); |
| ... | @@ -22202,8 +22203,8 @@ fn analyzeMinMax( | ... | @@ -22202,8 +22203,8 @@ fn analyzeMinMax( |
| 22202 | else => unreachable, | 22203 | else => unreachable, |
| 22203 | }; | 22204 | }; |
| 22204 | const max_val = switch (air_tag) { | 22205 | const max_val = switch (air_tag) { |
| 22205 | .min => try comptime_elem_ty.maxInt(sema.arena, mod), // @min(ct, rt) <= ct | 22206 | .min => try comptime_elem_ty.maxInt(sema.arena, mod, Type.comptime_int), // @min(ct, rt) <= ct |
| 22206 | .max => try unrefined_elem_ty.maxInt(sema.arena, mod), | 22207 | .max => try unrefined_elem_ty.maxInt(sema.arena, mod, Type.comptime_int), |
| 22207 | else => unreachable, | 22208 | else => unreachable, |
| 22208 | }; | 22209 | }; |
| 22209 | 22210 | ||
| ... | @@ -27931,33 +27932,32 @@ fn beginComptimePtrMutation( | ... | @@ -27931,33 +27932,32 @@ fn beginComptimePtrMutation( |
| 27931 | switch (parent.pointee) { | 27932 | switch (parent.pointee) { |
| 27932 | .direct => |val_ptr| { | 27933 | .direct => |val_ptr| { |
| 27933 | const payload_ty = parent.ty.errorUnionPayload(); | 27934 | const payload_ty = parent.ty.errorUnionPayload(); |
| 27934 | switch (val_ptr.tag()) { | 27935 | if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) { |
| 27935 | else => { | 27936 | return ComptimePtrMutationKit{ |
| 27936 | // An error union has been initialized to undefined at comptime and now we | 27937 | .decl_ref_mut = parent.decl_ref_mut, |
| 27937 | // are for the first time setting the payload. We must change the | 27938 | .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data }, |
| 27938 | // representation of the error union from `undef` to `opt_payload`. | 27939 | .ty = payload_ty, |
| 27939 | const arena = parent.beginArena(sema.mod); | 27940 | }; |
| 27940 | defer parent.finishArena(sema.mod); | 27941 | } else { |
| 27942 | // An error union has been initialized to undefined at comptime and now we | ||
| 27943 | // are for the first time setting the payload. We must change the | ||
| 27944 | // representation of the error union from `undef` to `opt_payload`. | ||
| 27945 | const arena = parent.beginArena(sema.mod); | ||
| 27946 | defer parent.finishArena(sema.mod); | ||
| 27941 | 27947 | ||
| 27942 | const payload = try arena.create(Value.Payload.SubValue); | 27948 | const payload = try arena.create(Value.Payload.SubValue); |
| 27943 | payload.* = .{ | 27949 | payload.* = .{ |
| 27944 | .base = .{ .tag = .eu_payload }, | 27950 | .base = .{ .tag = .eu_payload }, |
| 27945 | .data = Value.undef, | 27951 | .data = Value.undef, |
| 27946 | }; | 27952 | }; |
| 27947 | 27953 | ||
| 27948 | val_ptr.* = Value.initPayload(&payload.base); | 27954 | val_ptr.* = Value.initPayload(&payload.base); |
| 27949 | 27955 | ||
| 27950 | return ComptimePtrMutationKit{ | 27956 | return ComptimePtrMutationKit{ |
| 27951 | .decl_ref_mut = parent.decl_ref_mut, | ||
| 27952 | .pointee = .{ .direct = &payload.data }, | ||
| 27953 | .ty = payload_ty, | ||
| 27954 | }; | ||
| 27955 | }, | ||
| 27956 | .eu_payload => return ComptimePtrMutationKit{ | ||
| 27957 | .decl_ref_mut = parent.decl_ref_mut, | 27957 | .decl_ref_mut = parent.decl_ref_mut, |
| 27958 | .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data }, | 27958 | .pointee = .{ .direct = &payload.data }, |
| 27959 | .ty = payload_ty, | 27959 | .ty = payload_ty, |
| 27960 | }, | 27960 | }; |
| 27961 | } | 27961 | } |
| 27962 | }, | 27962 | }, |
| 27963 | .bad_decl_ty, .bad_ptr_ty => return parent, | 27963 | .bad_decl_ty, .bad_ptr_ty => return parent, |
| ... | @@ -33225,7 +33225,7 @@ fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { | ... | @@ -33225,7 +33225,7 @@ fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { |
| 33225 | 33225 | ||
| 33226 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { | 33226 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |
| 33227 | const gpa = sema.gpa; | 33227 | const gpa = sema.gpa; |
| 33228 | if (val.ip_index != .none) { | 33228 | if (val.ip_index != .none and val.ip_index != .null_value) { |
| 33229 | if (@enumToInt(val.ip_index) < Air.ref_start_index) | 33229 | if (@enumToInt(val.ip_index) < Air.ref_start_index) |
| 33230 | return @intToEnum(Air.Inst.Ref, @enumToInt(val.ip_index)); | 33230 | return @intToEnum(Air.Inst.Ref, @enumToInt(val.ip_index)); |
| 33231 | try sema.air_instructions.append(gpa, .{ | 33231 | try sema.air_instructions.append(gpa, .{ |
src/arch/x86_64/CodeGen.zig+1-1| ... | @@ -4915,7 +4915,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4915,7 +4915,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { |
| 4915 | 4915 | ||
| 4916 | const sign_val = switch (tag) { | 4916 | const sign_val = switch (tag) { |
| 4917 | .neg => try vec_ty.minInt(stack.get(), mod), | 4917 | .neg => try vec_ty.minInt(stack.get(), mod), |
| 4918 | .fabs => try vec_ty.maxInt(stack.get(), mod), | 4918 | .fabs => try vec_ty.maxInt(stack.get(), mod, vec_ty), |
| 4919 | else => unreachable, | 4919 | else => unreachable, |
| 4920 | }; | 4920 | }; |
| 4921 | 4921 |
src/codegen/c.zig+4-4| ... | @@ -3542,7 +3542,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3542,7 +3542,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3542 | try v.elem(f, writer); | 3542 | try v.elem(f, writer); |
| 3543 | } else switch (dest_int_info.signedness) { | 3543 | } else switch (dest_int_info.signedness) { |
| 3544 | .unsigned => { | 3544 | .unsigned => { |
| 3545 | const mask_val = try inst_scalar_ty.maxIntScalar(mod); | 3545 | const mask_val = try inst_scalar_ty.maxIntScalar(mod, scalar_ty); |
| 3546 | try writer.writeAll("zig_and_"); | 3546 | try writer.writeAll("zig_and_"); |
| 3547 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | 3547 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); |
| 3548 | try writer.writeByte('('); | 3548 | try writer.writeByte('('); |
| ... | @@ -6681,13 +6681,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6681,13 +6681,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6681 | .And => switch (scalar_ty.zigTypeTag(mod)) { | 6681 | .And => switch (scalar_ty.zigTypeTag(mod)) { |
| 6682 | .Bool => try mod.intValue(Type.comptime_int, 1), | 6682 | .Bool => try mod.intValue(Type.comptime_int, 1), |
| 6683 | else => switch (scalar_ty.intInfo(mod).signedness) { | 6683 | else => switch (scalar_ty.intInfo(mod).signedness) { |
| 6684 | .unsigned => try scalar_ty.maxIntScalar(mod), | 6684 | .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty), |
| 6685 | .signed => try mod.intValue(scalar_ty, -1), | 6685 | .signed => try mod.intValue(scalar_ty, -1), |
| 6686 | }, | 6686 | }, |
| 6687 | }, | 6687 | }, |
| 6688 | .Min => switch (scalar_ty.zigTypeTag(mod)) { | 6688 | .Min => switch (scalar_ty.zigTypeTag(mod)) { |
| 6689 | .Bool => try mod.intValue(Type.comptime_int, 1), | 6689 | .Bool => Value.one_comptime_int, |
| 6690 | .Int => try scalar_ty.maxIntScalar(mod), | 6690 | .Int => try scalar_ty.maxIntScalar(mod, scalar_ty), |
| 6691 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | 6691 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), |
| 6692 | else => unreachable, | 6692 | else => unreachable, |
| 6693 | }, | 6693 | }, |
src/codegen/llvm.zig+17-11| ... | @@ -3570,15 +3570,21 @@ pub const DeclGen = struct { | ... | @@ -3570,15 +3570,21 @@ pub const DeclGen = struct { |
| 3570 | }, | 3570 | }, |
| 3571 | .ErrorSet => { | 3571 | .ErrorSet => { |
| 3572 | const llvm_ty = try dg.lowerType(Type.anyerror); | 3572 | const llvm_ty = try dg.lowerType(Type.anyerror); |
| 3573 | switch (tv.val.tag()) { | 3573 | switch (tv.val.ip_index) { |
| 3574 | .@"error" => { | 3574 | .none => switch (tv.val.tag()) { |
| 3575 | const err_name = tv.val.castTag(.@"error").?.data.name; | 3575 | .@"error" => { |
| 3576 | const kv = try dg.module.getErrorValue(err_name); | 3576 | const err_name = tv.val.castTag(.@"error").?.data.name; |
| 3577 | return llvm_ty.constInt(kv.value, .False); | 3577 | const kv = try dg.module.getErrorValue(err_name); |
| 3578 | return llvm_ty.constInt(kv.value, .False); | ||
| 3579 | }, | ||
| 3580 | else => { | ||
| 3581 | // In this case we are rendering an error union which has a 0 bits payload. | ||
| 3582 | return llvm_ty.constNull(); | ||
| 3583 | }, | ||
| 3578 | }, | 3584 | }, |
| 3579 | else => { | 3585 | else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { |
| 3580 | // In this case we are rendering an error union which has a 0 bits payload. | 3586 | .int => |int| return llvm_ty.constInt(int.storage.u64, .False), |
| 3581 | return llvm_ty.constNull(); | 3587 | else => unreachable, |
| 3582 | }, | 3588 | }, |
| 3583 | } | 3589 | } |
| 3584 | }, | 3590 | }, |
| ... | @@ -3588,7 +3594,7 @@ pub const DeclGen = struct { | ... | @@ -3588,7 +3594,7 @@ pub const DeclGen = struct { |
| 3588 | 3594 | ||
| 3589 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3595 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3590 | // We use the error type directly as the type. | 3596 | // We use the error type directly as the type. |
| 3591 | const err_val = if (!is_pl) tv.val else try mod.intValue(Type.anyerror, 0); | 3597 | const err_val = if (!is_pl) tv.val else try mod.intValue(Type.err_int, 0); |
| 3592 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); | 3598 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); |
| 3593 | } | 3599 | } |
| 3594 | 3600 | ||
| ... | @@ -3596,7 +3602,7 @@ pub const DeclGen = struct { | ... | @@ -3596,7 +3602,7 @@ pub const DeclGen = struct { |
| 3596 | const error_align = Type.anyerror.abiAlignment(mod); | 3602 | const error_align = Type.anyerror.abiAlignment(mod); |
| 3597 | const llvm_error_value = try dg.lowerValue(.{ | 3603 | const llvm_error_value = try dg.lowerValue(.{ |
| 3598 | .ty = Type.anyerror, | 3604 | .ty = Type.anyerror, |
| 3599 | .val = if (is_pl) try mod.intValue(Type.anyerror, 0) else tv.val, | 3605 | .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val, |
| 3600 | }); | 3606 | }); |
| 3601 | const llvm_payload_value = try dg.lowerValue(.{ | 3607 | const llvm_payload_value = try dg.lowerValue(.{ |
| 3602 | .ty = payload_type, | 3608 | .ty = payload_type, |
| ... | @@ -6873,7 +6879,7 @@ pub const FuncGen = struct { | ... | @@ -6873,7 +6879,7 @@ pub const FuncGen = struct { |
| 6873 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); | 6879 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); |
| 6874 | 6880 | ||
| 6875 | const payload_ty = err_union_ty.errorUnionPayload(); | 6881 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 6876 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.anyerror, 0) }); | 6882 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) }); |
| 6877 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6883 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6878 | _ = self.builder.buildStore(non_error_val, operand); | 6884 | _ = self.builder.buildStore(non_error_val, operand); |
| 6879 | return operand; | 6885 | return operand; |
src/type.zig+29-19| ... | @@ -4382,8 +4382,9 @@ pub const Type = struct { | ... | @@ -4382,8 +4382,9 @@ pub const Type = struct { |
| 4382 | } | 4382 | } |
| 4383 | 4383 | ||
| 4384 | // Works for vectors and vectors of integers. | 4384 | // Works for vectors and vectors of integers. |
| 4385 | pub fn maxInt(ty: Type, arena: Allocator, mod: *Module) !Value { | 4385 | /// The returned Value will have type dest_ty. |
| 4386 | const scalar = try maxIntScalar(ty.scalarType(mod), mod); | 4386 | pub fn maxInt(ty: Type, arena: Allocator, mod: *Module, dest_ty: Type) !Value { |
| 4387 | const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty); | ||
| 4387 | if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) { | 4388 | if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) { |
| 4388 | return Value.Tag.repeated.create(arena, scalar); | 4389 | return Value.Tag.repeated.create(arena, scalar); |
| 4389 | } else { | 4390 | } else { |
| ... | @@ -4391,18 +4392,18 @@ pub const Type = struct { | ... | @@ -4391,18 +4392,18 @@ pub const Type = struct { |
| 4391 | } | 4392 | } |
| 4392 | } | 4393 | } |
| 4393 | 4394 | ||
| 4394 | /// Asserts that the type is an integer. | 4395 | /// The returned Value will have type dest_ty. |
| 4395 | pub fn maxIntScalar(ty: Type, mod: *Module) !Value { | 4396 | pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value { |
| 4396 | const info = ty.intInfo(mod); | 4397 | const info = ty.intInfo(mod); |
| 4397 | 4398 | ||
| 4398 | switch (info.bits) { | 4399 | switch (info.bits) { |
| 4399 | 0 => return switch (info.signedness) { | 4400 | 0 => return switch (info.signedness) { |
| 4400 | .signed => mod.intValue(ty, -1), | 4401 | .signed => try mod.intValue(dest_ty, -1), |
| 4401 | .unsigned => mod.intValue(ty, 0), | 4402 | .unsigned => try mod.intValue(dest_ty, 0), |
| 4402 | }, | 4403 | }, |
| 4403 | 1 => return switch (info.signedness) { | 4404 | 1 => return switch (info.signedness) { |
| 4404 | .signed => mod.intValue(ty, 0), | 4405 | .signed => try mod.intValue(dest_ty, 0), |
| 4405 | .unsigned => mod.intValue(ty, 0), | 4406 | .unsigned => try mod.intValue(dest_ty, 1), |
| 4406 | }, | 4407 | }, |
| 4407 | else => {}, | 4408 | else => {}, |
| 4408 | } | 4409 | } |
| ... | @@ -4410,11 +4411,11 @@ pub const Type = struct { | ... | @@ -4410,11 +4411,11 @@ pub const Type = struct { |
| 4410 | if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) { | 4411 | if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) { |
| 4411 | .signed => { | 4412 | .signed => { |
| 4412 | const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift); | 4413 | const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift); |
| 4413 | return mod.intValue(Type.comptime_int, n); | 4414 | return mod.intValue(dest_ty, n); |
| 4414 | }, | 4415 | }, |
| 4415 | .unsigned => { | 4416 | .unsigned => { |
| 4416 | const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift); | 4417 | const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift); |
| 4417 | return mod.intValue(Type.comptime_int, n); | 4418 | return mod.intValue(dest_ty, n); |
| 4418 | }, | 4419 | }, |
| 4419 | }; | 4420 | }; |
| 4420 | 4421 | ||
| ... | @@ -4423,7 +4424,7 @@ pub const Type = struct { | ... | @@ -4423,7 +4424,7 @@ pub const Type = struct { |
| 4423 | 4424 | ||
| 4424 | try res.setTwosCompIntLimit(.max, info.signedness, info.bits); | 4425 | try res.setTwosCompIntLimit(.max, info.signedness, info.bits); |
| 4425 | 4426 | ||
| 4426 | return mod.intValue_big(Type.comptime_int, res.toConst()); | 4427 | return mod.intValue_big(dest_ty, res.toConst()); |
| 4427 | } | 4428 | } |
| 4428 | 4429 | ||
| 4429 | /// Asserts the type is an enum or a union. | 4430 | /// Asserts the type is an enum or a union. |
| ... | @@ -5068,6 +5069,7 @@ pub const Type = struct { | ... | @@ -5068,6 +5069,7 @@ pub const Type = struct { |
| 5068 | 5069 | ||
| 5069 | pub fn isSimpleTuple(ty: Type) bool { | 5070 | pub fn isSimpleTuple(ty: Type) bool { |
| 5070 | return switch (ty.ip_index) { | 5071 | return switch (ty.ip_index) { |
| 5072 | .empty_struct => true, | ||
| 5071 | .none => switch (ty.tag()) { | 5073 | .none => switch (ty.tag()) { |
| 5072 | .tuple, .empty_struct_literal => true, | 5074 | .tuple, .empty_struct_literal => true, |
| 5073 | else => false, | 5075 | else => false, |
| ... | @@ -5077,21 +5079,29 @@ pub const Type = struct { | ... | @@ -5077,21 +5079,29 @@ pub const Type = struct { |
| 5077 | } | 5079 | } |
| 5078 | 5080 | ||
| 5079 | pub fn isSimpleTupleOrAnonStruct(ty: Type) bool { | 5081 | pub fn isSimpleTupleOrAnonStruct(ty: Type) bool { |
| 5080 | return switch (ty.tag()) { | 5082 | return switch (ty.ip_index) { |
| 5081 | .tuple, .empty_struct_literal, .anon_struct => true, | 5083 | .empty_struct => true, |
| 5084 | .none => switch (ty.tag()) { | ||
| 5085 | .tuple, .empty_struct_literal, .anon_struct => true, | ||
| 5086 | else => false, | ||
| 5087 | }, | ||
| 5082 | else => false, | 5088 | else => false, |
| 5083 | }; | 5089 | }; |
| 5084 | } | 5090 | } |
| 5085 | 5091 | ||
| 5086 | // Only allowed for simple tuple types | 5092 | // Only allowed for simple tuple types |
| 5087 | pub fn tupleFields(ty: Type) Payload.Tuple.Data { | 5093 | pub fn tupleFields(ty: Type) Payload.Tuple.Data { |
| 5088 | return switch (ty.tag()) { | 5094 | return switch (ty.ip_index) { |
| 5089 | .tuple => ty.castTag(.tuple).?.data, | 5095 | .empty_struct => .{ .types = &.{}, .values = &.{} }, |
| 5090 | .anon_struct => .{ | 5096 | .none => switch (ty.tag()) { |
| 5091 | .types = ty.castTag(.anon_struct).?.data.types, | 5097 | .tuple => ty.castTag(.tuple).?.data, |
| 5092 | .values = ty.castTag(.anon_struct).?.data.values, | 5098 | .anon_struct => .{ |
| 5099 | .types = ty.castTag(.anon_struct).?.data.types, | ||
| 5100 | .values = ty.castTag(.anon_struct).?.data.values, | ||
| 5101 | }, | ||
| 5102 | .empty_struct_literal => .{ .types = &.{}, .values = &.{} }, | ||
| 5103 | else => unreachable, | ||
| 5093 | }, | 5104 | }, |
| 5094 | .empty_struct_literal => .{ .types = &.{}, .values = &.{} }, | ||
| 5095 | else => unreachable, | 5105 | else => unreachable, |
| 5096 | }; | 5106 | }; |
| 5097 | } | 5107 | } |
src/value.zig+9-1| ... | @@ -2625,6 +2625,10 @@ pub const Value = struct { | ... | @@ -2625,6 +2625,10 @@ pub const Value = struct { |
| 2625 | } | 2625 | } |
| 2626 | } | 2626 | } |
| 2627 | 2627 | ||
| 2628 | pub fn isRuntimeValue(val: Value) bool { | ||
| 2629 | return val.ip_index == .none and val.tag() == .runtime_value; | ||
| 2630 | } | ||
| 2631 | |||
| 2628 | pub fn tagIsVariable(val: Value) bool { | 2632 | pub fn tagIsVariable(val: Value) bool { |
| 2629 | return val.ip_index == .none and val.tag() == .variable; | 2633 | return val.ip_index == .none and val.tag() == .variable; |
| 2630 | } | 2634 | } |
| ... | @@ -3402,7 +3406,7 @@ pub const Value = struct { | ... | @@ -3402,7 +3406,7 @@ pub const Value = struct { |
| 3402 | if (lhs.isUndef() or rhs.isUndef()) return Value.undef; | 3406 | if (lhs.isUndef() or rhs.isUndef()) return Value.undef; |
| 3403 | 3407 | ||
| 3404 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); | 3408 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); |
| 3405 | const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod); | 3409 | const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty); |
| 3406 | return bitwiseXor(anded, all_ones, ty, arena, mod); | 3410 | return bitwiseXor(anded, all_ones, ty, arena, mod); |
| 3407 | } | 3411 | } |
| 3408 | 3412 | ||
| ... | @@ -5152,6 +5156,10 @@ pub const Value = struct { | ... | @@ -5152,6 +5156,10 @@ pub const Value = struct { |
| 5152 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; | 5156 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 5153 | 5157 | ||
| 5154 | pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined }; | 5158 | pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined }; |
| 5159 | pub const zero_u8: Value = .{ .ip_index = .zero_u8, .legacy = undefined }; | ||
| 5160 | pub const zero_comptime_int: Value = .{ .ip_index = .zero, .legacy = undefined }; | ||
| 5161 | pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined }; | ||
| 5162 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined }; | ||
| 5155 | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; | 5163 | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; |
| 5156 | pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this! | 5164 | pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this! |
| 5157 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; | 5165 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; |