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