| ... | @@ -17282,12 +17282,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17282,12 +17282,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17282 | for (enum_field_vals, 0..) |*field_val, i| { | 17282 | for (enum_field_vals, 0..) |*field_val, i| { |
| 17283 | const enum_type = ip.indexToKey(ty.toIntern()).enum_type; | 17283 | const enum_type = ip.indexToKey(ty.toIntern()).enum_type; |
| 17284 | const value_val = if (enum_type.values.len > 0) | 17284 | const value_val = if (enum_type.values.len > 0) |
| 17285 | try mod.intern_pool.getCoerced(gpa, enum_type.values.get(ip)[i], .comptime_int_type) | 17285 | try mod.intern_pool.getCoercedInts( |
| | 17286 | mod.gpa, |
| | 17287 | mod.intern_pool.indexToKey(enum_type.values.get(ip)[i]).int, |
| | 17288 | .comptime_int_type, |
| | 17289 | ) |
| 17286 | else | 17290 | else |
| 17287 | try mod.intern(.{ .int = .{ | 17291 | (try mod.intValue(Type.comptime_int, i)).toIntern(); |
| 17288 | .ty = .comptime_int_type, | | |
| 17289 | .storage = .{ .u64 = @intCast(i) }, | | |
| 17290 | } }); | | |
| 17291 | // TODO: write something like getCoercedInts to avoid needing to dupe | 17292 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 17292 | const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i])); | 17293 | const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i])); |
| 17293 | const name_val = v: { | 17294 | const name_val = v: { |
| ... | @@ -21259,7 +21260,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -21259,7 +21260,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 21259 | try sema.checkFloatType(block, operand_src, operand_scalar_ty); | 21260 | try sema.checkFloatType(block, operand_src, operand_scalar_ty); |
| 21260 | | 21261 | |
| 21261 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { | 21262 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { |
| 21262 | const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty); | 21263 | const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, .truncate); |
| 21263 | return Air.internedToRef(result_val.toIntern()); | 21264 | return Air.internedToRef(result_val.toIntern()); |
| 21264 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { | 21265 | } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeInt) { |
| 21265 | return sema.failWithNeededComptime(block, operand_src, .{ | 21266 | return sema.failWithNeededComptime(block, operand_src, .{ |
| ... | @@ -27575,21 +27576,21 @@ fn coerceExtra( | ... | @@ -27575,21 +27576,21 @@ fn coerceExtra( |
| 27575 | return block.addBitCast(dest_ty, inst); | 27576 | return block.addBitCast(dest_ty, inst); |
| 27576 | } | 27577 | } |
| 27577 | | 27578 | |
| 27578 | const is_undef = inst_ty.zigTypeTag(mod) == .Undefined; | | |
| 27579 | | | |
| 27580 | switch (dest_ty.zigTypeTag(mod)) { | 27579 | switch (dest_ty.zigTypeTag(mod)) { |
| 27581 | .Optional => optional: { | 27580 | .Optional => optional: { |
| 27582 | // undefined sets the optional bit also to undefined. | 27581 | if (maybe_inst_val) |val| { |
| 27583 | if (is_undef) { | 27582 | // undefined sets the optional bit also to undefined. |
| 27584 | return mod.undefRef(dest_ty); | 27583 | if (val.toIntern() == .undef) { |
| 27585 | } | 27584 | return mod.undefRef(dest_ty); |
| | 27585 | } |
| 27586 | | 27586 | |
| 27587 | // null to ?T | 27587 | // null to ?T |
| 27588 | if (inst_ty.zigTypeTag(mod) == .Null) { | 27588 | if (val.toIntern() == .null_value) { |
| 27589 | return Air.internedToRef((try mod.intern(.{ .opt = .{ | 27589 | return Air.internedToRef((try mod.intern(.{ .opt = .{ |
| 27590 | .ty = dest_ty.toIntern(), | 27590 | .ty = dest_ty.toIntern(), |
| 27591 | .val = .none, | 27591 | .val = .none, |
| 27592 | } }))); | 27592 | } }))); |
| | 27593 | } |
| 27593 | } | 27594 | } |
| 27594 | | 27595 | |
| 27595 | // cast from ?*T and ?[*]T to ?*anyopaque | 27596 | // cast from ?*T and ?[*]T to ?*anyopaque |
| ... | @@ -27681,7 +27682,9 @@ fn coerceExtra( | ... | @@ -27681,7 +27682,9 @@ fn coerceExtra( |
| 27681 | | 27682 | |
| 27682 | if (dest_info.sentinel != .none) { | 27683 | if (dest_info.sentinel != .none) { |
| 27683 | if (array_ty.sentinel(mod)) |inst_sent| { | 27684 | if (array_ty.sentinel(mod)) |inst_sent| { |
| 27684 | if (dest_info.sentinel != (try mod.getCoerced(inst_sent, dst_elem_type)).toIntern()) { | 27685 | if (Air.internedToRef(dest_info.sentinel) != |
| | 27686 | try sema.coerceInMemory(inst_sent, dst_elem_type)) |
| | 27687 | { |
| 27685 | in_memory_result = .{ .ptr_sentinel = .{ | 27688 | in_memory_result = .{ .ptr_sentinel = .{ |
| 27686 | .actual = inst_sent, | 27689 | .actual = inst_sent, |
| 27687 | .wanted = dest_info.sentinel.toValue(), | 27690 | .wanted = dest_info.sentinel.toValue(), |
| ... | @@ -27758,9 +27761,10 @@ fn coerceExtra( | ... | @@ -27758,9 +27761,10 @@ fn coerceExtra( |
| 27758 | switch (dest_info.flags.size) { | 27761 | switch (dest_info.flags.size) { |
| 27759 | // coercion to C pointer | 27762 | // coercion to C pointer |
| 27760 | .C => switch (inst_ty.zigTypeTag(mod)) { | 27763 | .C => switch (inst_ty.zigTypeTag(mod)) { |
| 27761 | .Null => { | 27764 | .Null => return Air.internedToRef(try mod.intern(.{ .ptr = .{ |
| 27762 | return Air.internedToRef((try mod.getCoerced(Value.null, dest_ty)).toIntern()); | 27765 | .ty = dest_ty.toIntern(), |
| 27763 | }, | 27766 | .addr = .{ .int = .zero_usize }, |
| | 27767 | } })), |
| 27764 | .ComptimeInt => { | 27768 | .ComptimeInt => { |
| 27765 | const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { | 27769 | const addr = sema.coerceExtra(block, Type.usize, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { |
| 27766 | error.NotCoercible => break :pointer, | 27770 | error.NotCoercible => break :pointer, |
| ... | @@ -27865,10 +27869,19 @@ fn coerceExtra( | ... | @@ -27865,10 +27869,19 @@ fn coerceExtra( |
| 27865 | // we use a dummy pointer value with the required alignment. | 27869 | // we use a dummy pointer value with the required alignment. |
| 27866 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 27870 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ |
| 27867 | .ty = dest_ty.toIntern(), | 27871 | .ty = dest_ty.toIntern(), |
| 27868 | .addr = .{ .int = (if (dest_info.flags.alignment != .none) | 27872 | .addr = .{ .int = if (dest_info.flags.alignment != .none) |
| 27869 | try mod.intValue(Type.usize, dest_info.flags.alignment.toByteUnitsOptional().?) | 27873 | (try mod.intValue( |
| | 27874 | Type.usize, |
| | 27875 | dest_info.flags.alignment.toByteUnitsOptional().?, |
| | 27876 | )).toIntern() |
| 27870 | else | 27877 | else |
| 27871 | try mod.getCoerced(try dest_info.child.toType().lazyAbiAlignment(mod), Type.usize)).toIntern() }, | 27878 | try mod.intern_pool.getCoercedInts( |
| | 27879 | mod.gpa, |
| | 27880 | mod.intern_pool.indexToKey( |
| | 27881 | (try dest_info.child.toType().lazyAbiAlignment(mod)).toIntern(), |
| | 27882 | ).int, |
| | 27883 | .usize_type, |
| | 27884 | ) }, |
| 27872 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), | 27885 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), |
| 27873 | } }))); | 27886 | } }))); |
| 27874 | } | 27887 | } |
| ... | @@ -27904,8 +27917,8 @@ fn coerceExtra( | ... | @@ -27904,8 +27917,8 @@ fn coerceExtra( |
| 27904 | } | 27917 | } |
| 27905 | | 27918 | |
| 27906 | if (dest_info.sentinel == .none or inst_info.sentinel == .none or | 27919 | if (dest_info.sentinel == .none or inst_info.sentinel == .none or |
| 27907 | dest_info.sentinel != | 27920 | Air.internedToRef(dest_info.sentinel) != |
| 27908 | try mod.intern_pool.getCoerced(sema.gpa, inst_info.sentinel, dest_info.child)) | 27921 | try sema.coerceInMemory(inst_info.sentinel.toValue(), dest_info.child.toType())) |
| 27909 | break :p; | 27922 | break :p; |
| 27910 | | 27923 | |
| 27911 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 27924 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -27915,10 +27928,7 @@ fn coerceExtra( | ... | @@ -27915,10 +27928,7 @@ fn coerceExtra( |
| 27915 | }, | 27928 | }, |
| 27916 | .Int, .ComptimeInt => switch (inst_ty.zigTypeTag(mod)) { | 27929 | .Int, .ComptimeInt => switch (inst_ty.zigTypeTag(mod)) { |
| 27917 | .Float, .ComptimeFloat => float: { | 27930 | .Float, .ComptimeFloat => float: { |
| 27918 | if (is_undef) { | 27931 | const val = maybe_inst_val orelse { |
| 27919 | return mod.undefRef(dest_ty); | | |
| 27920 | } | | |
| 27921 | const val = (try sema.resolveMaybeUndefVal(inst)) orelse { | | |
| 27922 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { | 27932 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { |
| 27923 | if (!opts.report_err) return error.NotCoercible; | 27933 | if (!opts.report_err) return error.NotCoercible; |
| 27924 | return sema.failWithNeededComptime(block, inst_src, .{ | 27934 | return sema.failWithNeededComptime(block, inst_src, .{ |
| ... | @@ -27927,29 +27937,23 @@ fn coerceExtra( | ... | @@ -27927,29 +27937,23 @@ fn coerceExtra( |
| 27927 | } | 27937 | } |
| 27928 | break :float; | 27938 | break :float; |
| 27929 | }; | 27939 | }; |
| 27930 | | 27940 | const result_val = try sema.intFromFloat(block, inst_src, val, inst_ty, dest_ty, .exact); |
| 27931 | if (val.floatHasFraction(mod)) { | | |
| 27932 | return sema.fail( | | |
| 27933 | block, | | |
| 27934 | inst_src, | | |
| 27935 | "fractional component prevents float value '{}' from coercion to type '{}'", | | |
| 27936 | .{ val.fmtValue(inst_ty, mod), dest_ty.fmt(mod) }, | | |
| 27937 | ); | | |
| 27938 | } | | |
| 27939 | const result_val = try sema.intFromFloat(block, inst_src, val, inst_ty, dest_ty); | | |
| 27940 | return Air.internedToRef(result_val.toIntern()); | 27941 | return Air.internedToRef(result_val.toIntern()); |
| 27941 | }, | 27942 | }, |
| 27942 | .Int, .ComptimeInt => { | 27943 | .Int, .ComptimeInt => { |
| 27943 | if (is_undef) { | 27944 | if (maybe_inst_val) |val| { |
| 27944 | return mod.undefRef(dest_ty); | | |
| 27945 | } | | |
| 27946 | if (try sema.resolveMaybeUndefVal(inst)) |val| { | | |
| 27947 | // comptime-known integer to other number | 27945 | // comptime-known integer to other number |
| 27948 | if (!(try sema.intFitsInType(val, dest_ty, null))) { | 27946 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 27949 | if (!opts.report_err) return error.NotCoercible; | 27947 | if (!opts.report_err) return error.NotCoercible; |
| 27950 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }); | 27948 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }); |
| 27951 | } | 27949 | } |
| 27952 | return Air.internedToRef((try mod.getCoerced(val, dest_ty)).toIntern()); | 27950 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| | 27951 | .undef => try mod.undefRef(dest_ty), |
| | 27952 | .int => |int| Air.internedToRef( |
| | 27953 | try mod.intern_pool.getCoercedInts(mod.gpa, int, dest_ty.toIntern()), |
| | 27954 | ), |
| | 27955 | else => unreachable, |
| | 27956 | }; |
| 27953 | } | 27957 | } |
| 27954 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { | 27958 | if (dest_ty.zigTypeTag(mod) == .ComptimeInt) { |
| 27955 | if (!opts.report_err) return error.NotCoercible; | 27959 | if (!opts.report_err) return error.NotCoercible; |
| ... | @@ -27970,9 +27974,6 @@ fn coerceExtra( | ... | @@ -27970,9 +27974,6 @@ fn coerceExtra( |
| 27970 | return block.addTyOp(.intcast, dest_ty, inst); | 27974 | return block.addTyOp(.intcast, dest_ty, inst); |
| 27971 | } | 27975 | } |
| 27972 | }, | 27976 | }, |
| 27973 | .Undefined => { | | |
| 27974 | return mod.undefRef(dest_ty); | | |
| 27975 | }, | | |
| 27976 | else => {}, | 27977 | else => {}, |
| 27977 | }, | 27978 | }, |
| 27978 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) { | 27979 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(mod)) { |
| ... | @@ -27982,10 +27983,7 @@ fn coerceExtra( | ... | @@ -27982,10 +27983,7 @@ fn coerceExtra( |
| 27982 | return Air.internedToRef(result_val.toIntern()); | 27983 | return Air.internedToRef(result_val.toIntern()); |
| 27983 | }, | 27984 | }, |
| 27984 | .Float => { | 27985 | .Float => { |
| 27985 | if (is_undef) { | 27986 | if (maybe_inst_val) |val| { |
| 27986 | return mod.undefRef(dest_ty); | | |
| 27987 | } | | |
| 27988 | if (try sema.resolveMaybeUndefVal(inst)) |val| { | | |
| 27989 | const result_val = try val.floatCast(dest_ty, mod); | 27987 | const result_val = try val.floatCast(dest_ty, mod); |
| 27990 | if (!val.eql(try result_val.floatCast(inst_ty, mod), inst_ty, mod)) { | 27988 | if (!val.eql(try result_val.floatCast(inst_ty, mod), inst_ty, mod)) { |
| 27991 | return sema.fail( | 27989 | return sema.fail( |
| ... | @@ -28012,10 +28010,7 @@ fn coerceExtra( | ... | @@ -28012,10 +28010,7 @@ fn coerceExtra( |
| 28012 | } | 28010 | } |
| 28013 | }, | 28011 | }, |
| 28014 | .Int, .ComptimeInt => int: { | 28012 | .Int, .ComptimeInt => int: { |
| 28015 | if (is_undef) { | 28013 | const val = maybe_inst_val orelse { |
| 28016 | return mod.undefRef(dest_ty); | | |
| 28017 | } | | |
| 28018 | const val = (try sema.resolveMaybeUndefVal(inst)) orelse { | | |
| 28019 | if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) { | 28014 | if (dest_ty.zigTypeTag(mod) == .ComptimeFloat) { |
| 28020 | if (!opts.report_err) return error.NotCoercible; | 28015 | if (!opts.report_err) return error.NotCoercible; |
| 28021 | return sema.failWithNeededComptime(block, inst_src, .{ | 28016 | return sema.failWithNeededComptime(block, inst_src, .{ |
| ... | @@ -28037,9 +28032,6 @@ fn coerceExtra( | ... | @@ -28037,9 +28032,6 @@ fn coerceExtra( |
| 28037 | //} | 28032 | //} |
| 28038 | return Air.internedToRef(result_val.toIntern()); | 28033 | return Air.internedToRef(result_val.toIntern()); |
| 28039 | }, | 28034 | }, |
| 28040 | .Undefined => { | | |
| 28041 | return mod.undefRef(dest_ty); | | |
| 28042 | }, | | |
| 28043 | else => {}, | 28035 | else => {}, |
| 28044 | }, | 28036 | }, |
| 28045 | .Enum => switch (inst_ty.zigTypeTag(mod)) { | 28037 | .Enum => switch (inst_ty.zigTypeTag(mod)) { |
| ... | @@ -28070,9 +28062,6 @@ fn coerceExtra( | ... | @@ -28070,9 +28062,6 @@ fn coerceExtra( |
| 28070 | return sema.unionToTag(block, dest_ty, inst, inst_src); | 28062 | return sema.unionToTag(block, dest_ty, inst, inst_src); |
| 28071 | } | 28063 | } |
| 28072 | }, | 28064 | }, |
| 28073 | .Undefined => { | | |
| 28074 | return mod.undefRef(dest_ty); | | |
| 28075 | }, | | |
| 28076 | else => {}, | 28065 | else => {}, |
| 28077 | }, | 28066 | }, |
| 28078 | .ErrorUnion => switch (inst_ty.zigTypeTag(mod)) { | 28067 | .ErrorUnion => switch (inst_ty.zigTypeTag(mod)) { |
| ... | @@ -28107,9 +28096,6 @@ fn coerceExtra( | ... | @@ -28107,9 +28096,6 @@ fn coerceExtra( |
| 28107 | // E to E!T | 28096 | // E to E!T |
| 28108 | return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src); | 28097 | return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src); |
| 28109 | }, | 28098 | }, |
| 28110 | .Undefined => { | | |
| 28111 | return mod.undefRef(dest_ty); | | |
| 28112 | }, | | |
| 28113 | else => eu: { | 28099 | else => eu: { |
| 28114 | // T to E!T | 28100 | // T to E!T |
| 28115 | return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) { | 28101 | return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) { |
| ... | @@ -28125,9 +28111,6 @@ fn coerceExtra( | ... | @@ -28125,9 +28111,6 @@ fn coerceExtra( |
| 28125 | return sema.coerceAnonStructToUnion(block, dest_ty, dest_ty_src, inst, inst_src); | 28111 | return sema.coerceAnonStructToUnion(block, dest_ty, dest_ty_src, inst, inst_src); |
| 28126 | } | 28112 | } |
| 28127 | }, | 28113 | }, |
| 28128 | .Undefined => { | | |
| 28129 | return mod.undefRef(dest_ty); | | |
| 28130 | }, | | |
| 28131 | else => {}, | 28114 | else => {}, |
| 28132 | }, | 28115 | }, |
| 28133 | .Array => switch (inst_ty.zigTypeTag(mod)) { | 28116 | .Array => switch (inst_ty.zigTypeTag(mod)) { |
| ... | @@ -28140,9 +28123,6 @@ fn coerceExtra( | ... | @@ -28140,9 +28123,6 @@ fn coerceExtra( |
| 28140 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); | 28123 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); |
| 28141 | } | 28124 | } |
| 28142 | }, | 28125 | }, |
| 28143 | .Undefined => { | | |
| 28144 | return mod.undefRef(dest_ty); | | |
| 28145 | }, | | |
| 28146 | else => {}, | 28126 | else => {}, |
| 28147 | }, | 28127 | }, |
| 28148 | .Vector => switch (inst_ty.zigTypeTag(mod)) { | 28128 | .Vector => switch (inst_ty.zigTypeTag(mod)) { |
| ... | @@ -28152,9 +28132,6 @@ fn coerceExtra( | ... | @@ -28152,9 +28132,6 @@ fn coerceExtra( |
| 28152 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); | 28132 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); |
| 28153 | } | 28133 | } |
| 28154 | }, | 28134 | }, |
| 28155 | .Undefined => { | | |
| 28156 | return mod.undefRef(dest_ty); | | |
| 28157 | }, | | |
| 28158 | else => {}, | 28135 | else => {}, |
| 28159 | }, | 28136 | }, |
| 28160 | .Struct => blk: { | 28137 | .Struct => blk: { |
| ... | @@ -28174,9 +28151,7 @@ fn coerceExtra( | ... | @@ -28174,9 +28151,7 @@ fn coerceExtra( |
| 28174 | // undefined to anything. We do this after the big switch above so that | 28151 | // undefined to anything. We do this after the big switch above so that |
| 28175 | // special logic has a chance to run first, such as `*[N]T` to `[]T` which | 28152 | // special logic has a chance to run first, such as `*[N]T` to `[]T` which |
| 28176 | // should initialize the length field of the slice. | 28153 | // should initialize the length field of the slice. |
| 28177 | if (is_undef) { | 28154 | if (maybe_inst_val) |val| if (val.toIntern() == .undef) return mod.undefRef(dest_ty); |
| 28178 | return mod.undefRef(dest_ty); | | |
| 28179 | } | | |
| 28180 | | 28155 | |
| 28181 | if (!opts.report_err) return error.NotCoercible; | 28156 | if (!opts.report_err) return error.NotCoercible; |
| 28182 | | 28157 | |
| ... | @@ -34043,10 +34018,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { | ... | @@ -34043,10 +34018,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 34043 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | 34018 | switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 34044 | .int => |int| switch (int.storage) { | 34019 | .int => |int| switch (int.storage) { |
| 34045 | .u64, .i64, .big_int => return val, | 34020 | .u64, .i64, .big_int => return val, |
| 34046 | .lazy_align, .lazy_size => return (try mod.intern(.{ .int = .{ | 34021 | .lazy_align, .lazy_size => return mod.intValue( |
| 34047 | .ty = int.ty, | 34022 | int.ty.toType(), |
| 34048 | .storage = .{ .u64 = (try val.getUnsignedIntAdvanced(mod, sema)).? }, | 34023 | (try val.getUnsignedIntAdvanced(mod, sema)).?, |
| 34049 | } })).toValue(), | 34024 | ), |
| 34050 | }, | 34025 | }, |
| 34051 | .ptr => |ptr| { | 34026 | .ptr => |ptr| { |
| 34052 | const resolved_len = switch (ptr.len) { | 34027 | const resolved_len = switch (ptr.len) { |
| ... | @@ -36217,20 +36192,21 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36217,20 +36192,21 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36217 | .auto, .explicit => { | 36192 | .auto, .explicit => { |
| 36218 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; | 36193 | if (enum_type.tag_ty.toType().hasRuntimeBits(mod)) return null; |
| 36219 | | 36194 | |
| 36220 | switch (enum_type.names.len) { | 36195 | return switch (enum_type.names.len) { |
| 36221 | 0 => { | 36196 | 0 => try mod.intern(.{ .empty_enum_value = ty.toIntern() }), |
| 36222 | const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() }); | 36197 | 1 => try mod.intern(.{ .enum_tag = .{ |
| 36223 | return only.toValue(); | 36198 | .ty = ty.toIntern(), |
| 36224 | }, | 36199 | .int = if (enum_type.values.len == 0) |
| 36225 | 1 => return try mod.getCoerced((if (enum_type.values.len == 0) | 36200 | (try mod.intValue(enum_type.tag_ty.toType(), 0)).toIntern() |
| 36226 | try mod.intern(.{ .int = .{ | 36201 | else |
| 36227 | .ty = enum_type.tag_ty, | 36202 | try mod.intern_pool.getCoercedInts( |
| 36228 | .storage = .{ .u64 = 0 }, | 36203 | mod.gpa, |
| 36229 | } }) | 36204 | mod.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int, |
| 36230 | else | 36205 | enum_type.tag_ty, |
| 36231 | enum_type.values.get(ip)[0]).toValue(), ty), | 36206 | ), |
| | 36207 | } }), |
| 36232 | else => return null, | 36208 | else => return null, |
| 36233 | } | 36209 | }.toValue(); |
| 36234 | }, | 36210 | }, |
| 36235 | }, | 36211 | }, |
| 36236 | | 36212 | |
| ... | @@ -37069,6 +37045,8 @@ fn intSubWithOverflowScalar( | ... | @@ -37069,6 +37045,8 @@ fn intSubWithOverflowScalar( |
| 37069 | }; | 37045 | }; |
| 37070 | } | 37046 | } |
| 37071 | | 37047 | |
| | 37048 | const IntFromFloatMode = enum { exact, truncate }; |
| | 37049 | |
| 37072 | fn intFromFloat( | 37050 | fn intFromFloat( |
| 37073 | sema: *Sema, | 37051 | sema: *Sema, |
| 37074 | block: *Block, | 37052 | block: *Block, |
| ... | @@ -37076,6 +37054,7 @@ fn intFromFloat( | ... | @@ -37076,6 +37054,7 @@ fn intFromFloat( |
| 37076 | val: Value, | 37054 | val: Value, |
| 37077 | float_ty: Type, | 37055 | float_ty: Type, |
| 37078 | int_ty: Type, | 37056 | int_ty: Type, |
| | 37057 | mode: IntFromFloatMode, |
| 37079 | ) CompileError!Value { | 37058 | ) CompileError!Value { |
| 37080 | const mod = sema.mod; | 37059 | const mod = sema.mod; |
| 37081 | if (float_ty.zigTypeTag(mod) == .Vector) { | 37060 | if (float_ty.zigTypeTag(mod) == .Vector) { |
| ... | @@ -37084,14 +37063,14 @@ fn intFromFloat( | ... | @@ -37084,14 +37063,14 @@ fn intFromFloat( |
| 37084 | const scalar_ty = int_ty.scalarType(mod); | 37063 | const scalar_ty = int_ty.scalarType(mod); |
| 37085 | for (result_data, 0..) |*scalar, i| { | 37064 | for (result_data, 0..) |*scalar, i| { |
| 37086 | const elem_val = try val.elemValue(sema.mod, i); | 37065 | const elem_val = try val.elemValue(sema.mod, i); |
| 37087 | scalar.* = try (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod))).intern(scalar_ty, mod); | 37066 | scalar.* = try (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).intern(scalar_ty, mod); |
| 37088 | } | 37067 | } |
| 37089 | return (try mod.intern(.{ .aggregate = .{ | 37068 | return (try mod.intern(.{ .aggregate = .{ |
| 37090 | .ty = int_ty.toIntern(), | 37069 | .ty = int_ty.toIntern(), |
| 37091 | .storage = .{ .elems = result_data }, | 37070 | .storage = .{ .elems = result_data }, |
| 37092 | } })).toValue(); | 37071 | } })).toValue(); |
| 37093 | } | 37072 | } |
| 37094 | return sema.intFromFloatScalar(block, src, val, float_ty, int_ty); | 37073 | return sema.intFromFloatScalar(block, src, val, float_ty, int_ty, mode); |
| 37095 | } | 37074 | } |
| 37096 | | 37075 | |
| 37097 | // float is expected to be finite and non-NaN | 37076 | // float is expected to be finite and non-NaN |
| ... | @@ -37126,9 +37105,19 @@ fn intFromFloatScalar( | ... | @@ -37126,9 +37105,19 @@ fn intFromFloatScalar( |
| 37126 | val: Value, | 37105 | val: Value, |
| 37127 | float_ty: Type, | 37106 | float_ty: Type, |
| 37128 | int_ty: Type, | 37107 | int_ty: Type, |
| | 37108 | mode: IntFromFloatMode, |
| 37129 | ) CompileError!Value { | 37109 | ) CompileError!Value { |
| 37130 | const mod = sema.mod; | 37110 | const mod = sema.mod; |
| 37131 | | 37111 | |
| | 37112 | if (val.isUndef(mod)) return sema.failWithUseOfUndef(block, src); |
| | 37113 | |
| | 37114 | if (mode == .exact and val.floatHasFraction(mod)) return sema.fail( |
| | 37115 | block, |
| | 37116 | src, |
| | 37117 | "fractional component prevents float value '{}' from coercion to type '{}'", |
| | 37118 | .{ val.fmtValue(float_ty, mod), int_ty.fmt(mod) }, |
| | 37119 | ); |
| | 37120 | |
| 37132 | const float = val.toFloat(f128, mod); | 37121 | const float = val.toFloat(f128, mod); |
| 37133 | if (std.math.isNan(float)) { | 37122 | if (std.math.isNan(float)) { |
| 37134 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ | 37123 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ |