authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 22:30:38-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-22 22:30:38-04:00
loge8813b296bc55a13b534bd9b2a03e1f6af366915
treed58db370235d221e8780b06e85dccfb548536b3a
parentcb6364624fb28bf51adb2dc16c8e93a30c33c76b
parent44f9061b718e9bdcd43d258291f89930b74aa56a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11260 from ziglang/lazy-alignof

stage2: lazy `@alignOf`

26 files changed, 1733 insertions(+), 1094 deletions(-)

src/Compilation.zig+3-1
......@@ -2781,7 +2781,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
27812781 .error_msg = null,
27822782 .decl = decl,
27832783 .fwd_decl = fwd_decl.toManaged(gpa),
2784 .typedefs = c_codegen.TypedefMap.init(gpa),
2784 .typedefs = c_codegen.TypedefMap.initContext(gpa, .{
2785 .target = comp.getTarget(),
2786 }),
27852787 .typedefs_arena = typedefs_arena.allocator(),
27862788 };
27872789 defer dg.fwd_decl.deinit();
src/Module.zig+25-33
......@@ -146,6 +146,8 @@ const MonomorphedFuncsSet = std.HashMapUnmanaged(
146146);
147147
148148const MonomorphedFuncsContext = struct {
149 target: Target,
150
149151 pub fn eql(ctx: @This(), a: *Fn, b: *Fn) bool {
150152 _ = ctx;
151153 return a == b;
......@@ -153,7 +155,6 @@ const MonomorphedFuncsContext = struct {
153155
154156 /// Must match `Sema.GenericCallAdapter.hash`.
155157 pub fn hash(ctx: @This(), key: *Fn) u64 {
156 _ = ctx;
157158 var hasher = std.hash.Wyhash.init(0);
158159
159160 // The generic function Decl is guaranteed to be the first dependency
......@@ -168,7 +169,7 @@ const MonomorphedFuncsContext = struct {
168169 const generic_ty_info = generic_owner_decl.ty.fnInfo();
169170 for (generic_ty_info.param_types) |param_ty, i| {
170171 if (generic_ty_info.paramIsComptime(i) and param_ty.tag() != .generic_poison) {
171 comptime_args[i].val.hash(param_ty, &hasher);
172 comptime_args[i].val.hash(param_ty, &hasher, ctx.target);
172173 }
173174 }
174175
......@@ -176,6 +177,12 @@ const MonomorphedFuncsContext = struct {
176177 }
177178};
178179
180pub const WipAnalysis = struct {
181 sema: *Sema,
182 block: *Sema.Block,
183 src: Module.LazySrcLoc,
184};
185
179186pub const MemoizedCallSet = std.HashMapUnmanaged(
180187 MemoizedCall.Key,
181188 MemoizedCall.Result,
......@@ -184,6 +191,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
184191);
185192
186193pub const MemoizedCall = struct {
194 target: std.Target,
195
187196 pub const Key = struct {
188197 func: *Fn,
189198 args: []TypedValue,
......@@ -195,14 +204,12 @@ pub const MemoizedCall = struct {
195204 };
196205
197206 pub fn eql(ctx: @This(), a: Key, b: Key) bool {
198 _ = ctx;
199
200207 if (a.func != b.func) return false;
201208
202209 assert(a.args.len == b.args.len);
203210 for (a.args) |a_arg, arg_i| {
204211 const b_arg = b.args[arg_i];
205 if (!a_arg.eql(b_arg)) {
212 if (!a_arg.eql(b_arg, ctx.target)) {
206213 return false;
207214 }
208215 }
......@@ -212,8 +219,6 @@ pub const MemoizedCall = struct {
212219
213220 /// Must match `Sema.GenericCallAdapter.hash`.
214221 pub fn hash(ctx: @This(), key: Key) u64 {
215 _ = ctx;
216
217222 var hasher = std.hash.Wyhash.init(0);
218223
219224 // The generic function Decl is guaranteed to be the first dependency
......@@ -223,7 +228,7 @@ pub const MemoizedCall = struct {
223228 // This logic must be kept in sync with the logic in `analyzeCall` that
224229 // computes the hash.
225230 for (key.args) |arg| {
226 arg.hash(&hasher);
231 arg.hash(&hasher, ctx.target);
227232 }
228233
229234 return hasher.final();
......@@ -1230,7 +1235,7 @@ pub const Union = struct {
12301235 if (field.abi_align == 0) {
12311236 break :a field.ty.abiAlignment(target);
12321237 } else {
1233 break :a @intCast(u32, field.abi_align.toUnsignedInt());
1238 break :a field.abi_align;
12341239 }
12351240 };
12361241 if (field_align > most_alignment) {
......@@ -3877,6 +3882,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38773882 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);
38783883 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
38793884 };
3885 const target = sema.mod.getTarget();
38803886 const address_space = blk: {
38813887 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {
38823888 .function, .extern_fn => .function,
......@@ -3886,9 +3892,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38863892
38873893 break :blk switch (decl.zirAddrspaceRef()) {
38883894 .none => switch (addrspace_ctx) {
3889 .function => target_util.defaultAddressSpace(sema.mod.getTarget(), .function),
3890 .variable => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_mutable),
3891 .constant => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
3895 .function => target_util.defaultAddressSpace(target, .function),
3896 .variable => target_util.defaultAddressSpace(target, .global_mutable),
3897 .constant => target_util.defaultAddressSpace(target, .global_constant),
38923898 else => unreachable,
38933899 },
38943900 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
......@@ -3904,13 +3910,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39043910
39053911 if (decl.is_usingnamespace) {
39063912 const ty_ty = Type.initTag(.type);
3907 if (!decl_tv.ty.eql(ty_ty)) {
3908 return sema.fail(&block_scope, src, "expected type, found {}", .{decl_tv.ty});
3913 if (!decl_tv.ty.eql(ty_ty, target)) {
3914 return sema.fail(&block_scope, src, "expected type, found {}", .{
3915 decl_tv.ty.fmt(target),
3916 });
39093917 }
39103918 var buffer: Value.ToTypeBuffer = undefined;
39113919 const ty = decl_tv.val.toType(&buffer);
39123920 if (ty.getNamespace() == null) {
3913 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty});
3921 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(target)});
39143922 }
39153923
39163924 decl.ty = ty_ty;
......@@ -3937,7 +3945,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39373945
39383946 if (decl.has_tv) {
39393947 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
3940 type_changed = !decl.ty.eql(decl_tv.ty);
3948 type_changed = !decl.ty.eql(decl_tv.ty, target);
39413949 if (decl.getFunction()) |prev_func| {
39423950 prev_is_inline = prev_func.state == .inline_only;
39433951 }
......@@ -3986,7 +3994,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39863994 }
39873995 var type_changed = true;
39883996 if (decl.has_tv) {
3989 type_changed = !decl.ty.eql(decl_tv.ty);
3997 type_changed = !decl.ty.eql(decl_tv.ty, target);
39903998 decl.clearValues(gpa);
39913999 }
39924000
......@@ -5054,22 +5062,6 @@ pub fn errNoteNonLazy(
50545062 };
50555063}
50565064
5057pub fn errorUnionType(
5058 arena: Allocator,
5059 error_set: Type,
5060 payload: Type,
5061) Allocator.Error!Type {
5062 assert(error_set.zigTypeTag() == .ErrorSet);
5063 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
5064 return Type.initTag(.anyerror_void_error_union);
5065 }
5066
5067 return Type.Tag.error_union.create(arena, .{
5068 .error_set = error_set,
5069 .payload = payload,
5070 });
5071}
5072
50735065pub fn getTarget(mod: Module) Target {
50745066 return mod.comp.bin_file.options.target;
50755067}
src/RangeSet.zig+22-9
......@@ -6,6 +6,7 @@ const RangeSet = @This();
66const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;
77
88ranges: std.ArrayList(Range),
9target: std.Target,
910
1011pub const Range = struct {
1112 first: Value,
......@@ -13,9 +14,10 @@ pub const Range = struct {
1314 src: SwitchProngSrc,
1415};
1516
16pub fn init(allocator: std.mem.Allocator) RangeSet {
17pub fn init(allocator: std.mem.Allocator, target: std.Target) RangeSet {
1718 return .{
1819 .ranges = std.ArrayList(Range).init(allocator),
20 .target = target,
1921 };
2022}
2123
......@@ -30,8 +32,12 @@ pub fn add(
3032 ty: Type,
3133 src: SwitchProngSrc,
3234) !?SwitchProngSrc {
35 const target = self.target;
36
3337 for (self.ranges.items) |range| {
34 if (last.compare(.gte, range.first, ty) and first.compare(.lte, range.last, ty)) {
38 if (last.compare(.gte, range.first, ty, target) and
39 first.compare(.lte, range.last, ty, target))
40 {
3541 return range.src; // They overlap.
3642 }
3743 }
......@@ -43,19 +49,26 @@ pub fn add(
4349 return null;
4450}
4551
52const LessThanContext = struct { ty: Type, target: std.Target };
53
4654/// Assumes a and b do not overlap
47fn lessThan(ty: Type, a: Range, b: Range) bool {
48 return a.first.compare(.lt, b.first, ty);
55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
56 return a.first.compare(.lt, b.first, ctx.ty, ctx.target);
4957}
5058
5159pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
5260 if (self.ranges.items.len == 0)
5361 return false;
5462
55 std.sort.sort(Range, self.ranges.items, ty, lessThan);
63 const target = self.target;
64
65 std.sort.sort(Range, self.ranges.items, LessThanContext{
66 .ty = ty,
67 .target = target,
68 }, lessThan);
5669
57 if (!self.ranges.items[0].first.eql(first, ty) or
58 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty))
70 if (!self.ranges.items[0].first.eql(first, ty, target) or
71 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, target))
5972 {
6073 return false;
6174 }
......@@ -71,10 +84,10 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
7184 const prev = self.ranges.items[i];
7285
7386 // prev.last + 1 == cur.first
74 try counter.copy(prev.last.toBigInt(&space));
87 try counter.copy(prev.last.toBigInt(&space, target));
7588 try counter.addScalar(counter.toConst(), 1);
7689
77 const cur_start_int = cur.first.toBigInt(&space);
90 const cur_start_int = cur.first.toBigInt(&space, target);
7891 if (!cur_start_int.eq(counter.toConst())) {
7992 return false;
8093 }
src/Sema.zig+541-366
......@@ -1303,7 +1303,8 @@ pub fn resolveConstString(
13031303 const wanted_type = Type.initTag(.const_slice_u8);
13041304 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
13051305 const val = try sema.resolveConstValue(block, src, coerced_inst);
1306 return val.toAllocatedBytes(wanted_type, sema.arena);
1306 const target = sema.mod.getTarget();
1307 return val.toAllocatedBytes(wanted_type, sema.arena, target);
13071308}
13081309
13091310pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
......@@ -1457,19 +1458,29 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro
14571458}
14581459
14591460fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {
1460 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty });
1461 const target = sema.mod.getTarget();
1462 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{
1463 lhs_ty.fmt(target), rhs_ty.fmt(target),
1464 });
14611465}
14621466
14631467fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {
1464 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty});
1468 const target = sema.mod.getTarget();
1469 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty.fmt(target)});
14651470}
14661471
14671472fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1468 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ty});
1473 const target = sema.mod.getTarget();
1474 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{
1475 ty.fmt(target),
1476 });
14691477}
14701478
14711479fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1472 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ty});
1480 const target = sema.mod.getTarget();
1481 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
1482 ty.fmt(target),
1483 });
14731484}
14741485
14751486fn failWithErrorSetCodeMissing(
......@@ -1479,8 +1490,9 @@ fn failWithErrorSetCodeMissing(
14791490 dest_err_set_ty: Type,
14801491 src_err_set_ty: Type,
14811492) CompileError {
1493 const target = sema.mod.getTarget();
14821494 return sema.fail(block, src, "expected type '{}', found type '{}'", .{
1483 dest_err_set_ty, src_err_set_ty,
1495 dest_err_set_ty.fmt(target), src_err_set_ty.fmt(target),
14841496 });
14851497}
14861498
......@@ -1578,8 +1590,8 @@ fn resolveInt(
15781590 const air_inst = sema.resolveInst(zir_ref);
15791591 const coerced = try sema.coerce(block, dest_ty, air_inst, src);
15801592 const val = try sema.resolveConstValue(block, src, coerced);
1581
1582 return val.toUnsignedInt();
1593 const target = sema.mod.getTarget();
1594 return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
15831595}
15841596
15851597// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for
......@@ -1864,6 +1876,7 @@ fn createTypeName(
18641876 },
18651877 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),
18661878 .func => {
1879 const target = sema.mod.getTarget();
18671880 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);
18681881 const zir_tags = sema.code.instructions.items(.tag);
18691882
......@@ -1881,7 +1894,7 @@ fn createTypeName(
18811894 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;
18821895
18831896 if (arg_i != 0) try buf.appendSlice(",");
1884 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg))});
1897 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), target)});
18851898
18861899 arg_i += 1;
18871900 continue;
......@@ -2045,6 +2058,7 @@ fn zirEnumDecl(
20452058 enum_obj.tag_ty_inferred = true;
20462059 }
20472060 }
2061 const target = mod.getTarget();
20482062
20492063 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
20502064 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
......@@ -2053,6 +2067,7 @@ fn zirEnumDecl(
20532067 if (any_values) {
20542068 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
20552069 .ty = enum_obj.tag_ty,
2070 .target = target,
20562071 });
20572072 }
20582073
......@@ -2102,16 +2117,18 @@ fn zirEnumDecl(
21022117 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
21032118 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
21042119 .ty = enum_obj.tag_ty,
2120 .target = target,
21052121 });
21062122 } else if (any_values) {
21072123 const tag_val = if (last_tag_val) |val|
2108 try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena)
2124 try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena, target)
21092125 else
21102126 Value.zero;
21112127 last_tag_val = tag_val;
21122128 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
21132129 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
21142130 .ty = enum_obj.tag_ty,
2131 .target = target,
21152132 });
21162133 }
21172134 }
......@@ -2417,13 +2434,14 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
24172434 else
24182435 object_ty;
24192436
2437 const target = sema.mod.getTarget();
24202438 if (!array_ty.isIndexable()) {
24212439 const msg = msg: {
24222440 const msg = try sema.errMsg(
24232441 block,
24242442 src,
24252443 "type '{}' does not support indexing",
2426 .{array_ty},
2444 .{array_ty.fmt(target)},
24272445 );
24282446 errdefer msg.destroy(sema.gpa);
24292447 try sema.errNote(
......@@ -3346,8 +3364,9 @@ fn failWithBadMemberAccess(
33463364 else => unreachable,
33473365 };
33483366 const msg = msg: {
3367 const target = sema.mod.getTarget();
33493368 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{
3350 kw_name, agg_ty, field_name,
3369 kw_name, agg_ty.fmt(target), field_name,
33513370 });
33523371 errdefer msg.destroy(sema.gpa);
33533372 try sema.addDeclaredHereNote(msg, agg_ty);
......@@ -3680,6 +3699,7 @@ fn zirCompileLog(
36803699 const src_node = extra.data.src_node;
36813700 const src: LazySrcLoc = .{ .node_offset = src_node };
36823701 const args = sema.code.refSlice(extra.end, extended.small);
3702 const target = sema.mod.getTarget();
36833703
36843704 for (args) |arg_ref, i| {
36853705 if (i != 0) try writer.print(", ", .{});
......@@ -3687,9 +3707,11 @@ fn zirCompileLog(
36873707 const arg = sema.resolveInst(arg_ref);
36883708 const arg_ty = sema.typeOf(arg);
36893709 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {
3690 try writer.print("@as({}, {})", .{ arg_ty, val.fmtValue(arg_ty) });
3710 try writer.print("@as({}, {})", .{
3711 arg_ty.fmt(target), val.fmtValue(arg_ty, target),
3712 });
36913713 } else {
3692 try writer.print("@as({}, [runtime value])", .{arg_ty});
3714 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(target)});
36933715 }
36943716 }
36953717 try writer.print("\n", .{});
......@@ -3982,9 +4004,10 @@ fn analyzeBlockBody(
39824004
39834005 const type_src = src; // TODO: better source location
39844006 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);
4007 const target = sema.mod.getTarget();
39854008 if (!valid_rt) {
39864009 const msg = msg: {
3987 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty});
4010 const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty.fmt(target)});
39884011 errdefer msg.destroy(sema.gpa);
39894012
39904013 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
......@@ -4012,7 +4035,7 @@ fn analyzeBlockBody(
40124035 const br_operand = sema.air_instructions.items(.data)[br].br.operand;
40134036 const br_operand_src = src;
40144037 const br_operand_ty = sema.typeOf(br_operand);
4015 if (br_operand_ty.eql(resolved_ty)) {
4038 if (br_operand_ty.eql(resolved_ty, target)) {
40164039 // No type coercion needed.
40174040 continue;
40184041 }
......@@ -4102,12 +4125,15 @@ pub fn analyzeExport(
41024125) !void {
41034126 const Export = Module.Export;
41044127 const mod = sema.mod;
4128 const target = mod.getTarget();
41054129
41064130 try mod.ensureDeclAnalyzed(exported_decl);
41074131 // TODO run the same checks as we do for C ABI struct fields
41084132 switch (exported_decl.ty.zigTypeTag()) {
41094133 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},
4110 else => return sema.fail(block, src, "unable to export type '{}'", .{exported_decl.ty}),
4134 else => return sema.fail(block, src, "unable to export type '{}'", .{
4135 exported_decl.ty.fmt(target),
4136 }),
41114137 }
41124138
41134139 const gpa = mod.gpa;
......@@ -4520,6 +4546,7 @@ const GenericCallAdapter = struct {
45204546 precomputed_hash: u64,
45214547 func_ty_info: Type.Payload.Function.Data,
45224548 comptime_tvs: []const TypedValue,
4549 target: std.Target,
45234550
45244551 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
45254552 _ = adapted_key;
......@@ -4532,7 +4559,7 @@ const GenericCallAdapter = struct {
45324559 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {
45334560 if (other_arg.ty.tag() != .generic_poison) {
45344561 // anytype parameter
4535 if (!other_arg.ty.eql(ctx.comptime_tvs[i].ty)) {
4562 if (!other_arg.ty.eql(ctx.comptime_tvs[i].ty, ctx.target)) {
45364563 return false;
45374564 }
45384565 }
......@@ -4543,7 +4570,7 @@ const GenericCallAdapter = struct {
45434570 // but the callsite does not.
45444571 return false;
45454572 }
4546 if (!other_arg.val.eql(ctx.comptime_tvs[i].val, other_arg.ty)) {
4573 if (!other_arg.val.eql(ctx.comptime_tvs[i].val, other_arg.ty, ctx.target)) {
45474574 return false;
45484575 }
45494576 }
......@@ -4588,6 +4615,7 @@ fn analyzeCall(
45884615 const mod = sema.mod;
45894616
45904617 const callee_ty = sema.typeOf(func);
4618 const target = sema.mod.getTarget();
45914619 const func_ty = func_ty: {
45924620 switch (callee_ty.zigTypeTag()) {
45934621 .Fn => break :func_ty callee_ty,
......@@ -4599,7 +4627,7 @@ fn analyzeCall(
45994627 },
46004628 else => {},
46014629 }
4602 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty});
4630 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(target)});
46034631 };
46044632
46054633 const func_ty_info = func_ty.fnInfo();
......@@ -4873,7 +4901,7 @@ fn analyzeCall(
48734901 // bug generating invalid LLVM IR.
48744902 const res2: Air.Inst.Ref = res2: {
48754903 if (should_memoize and is_comptime_call) {
4876 if (mod.memoized_calls.get(memoized_call_key)) |result| {
4904 if (mod.memoized_calls.getContext(memoized_call_key, .{ .target = target })) |result| {
48774905 const ty_inst = try sema.addType(fn_ret_ty);
48784906 try sema.air_values.append(gpa, result.val);
48794907 sema.air_instructions.set(block_inst, .{
......@@ -4945,10 +4973,10 @@ fn analyzeCall(
49454973 arg.* = try arg.*.copy(arena);
49464974 }
49474975
4948 try mod.memoized_calls.put(gpa, memoized_call_key, .{
4976 try mod.memoized_calls.putContext(gpa, memoized_call_key, .{
49494977 .val = try result_val.copy(arena),
49504978 .arena = arena_allocator.state,
4951 });
4979 }, .{ .target = sema.mod.getTarget() });
49524980 delete_memoized_call_key = false;
49534981 }
49544982 }
......@@ -5037,6 +5065,7 @@ fn instantiateGenericCall(
50375065 std.hash.autoHash(&hasher, @ptrToInt(module_fn));
50385066
50395067 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);
5068 const target = sema.mod.getTarget();
50405069
50415070 for (func_ty_info.param_types) |param_ty, i| {
50425071 const is_comptime = func_ty_info.paramIsComptime(i);
......@@ -5045,7 +5074,7 @@ fn instantiateGenericCall(
50455074 const casted_arg = try sema.coerce(block, param_ty, uncasted_args[i], arg_src);
50465075 if (try sema.resolveMaybeUndefVal(block, arg_src, casted_arg)) |arg_val| {
50475076 if (param_ty.tag() != .generic_poison) {
5048 arg_val.hash(param_ty, &hasher);
5077 arg_val.hash(param_ty, &hasher, target);
50495078 }
50505079 comptime_tvs[i] = .{
50515080 // This will be different than `param_ty` in the case of `generic_poison`.
......@@ -5070,8 +5099,9 @@ fn instantiateGenericCall(
50705099 .precomputed_hash = precomputed_hash,
50715100 .func_ty_info = func_ty_info,
50725101 .comptime_tvs = comptime_tvs,
5102 .target = target,
50735103 };
5074 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);
5104 const gop = try mod.monomorphed_funcs.getOrPutContextAdapted(gpa, {}, adapter, .{ .target = target });
50755105 if (!gop.found_existing) {
50765106 const new_module_func = try gpa.create(Module.Fn);
50775107 gop.key_ptr.* = new_module_func;
......@@ -5255,7 +5285,7 @@ fn instantiateGenericCall(
52555285 new_decl.analysis = .complete;
52565286
52575287 log.debug("generic function '{s}' instantiated with type {}", .{
5258 new_decl.name, new_decl.ty,
5288 new_decl.name, new_decl.ty.fmtDebug(),
52595289 });
52605290
52615291 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
......@@ -5410,7 +5440,8 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
54105440 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
54115441 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);
54125442 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
5413 const array_ty = try Type.array(sema.arena, len, null, elem_type);
5443 const target = sema.mod.getTarget();
5444 const array_ty = try Type.array(sema.arena, len, null, elem_type, target);
54145445
54155446 return sema.addType(array_ty);
54165447}
......@@ -5429,7 +5460,8 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
54295460 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
54305461 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
54315462 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);
5432 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type);
5463 const target = sema.mod.getTarget();
5464 const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, target);
54335465
54345466 return sema.addType(array_ty);
54355467}
......@@ -5456,13 +5488,14 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
54565488 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
54575489 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
54585490 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
5491 const target = sema.mod.getTarget();
54595492
54605493 if (error_set.zigTypeTag() != .ErrorSet) {
54615494 return sema.fail(block, lhs_src, "expected error set type, found {}", .{
5462 error_set,
5495 error_set.fmt(target),
54635496 });
54645497 }
5465 const err_union_ty = try Module.errorUnionType(sema.arena, error_set, payload);
5498 const err_union_ty = try Type.errorUnion(sema.arena, error_set, payload, target);
54665499 return sema.addType(err_union_ty);
54675500}
54685501
......@@ -5520,9 +5553,10 @@ fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
55205553 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
55215554
55225555 const op = sema.resolveInst(inst_data.operand);
5556 const target = sema.mod.getTarget();
55235557
55245558 if (try sema.resolveDefinedValue(block, operand_src, op)) |value| {
5525 const int = value.toUnsignedInt();
5559 const int = value.toUnsignedInt(target);
55265560 if (int > sema.mod.global_error_set.count() or int == 0)
55275561 return sema.fail(block, operand_src, "integer value {d} represents no error", .{int});
55285562 const payload = try sema.arena.create(Value.Payload.Error);
......@@ -5569,10 +5603,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
55695603 }
55705604 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
55715605 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
5606 const target = sema.mod.getTarget();
55725607 if (lhs_ty.zigTypeTag() != .ErrorSet)
5573 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty});
5608 return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty.fmt(target)});
55745609 if (rhs_ty.zigTypeTag() != .ErrorSet)
5575 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty});
5610 return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty.fmt(target)});
55765611
55775612 // Anything merged with anyerror is anyerror.
55785613 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
......@@ -5618,6 +5653,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
56185653 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
56195654 const operand = sema.resolveInst(inst_data.operand);
56205655 const operand_ty = sema.typeOf(operand);
5656 const target = sema.mod.getTarget();
56215657
56225658 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
56235659 .Enum => operand,
......@@ -5634,7 +5670,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
56345670 },
56355671 else => {
56365672 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{
5637 operand_ty,
5673 operand_ty.fmt(target),
56385674 });
56395675 },
56405676 };
......@@ -5668,7 +5704,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
56685704 const operand = sema.resolveInst(extra.rhs);
56695705
56705706 if (dest_ty.zigTypeTag() != .Enum) {
5671 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty});
5707 return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty.fmt(target)});
56725708 }
56735709
56745710 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
......@@ -5684,7 +5720,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
56845720 block,
56855721 src,
56865722 "enum '{}' has no tag with value {}",
5687 .{ dest_ty, int_val.fmtValue(sema.typeOf(operand)) },
5723 .{ dest_ty.fmt(target), int_val.fmtValue(sema.typeOf(operand), target) },
56885724 );
56895725 errdefer msg.destroy(sema.gpa);
56905726 try sema.mod.errNoteNonLazy(
......@@ -5733,13 +5769,13 @@ fn analyzeOptionalPayloadPtr(
57335769 const optional_ptr_ty = sema.typeOf(optional_ptr);
57345770 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
57355771
5772 const target = sema.mod.getTarget();
57365773 const opt_type = optional_ptr_ty.elemType();
57375774 if (opt_type.zigTypeTag() != .Optional) {
5738 return sema.fail(block, src, "expected optional type, found {}", .{opt_type});
5775 return sema.fail(block, src, "expected optional type, found {}", .{opt_type.fmt(target)});
57395776 }
57405777
57415778 const child_type = try opt_type.optionalChildAlloc(sema.arena);
5742 const target = sema.mod.getTarget();
57435779 const child_pointer = try Type.ptr(sema.arena, target, .{
57445780 .pointee_type = child_type,
57455781 .mutable = !optional_ptr_ty.isConstPtr(),
......@@ -5858,8 +5894,12 @@ fn zirErrUnionPayload(
58585894 const operand = sema.resolveInst(inst_data.operand);
58595895 const operand_src = src;
58605896 const operand_ty = sema.typeOf(operand);
5861 if (operand_ty.zigTypeTag() != .ErrorUnion)
5862 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{operand_ty});
5897 if (operand_ty.zigTypeTag() != .ErrorUnion) {
5898 const target = sema.mod.getTarget();
5899 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
5900 operand_ty.fmt(target),
5901 });
5902 }
58635903
58645904 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
58655905 if (val.getError()) |name| {
......@@ -5906,11 +5946,14 @@ fn analyzeErrUnionPayloadPtr(
59065946 const operand_ty = sema.typeOf(operand);
59075947 assert(operand_ty.zigTypeTag() == .Pointer);
59085948
5909 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
5910 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});
5949 const target = sema.mod.getTarget();
5950 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
5951 return sema.fail(block, src, "expected error union type, found {}", .{
5952 operand_ty.elemType().fmt(target),
5953 });
5954 }
59115955
59125956 const payload_ty = operand_ty.elemType().errorUnionPayload();
5913 const target = sema.mod.getTarget();
59145957 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{
59155958 .pointee_type = payload_ty,
59165959 .mutable = !operand_ty.isConstPtr(),
......@@ -5970,8 +6013,12 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
59706013 const src = inst_data.src();
59716014 const operand = sema.resolveInst(inst_data.operand);
59726015 const operand_ty = sema.typeOf(operand);
5973 if (operand_ty.zigTypeTag() != .ErrorUnion)
5974 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});
6016 const target = sema.mod.getTarget();
6017 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6018 return sema.fail(block, src, "expected error union type, found '{}'", .{
6019 operand_ty.fmt(target),
6020 });
6021 }
59756022
59766023 const result_ty = operand_ty.errorUnionSet();
59776024
......@@ -5995,8 +6042,12 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
59956042 const operand_ty = sema.typeOf(operand);
59966043 assert(operand_ty.zigTypeTag() == .Pointer);
59976044
5998 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
5999 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});
6045 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
6046 const target = sema.mod.getTarget();
6047 return sema.fail(block, src, "expected error union type, found {}", .{
6048 operand_ty.elemType().fmt(target),
6049 });
6050 }
60006051
60016052 const result_ty = operand_ty.elemType().errorUnionSet();
60026053
......@@ -6019,8 +6070,12 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
60196070 const src = inst_data.src();
60206071 const operand = sema.resolveInst(inst_data.operand);
60216072 const operand_ty = sema.typeOf(operand);
6022 if (operand_ty.zigTypeTag() != .ErrorUnion)
6023 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});
6073 const target = sema.mod.getTarget();
6074 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6075 return sema.fail(block, src, "expected error union type, found '{}'", .{
6076 operand_ty.fmt(target),
6077 });
6078 }
60246079 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {
60256080 return sema.fail(block, src, "expression value is ignored", .{});
60266081 }
......@@ -6205,7 +6260,7 @@ fn funcCommon(
62056260
62066261 const fn_ty: Type = fn_ty: {
62076262 const alignment: u32 = if (align_val.tag() == .null_value) 0 else a: {
6208 const alignment = @intCast(u32, align_val.toUnsignedInt());
6263 const alignment = @intCast(u32, align_val.toUnsignedInt(target));
62096264 if (alignment == target_util.defaultFunctionAlignment(target)) {
62106265 break :a 0;
62116266 } else {
......@@ -6494,7 +6549,8 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
64946549 const ptr = sema.resolveInst(inst_data.operand);
64956550 const ptr_ty = sema.typeOf(ptr);
64966551 if (!ptr_ty.isPtrAtRuntime()) {
6497 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty});
6552 const target = sema.mod.getTarget();
6553 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)});
64986554 }
64996555 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
65006556 return sema.addConstant(Type.usize, ptr_val);
......@@ -6652,6 +6708,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
66526708 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
66536709 const operand = sema.resolveInst(extra.rhs);
66546710
6711 const target = sema.mod.getTarget();
66556712 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {
66566713 .ComptimeFloat => true,
66576714 .Float => false,
......@@ -6659,7 +6716,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
66596716 block,
66606717 dest_ty_src,
66616718 "expected float type, found '{}'",
6662 .{dest_ty},
6719 .{dest_ty.fmt(target)},
66636720 ),
66646721 };
66656722
......@@ -6670,7 +6727,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
66706727 block,
66716728 operand_src,
66726729 "expected float type, found '{}'",
6673 .{operand_ty},
6730 .{operand_ty.fmt(target)},
66746731 ),
66756732 }
66766733
......@@ -6680,7 +6737,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
66806737 if (dest_is_comptime_float) {
66816738 return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{});
66826739 }
6683 const target = sema.mod.getTarget();
66846740 const src_bits = operand_ty.floatBits(target);
66856741 const dst_bits = dest_ty.floatBits(target);
66866742 if (dst_bits >= src_bits) {
......@@ -6839,13 +6895,14 @@ fn zirSwitchCapture(
68396895 const item = sema.resolveInst(scalar_prong.item);
68406896 // Previous switch validation ensured this will succeed
68416897 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;
6898 const target = sema.mod.getTarget();
68426899
68436900 switch (operand_ty.zigTypeTag()) {
68446901 .Union => {
68456902 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
68466903 const enum_ty = union_obj.tag_ty;
68476904
6848 const field_index_usize = enum_ty.enumTagFieldIndex(item_val).?;
6905 const field_index_usize = enum_ty.enumTagFieldIndex(item_val, target).?;
68496906 const field_index = @intCast(u32, field_index_usize);
68506907 const field = union_obj.fields.values()[field_index];
68516908
......@@ -6854,7 +6911,6 @@ fn zirSwitchCapture(
68546911 if (is_ref) {
68556912 assert(operand_is_ref);
68566913
6857 const target = sema.mod.getTarget();
68586914 const field_ty_ptr = try Type.ptr(sema.arena, target, .{
68596915 .pointee_type = field.ty,
68606916 .@"addrspace" = .generic,
......@@ -6894,7 +6950,7 @@ fn zirSwitchCapture(
68946950 },
68956951 else => {
68966952 return sema.fail(block, operand_src, "switch on type '{}' provides no capture value", .{
6897 operand_ty,
6953 operand_ty.fmt(target),
68986954 });
68996955 },
69006956 }
......@@ -6915,6 +6971,7 @@ fn zirSwitchCond(
69156971 else
69166972 operand_ptr;
69176973 const operand_ty = sema.typeOf(operand);
6974 const target = sema.mod.getTarget();
69186975
69196976 switch (operand_ty.zigTypeTag()) {
69206977 .Type,
......@@ -6962,7 +7019,7 @@ fn zirSwitchCond(
69627019 .Vector,
69637020 .Frame,
69647021 .AnyFrame,
6965 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty}),
7022 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(target)}),
69667023 }
69677024}
69687025
......@@ -7030,6 +7087,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
70307087 return sema.failWithOwnedErrorMsg(block, msg);
70317088 }
70327089
7090 const target = sema.mod.getTarget();
7091
70337092 // Validate for duplicate items, missing else prong, and invalid range.
70347093 switch (operand_ty.zigTypeTag()) {
70357094 .Enum => {
......@@ -7115,7 +7174,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
71157174 operand_ty.declSrcLoc(),
71167175 msg,
71177176 "enum '{}' declared here",
7118 .{operand_ty},
7177 .{operand_ty.fmt(target)},
71197178 );
71207179 break :msg msg;
71217180 };
......@@ -7232,7 +7291,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
72327291 operand_ty.declSrcLoc(),
72337292 msg,
72347293 "error set '{}' declared here",
7235 .{operand_ty},
7294 .{operand_ty.fmt(target)},
72367295 );
72377296 return sema.failWithOwnedErrorMsg(block, msg);
72387297 }
......@@ -7260,7 +7319,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
72607319 },
72617320 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
72627321 .Int, .ComptimeInt => {
7263 var range_set = RangeSet.init(gpa);
7322 var range_set = RangeSet.init(gpa, target);
72647323 defer range_set.deinit();
72657324
72667325 var extra_index: usize = special.end;
......@@ -7333,7 +7392,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
73337392 var arena = std.heap.ArenaAllocator.init(gpa);
73347393 defer arena.deinit();
73357394
7336 const target = sema.mod.getTarget();
73377395 const min_int = try operand_ty.minInt(arena.allocator(), target);
73387396 const max_int = try operand_ty.maxInt(arena.allocator(), target);
73397397 if (try range_set.spans(min_int, max_int, operand_ty)) {
......@@ -7437,11 +7495,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
74377495 block,
74387496 src,
74397497 "else prong required when switching on type '{}'",
7440 .{operand_ty},
7498 .{operand_ty.fmt(target)},
74417499 );
74427500 }
74437501
7444 var seen_values = ValueSrcMap.initContext(gpa, .{ .ty = operand_ty });
7502 var seen_values = ValueSrcMap.initContext(gpa, .{
7503 .ty = operand_ty,
7504 .target = target,
7505 });
74457506 defer seen_values.deinit();
74467507
74477508 var extra_index: usize = special.end;
......@@ -7505,7 +7566,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
75057566 .ComptimeFloat,
75067567 .Float,
75077568 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
7508 operand_ty,
7569 operand_ty.fmt(target),
75097570 }),
75107571 }
75117572
......@@ -7555,7 +7616,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
75557616 const item = sema.resolveInst(item_ref);
75567617 // Validation above ensured these will succeed.
75577618 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
7558 if (operand_val.eql(item_val, operand_ty)) {
7619 if (operand_val.eql(item_val, operand_ty, target)) {
75597620 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
75607621 }
75617622 }
......@@ -7577,7 +7638,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
75777638 const item = sema.resolveInst(item_ref);
75787639 // Validation above ensured these will succeed.
75797640 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;
7580 if (operand_val.eql(item_val, operand_ty)) {
7641 if (operand_val.eql(item_val, operand_ty, target)) {
75817642 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
75827643 }
75837644 }
......@@ -7592,8 +7653,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
75927653 // Validation above ensured these will succeed.
75937654 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
75947655 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
7595 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty) and
7596 Value.compare(operand_val, .lte, last_tv.val, operand_ty))
7656 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, target) and
7657 Value.compare(operand_val, .lte, last_tv.val, operand_ty, target))
75977658 {
75987659 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
75997660 }
......@@ -7907,14 +7968,15 @@ fn validateSwitchItemEnum(
79077968 switch_prong_src: Module.SwitchProngSrc,
79087969) CompileError!void {
79097970 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
7910 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val) orelse {
7971 const target = sema.mod.getTarget();
7972 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, target) orelse {
79117973 const msg = msg: {
79127974 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);
79137975 const msg = try sema.errMsg(
79147976 block,
79157977 src,
79167978 "enum '{}' has no tag with value '{}'",
7917 .{ item_tv.ty, item_tv.val.fmtValue(item_tv.ty) },
7979 .{ item_tv.ty.fmt(target), item_tv.val.fmtValue(item_tv.ty, target) },
79187980 );
79197981 errdefer msg.destroy(sema.gpa);
79207982 try sema.mod.errNoteNonLazy(
......@@ -8030,12 +8092,13 @@ fn validateSwitchNoRange(
80308092 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
80318093 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };
80328094
8095 const target = sema.mod.getTarget();
80338096 const msg = msg: {
80348097 const msg = try sema.errMsg(
80358098 block,
80368099 operand_src,
80378100 "ranges not allowed when switching on type '{}'",
8038 .{operand_ty},
8101 .{operand_ty.fmt(target)},
80398102 );
80408103 errdefer msg.destroy(sema.gpa);
80418104 try sema.errNote(
......@@ -8058,6 +8121,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
80588121 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
80598122 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);
80608123 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
8124 const target = sema.mod.getTarget();
80618125
80628126 const has_field = hf: {
80638127 if (ty.isSlice()) {
......@@ -8080,7 +8144,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
80808144 .Enum => ty.enumFields().contains(field_name),
80818145 .Array => mem.eql(u8, field_name, "len"),
80828146 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
8083 ty,
8147 ty.fmt(target),
80848148 }),
80858149 };
80868150 };
......@@ -8227,25 +8291,25 @@ fn zirShl(
82278291
82288292 const val = switch (air_tag) {
82298293 .shl_exact => val: {
8230 const shifted = try lhs_val.shl(rhs_val, lhs_ty, sema.arena);
8294 const shifted = try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target);
82318295 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
82328296 break :val shifted;
82338297 }
82348298 const int_info = scalar_ty.intInfo(target);
8235 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits);
8236 if (truncated.compare(.eq, shifted, lhs_ty)) {
8299 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target);
8300 if (truncated.compare(.eq, shifted, lhs_ty, target)) {
82378301 break :val shifted;
82388302 }
82398303 return sema.addConstUndef(lhs_ty);
82408304 },
82418305
82428306 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)
8243 try lhs_val.shl(rhs_val, lhs_ty, sema.arena)
8307 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target)
82448308 else
82458309 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target),
82468310
82478311 .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt)
8248 try lhs_val.shl(rhs_val, lhs_ty, sema.arena)
8312 try lhs_val.shl(rhs_val, lhs_ty, sema.arena, target)
82498313 else
82508314 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target),
82518315
......@@ -8296,6 +8360,7 @@ fn zirShr(
82968360 const lhs_ty = sema.typeOf(lhs);
82978361 const rhs_ty = sema.typeOf(rhs);
82988362 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
8363 const target = sema.mod.getTarget();
82998364
83008365 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {
83018366 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
......@@ -8308,12 +8373,12 @@ fn zirShr(
83088373 }
83098374 if (air_tag == .shr_exact) {
83108375 // Detect if any ones would be shifted out.
8311 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val);
8376 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, target);
83128377 if (!truncated.compareWithZero(.eq)) {
83138378 return sema.addConstUndef(lhs_ty);
83148379 }
83158380 }
8316 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena);
8381 const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, target);
83178382 return sema.addConstant(lhs_ty, val);
83188383 } else {
83198384 // Even if lhs is not comptime known, we can still deduce certain things based
......@@ -8359,6 +8424,7 @@ fn zirBitwise(
83598424 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
83608425
83618426 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
8427 const target = sema.mod.getTarget();
83628428
83638429 if (!is_int) {
83648430 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
......@@ -8367,9 +8433,9 @@ fn zirBitwise(
83678433 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
83688434 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
83698435 const result_val = switch (air_tag) {
8370 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena),
8371 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena),
8372 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena),
8436 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
8437 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
8438 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
83738439 else => unreachable,
83748440 };
83758441 return sema.addConstant(resolved_type, result_val);
......@@ -8391,13 +8457,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
83918457 const operand = sema.resolveInst(inst_data.operand);
83928458 const operand_type = sema.typeOf(operand);
83938459 const scalar_type = operand_type.scalarType();
8460 const target = sema.mod.getTarget();
83948461
83958462 if (scalar_type.zigTypeTag() != .Int) {
8396 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{operand_type});
8463 return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{
8464 operand_type.fmt(target),
8465 });
83978466 }
83988467
83998468 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
8400 const target = sema.mod.getTarget();
84018469 if (val.isUndef()) {
84028470 return sema.addConstUndef(operand_type);
84038471 } else if (operand_type.zigTypeTag() == .Vector) {
......@@ -8513,19 +8581,22 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
85138581 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
85148582 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
85158583
8584 const target = sema.mod.getTarget();
85168585 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
8517 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});
8586 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});
85188587 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse
8519 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty});
8520 if (!lhs_info.elem_type.eql(rhs_info.elem_type)) {
8521 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty });
8588 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty.fmt(target)});
8589 if (!lhs_info.elem_type.eql(rhs_info.elem_type, target)) {
8590 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{
8591 lhs_info.elem_type.fmt(target), rhs_ty.fmt(target),
8592 });
85228593 }
85238594
85248595 // When there is a sentinel mismatch, no sentinel on the result. The type system
85258596 // will catch this if it is a problem.
85268597 var res_sent: ?Value = null;
85278598 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {
8528 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type)) {
8599 if (rhs_info.sentinel.?.eql(lhs_info.sentinel.?, lhs_info.elem_type, target)) {
85298600 res_sent = lhs_info.sentinel.?;
85308601 }
85318602 }
......@@ -8586,6 +8657,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
85868657
85878658fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {
85888659 const t = sema.typeOf(inst);
8660 const target = sema.mod.getTarget();
85898661 return switch (t.zigTypeTag()) {
85908662 .Array => t.arrayInfo(),
85918663 .Pointer => blk: {
......@@ -8595,7 +8667,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R
85958667 return Type.ArrayInfo{
85968668 .elem_type = t.childType(),
85978669 .sentinel = t.sentinel(),
8598 .len = val.sliceLen(),
8670 .len = val.sliceLen(target),
85998671 };
86008672 }
86018673 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
......@@ -8691,9 +8763,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
86918763 if (lhs_ty.isTuple()) {
86928764 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
86938765 }
8766 const target = sema.mod.getTarget();
86948767
86958768 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse
8696 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty});
8769 return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty.fmt(target)});
86978770
86988771 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch
86998772 return sema.fail(block, rhs_src, "operation results in overflow", .{});
......@@ -8771,8 +8844,9 @@ fn zirNegate(
87718844 const rhs_ty = sema.typeOf(rhs);
87728845 const rhs_scalar_ty = rhs_ty.scalarType();
87738846
8847 const target = sema.mod.getTarget();
87748848 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {
8775 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty});
8849 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(target)});
87768850 }
87778851
87788852 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
......@@ -8824,15 +8898,14 @@ fn zirOverflowArithmetic(
88248898 const ptr = sema.resolveInst(extra.ptr);
88258899
88268900 const lhs_ty = sema.typeOf(lhs);
8901 const target = sema.mod.getTarget();
88278902
88288903 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.
88298904 const dest_ty = lhs_ty;
88308905 if (dest_ty.zigTypeTag() != .Int) {
8831 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty});
8906 return sema.fail(block, src, "expected integer type, found '{}'", .{dest_ty.fmt(target)});
88328907 }
88338908
8834 const target = sema.mod.getTarget();
8835
88368909 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
88378910 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);
88388911
......@@ -8894,7 +8967,7 @@ fn zirOverflowArithmetic(
88948967 if (!lhs_val.isUndef()) {
88958968 if (lhs_val.compareWithZero(.eq)) {
88968969 break :result .{ .overflowed = .no, .wrapped = lhs };
8897 } else if (lhs_val.compare(.eq, Value.one, dest_ty)) {
8970 } else if (lhs_val.compare(.eq, Value.one, dest_ty, target)) {
88988971 break :result .{ .overflowed = .no, .wrapped = rhs };
88998972 }
89008973 }
......@@ -8904,7 +8977,7 @@ fn zirOverflowArithmetic(
89048977 if (!rhs_val.isUndef()) {
89058978 if (rhs_val.compareWithZero(.eq)) {
89068979 break :result .{ .overflowed = .no, .wrapped = rhs };
8907 } else if (rhs_val.compare(.eq, Value.one, dest_ty)) {
8980 } else if (rhs_val.compare(.eq, Value.one, dest_ty, target)) {
89088981 break :result .{ .overflowed = .no, .wrapped = lhs };
89098982 }
89108983 }
......@@ -9079,7 +9152,7 @@ fn analyzeArithmetic(
90799152 if (is_int) {
90809153 return sema.addConstant(
90819154 resolved_type,
9082 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena),
9155 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target),
90839156 );
90849157 } else {
90859158 return sema.addConstant(
......@@ -9132,7 +9205,7 @@ fn analyzeArithmetic(
91329205 }
91339206 if (maybe_lhs_val) |lhs_val| {
91349207 const val = if (scalar_tag == .ComptimeInt)
9135 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena)
9208 try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target)
91369209 else
91379210 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target);
91389211
......@@ -9172,7 +9245,7 @@ fn analyzeArithmetic(
91729245 if (is_int) {
91739246 return sema.addConstant(
91749247 resolved_type,
9175 try lhs_val.intSub(rhs_val, resolved_type, sema.arena),
9248 try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target),
91769249 );
91779250 } else {
91789251 return sema.addConstant(
......@@ -9225,7 +9298,7 @@ fn analyzeArithmetic(
92259298 }
92269299 if (maybe_rhs_val) |rhs_val| {
92279300 const val = if (scalar_tag == .ComptimeInt)
9228 try lhs_val.intSub(rhs_val, resolved_type, sema.arena)
9301 try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target)
92299302 else
92309303 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target);
92319304
......@@ -9275,7 +9348,7 @@ fn analyzeArithmetic(
92759348 if (lhs_val.isUndef()) {
92769349 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
92779350 if (maybe_rhs_val) |rhs_val| {
9278 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {
9351 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
92799352 return sema.addConstUndef(resolved_type);
92809353 }
92819354 }
......@@ -9288,7 +9361,7 @@ fn analyzeArithmetic(
92889361 if (is_int) {
92899362 return sema.addConstant(
92909363 resolved_type,
9291 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),
9364 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
92929365 );
92939366 } else {
92949367 return sema.addConstant(
......@@ -9350,7 +9423,7 @@ fn analyzeArithmetic(
93509423 if (lhs_val.isUndef()) {
93519424 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
93529425 if (maybe_rhs_val) |rhs_val| {
9353 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {
9426 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
93549427 return sema.addConstUndef(resolved_type);
93559428 }
93569429 }
......@@ -9363,7 +9436,7 @@ fn analyzeArithmetic(
93639436 if (is_int) {
93649437 return sema.addConstant(
93659438 resolved_type,
9366 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),
9439 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
93679440 );
93689441 } else {
93699442 return sema.addConstant(
......@@ -9413,7 +9486,7 @@ fn analyzeArithmetic(
94139486 if (lhs_val.isUndef()) {
94149487 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
94159488 if (maybe_rhs_val) |rhs_val| {
9416 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) {
9489 if (rhs_val.compare(.neq, Value.negative_one, rhs_ty, target)) {
94179490 return sema.addConstUndef(resolved_type);
94189491 }
94199492 }
......@@ -9426,7 +9499,7 @@ fn analyzeArithmetic(
94269499 if (is_int) {
94279500 return sema.addConstant(
94289501 resolved_type,
9429 try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena),
9502 try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena, target),
94309503 );
94319504 } else {
94329505 return sema.addConstant(
......@@ -9477,7 +9550,7 @@ fn analyzeArithmetic(
94779550 // TODO: emit compile error if there is a remainder
94789551 return sema.addConstant(
94799552 resolved_type,
9480 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena),
9553 try lhs_val.intDiv(rhs_val, resolved_type, sema.arena, target),
94819554 );
94829555 } else {
94839556 // TODO: emit compile error if there is a remainder
......@@ -9503,7 +9576,7 @@ fn analyzeArithmetic(
95039576 if (lhs_val.compareWithZero(.eq)) {
95049577 return sema.addConstant(resolved_type, Value.zero);
95059578 }
9506 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {
9579 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
95079580 return casted_rhs;
95089581 }
95099582 }
......@@ -9519,7 +9592,7 @@ fn analyzeArithmetic(
95199592 if (rhs_val.compareWithZero(.eq)) {
95209593 return sema.addConstant(resolved_type, Value.zero);
95219594 }
9522 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {
9595 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
95239596 return casted_lhs;
95249597 }
95259598 if (maybe_lhs_val) |lhs_val| {
......@@ -9533,7 +9606,7 @@ fn analyzeArithmetic(
95339606 if (is_int) {
95349607 return sema.addConstant(
95359608 resolved_type,
9536 try lhs_val.intMul(rhs_val, resolved_type, sema.arena),
9609 try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target),
95379610 );
95389611 } else {
95399612 return sema.addConstant(
......@@ -9554,7 +9627,7 @@ fn analyzeArithmetic(
95549627 if (lhs_val.compareWithZero(.eq)) {
95559628 return sema.addConstant(resolved_type, Value.zero);
95569629 }
9557 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {
9630 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
95589631 return casted_rhs;
95599632 }
95609633 }
......@@ -9566,7 +9639,7 @@ fn analyzeArithmetic(
95669639 if (rhs_val.compareWithZero(.eq)) {
95679640 return sema.addConstant(resolved_type, Value.zero);
95689641 }
9569 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {
9642 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
95709643 return casted_lhs;
95719644 }
95729645 if (maybe_lhs_val) |lhs_val| {
......@@ -9590,7 +9663,7 @@ fn analyzeArithmetic(
95909663 if (lhs_val.compareWithZero(.eq)) {
95919664 return sema.addConstant(resolved_type, Value.zero);
95929665 }
9593 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {
9666 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
95949667 return casted_rhs;
95959668 }
95969669 }
......@@ -9602,7 +9675,7 @@ fn analyzeArithmetic(
96029675 if (rhs_val.compareWithZero(.eq)) {
96039676 return sema.addConstant(resolved_type, Value.zero);
96049677 }
9605 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {
9678 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
96069679 return casted_lhs;
96079680 }
96089681 if (maybe_lhs_val) |lhs_val| {
......@@ -9611,7 +9684,7 @@ fn analyzeArithmetic(
96119684 }
96129685
96139686 const val = if (scalar_tag == .ComptimeInt)
9614 try lhs_val.intMul(rhs_val, resolved_type, sema.arena)
9687 try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target)
96159688 else
96169689 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target);
96179690
......@@ -9652,7 +9725,7 @@ fn analyzeArithmetic(
96529725 return sema.failWithDivideByZero(block, rhs_src);
96539726 }
96549727 if (maybe_lhs_val) |lhs_val| {
9655 const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena);
9728 const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target);
96569729 // If this answer could possibly be different by doing `intMod`,
96579730 // we must emit a compile error. Otherwise, it's OK.
96589731 if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and
......@@ -9731,7 +9804,7 @@ fn analyzeArithmetic(
97319804 if (maybe_lhs_val) |lhs_val| {
97329805 return sema.addConstant(
97339806 resolved_type,
9734 try lhs_val.intRem(rhs_val, resolved_type, sema.arena),
9807 try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target),
97359808 );
97369809 }
97379810 break :rs .{ .src = lhs_src, .air_tag = .rem };
......@@ -9788,7 +9861,7 @@ fn analyzeArithmetic(
97889861 if (maybe_lhs_val) |lhs_val| {
97899862 return sema.addConstant(
97909863 resolved_type,
9791 try lhs_val.intMod(rhs_val, resolved_type, sema.arena),
9864 try lhs_val.intMod(rhs_val, resolved_type, sema.arena, target),
97929865 );
97939866 }
97949867 break :rs .{ .src = lhs_src, .air_tag = .mod };
......@@ -9839,6 +9912,7 @@ fn analyzePtrArithmetic(
98399912 // coerce to isize instead of usize.
98409913 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
98419914 // TODO adjust the return type according to alignment and other factors
9915 const target = sema.mod.getTarget();
98429916 const runtime_src = rs: {
98439917 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
98449918 if (try sema.resolveMaybeUndefVal(block, offset_src, offset)) |offset_val| {
......@@ -9849,11 +9923,10 @@ fn analyzePtrArithmetic(
98499923 return sema.addConstUndef(new_ptr_ty);
98509924 }
98519925
9852 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt());
9926 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(target));
98539927 // TODO I tried to put this check earlier but it the LLVM backend generate invalid instructinons
98549928 if (offset_int == 0) return ptr;
9855 if (ptr_val.getUnsignedInt()) |addr| {
9856 const target = sema.mod.getTarget();
9929 if (try ptr_val.getUnsignedIntAdvanced(target, sema.kit(block, ptr_src))) |addr| {
98579930 const ptr_child_ty = ptr_ty.childType();
98589931 const elem_ty = if (ptr_ty.isSinglePointer() and ptr_child_ty.zigTypeTag() == .Array)
98599932 ptr_child_ty.childType()
......@@ -9872,7 +9945,7 @@ fn analyzePtrArithmetic(
98729945 if (air_tag == .ptr_sub) {
98739946 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
98749947 }
9875 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int);
9948 const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int, target);
98769949 return sema.addConstant(new_ptr_ty, new_ptr_val);
98779950 } else break :rs offset_src;
98789951 } else break :rs ptr_src;
......@@ -10035,6 +10108,7 @@ fn zirCmpEq(
1003510108 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
1003610109 const lhs = sema.resolveInst(extra.lhs);
1003710110 const rhs = sema.resolveInst(extra.rhs);
10111 const target = sema.mod.getTarget();
1003810112
1003910113 const lhs_ty = sema.typeOf(lhs);
1004010114 const rhs_ty = sema.typeOf(rhs);
......@@ -10059,7 +10133,7 @@ fn zirCmpEq(
1005910133
1006010134 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
1006110135 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
10062 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type});
10136 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(target)});
1006310137 }
1006410138
1006510139 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
......@@ -10099,7 +10173,7 @@ fn zirCmpEq(
1009910173 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
1010010174 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
1010110175 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);
10102 if (lhs_as_type.eql(rhs_as_type) == (op == .eq)) {
10176 if (lhs_as_type.eql(rhs_as_type, target) == (op == .eq)) {
1010310177 return Air.Inst.Ref.bool_true;
1010410178 } else {
1010510179 return Air.Inst.Ref.bool_false;
......@@ -10176,9 +10250,10 @@ fn analyzeCmp(
1017610250 }
1017710251 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1017810252 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
10253 const target = sema.mod.getTarget();
1017910254 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
1018010255 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{
10181 @tagName(op), resolved_type,
10256 @tagName(op), resolved_type.fmt(target),
1018210257 });
1018310258 }
1018410259 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
......@@ -10196,6 +10271,7 @@ fn cmpSelf(
1019610271 rhs_src: LazySrcLoc,
1019710272) CompileError!Air.Inst.Ref {
1019810273 const resolved_type = sema.typeOf(casted_lhs);
10274 const target = sema.mod.getTarget();
1019910275 const runtime_src: LazySrcLoc = src: {
1020010276 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
1020110277 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
......@@ -10204,11 +10280,11 @@ fn cmpSelf(
1020410280
1020510281 if (resolved_type.zigTypeTag() == .Vector) {
1020610282 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");
10207 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena);
10283 const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena, target);
1020810284 return sema.addConstant(result_ty, cmp_val);
1020910285 }
1021010286
10211 if (lhs_val.compare(op, rhs_val, resolved_type)) {
10287 if (lhs_val.compare(op, rhs_val, resolved_type, target)) {
1021210288 return Air.Inst.Ref.bool_true;
1021310289 } else {
1021410290 return Air.Inst.Ref.bool_false;
......@@ -10276,7 +10352,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1027610352 .Null,
1027710353 .BoundFn,
1027810354 .Opaque,
10279 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty}),
10355 => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty.fmt(target)}),
1028010356
1028110357 .Type,
1028210358 .EnumLiteral,
......@@ -11365,11 +11441,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1136511441 },
1136611442 else => {},
1136711443 }
11444 const target = sema.mod.getTarget();
1136811445 return sema.fail(
1136911446 block,
1137011447 src,
1137111448 "bit shifting operation expected integer type, found '{}'",
11372 .{operand},
11449 .{operand.fmt(target)},
1137311450 );
1137411451}
1137511452
......@@ -11786,6 +11863,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1178611863 const elem_ty_src: LazySrcLoc = .unneeded;
1178711864 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
1178811865 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
11866 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
11867 const target = sema.mod.getTarget();
1178911868
1179011869 var extra_i = extra.end;
1179111870
......@@ -11795,10 +11874,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1179511874 break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val;
1179611875 } else null;
1179711876
11798 const abi_align = if (inst_data.flags.has_align) blk: {
11877 const abi_align: u32 = if (inst_data.flags.has_align) blk: {
1179911878 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
1180011879 extra_i += 1;
11801 const abi_align = try sema.resolveInt(block, .unneeded, ref, Type.u32);
11880 const coerced = try sema.coerce(block, Type.u32, sema.resolveInst(ref), src);
11881 const val = try sema.resolveConstValue(block, src, coerced);
11882 // Check if this happens to be the lazy alignment of our element type, in
11883 // which case we can make this 0 without resolving it.
11884 if (val.castTag(.lazy_align)) |payload| {
11885 if (payload.data.eql(unresolved_elem_ty, target)) {
11886 break :blk 0;
11887 }
11888 }
11889 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
1180211890 break :blk @intCast(u32, abi_align);
1180311891 } else 0;
1180411892
......@@ -11826,7 +11914,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1182611914 return sema.fail(block, src, "bit offset starts after end of host integer", .{});
1182711915 }
1182811916
11829 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
1183011917 const elem_ty = if (abi_align == 0)
1183111918 unresolved_elem_ty
1183211919 else t: {
......@@ -11834,7 +11921,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1183411921 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
1183511922 break :t elem_ty;
1183611923 };
11837 const target = sema.mod.getTarget();
1183811924 const ty = try Type.ptr(sema.arena, target, .{
1183911925 .pointee_type = elem_ty,
1184011926 .sentinel = sentinel,
......@@ -12414,6 +12500,7 @@ fn fieldType(
1241412500 ty_src: LazySrcLoc,
1241512501) CompileError!Air.Inst.Ref {
1241612502 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
12503 const target = sema.mod.getTarget();
1241712504 switch (resolved_ty.zigTypeTag()) {
1241812505 .Struct => {
1241912506 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
......@@ -12428,7 +12515,7 @@ fn fieldType(
1242812515 return sema.addType(field.ty);
1242912516 },
1243012517 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
12431 resolved_ty,
12518 resolved_ty.fmt(target),
1243212519 }),
1243312520 }
1243412521}
......@@ -12459,11 +12546,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1245912546 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1246012547 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1246112548 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
12462 const resolved_ty = try sema.resolveTypeFields(block, operand_src, ty);
12463 try sema.resolveTypeLayout(block, operand_src, resolved_ty);
1246412549 const target = sema.mod.getTarget();
12465 const abi_align = resolved_ty.abiAlignment(target);
12466 return sema.addIntUnsigned(Type.comptime_int, abi_align);
12550 return sema.addConstant(
12551 Type.comptime_int,
12552 try ty.lazyAbiAlignment(target, sema.arena),
12553 );
1246712554}
1246812555
1246912556fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -12509,6 +12596,7 @@ fn zirUnaryMath(
1250912596 const operand = sema.resolveInst(inst_data.operand);
1251012597 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1251112598 const operand_ty = sema.typeOf(operand);
12599 const target = sema.mod.getTarget();
1251212600
1251312601 switch (operand_ty.zigTypeTag()) {
1251412602 .ComptimeFloat, .Float => {},
......@@ -12516,13 +12604,12 @@ fn zirUnaryMath(
1251612604 const scalar_ty = operand_ty.scalarType();
1251712605 switch (scalar_ty.zigTypeTag()) {
1251812606 .ComptimeFloat, .Float => {},
12519 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty}),
12607 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(target)}),
1252012608 }
1252112609 },
12522 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty}),
12610 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(target)}),
1252312611 }
1252412612
12525 const target = sema.mod.getTarget();
1252612613 switch (operand_ty.zigTypeTag()) {
1252712614 .Vector => {
1252812615 const scalar_ty = operand_ty.scalarType();
......@@ -12568,6 +12655,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1256812655 const src = inst_data.src();
1256912656 const operand = sema.resolveInst(inst_data.operand);
1257012657 const operand_ty = sema.typeOf(operand);
12658 const target = sema.mod.getTarget();
1257112659
1257212660 try sema.resolveTypeLayout(block, operand_src, operand_ty);
1257312661 const enum_ty = switch (operand_ty.zigTypeTag()) {
......@@ -12590,13 +12678,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1259012678 return sema.failWithOwnedErrorMsg(block, msg);
1259112679 },
1259212680 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{
12593 operand_ty,
12681 operand_ty.fmt(target),
1259412682 }),
1259512683 };
1259612684 const enum_decl = enum_ty.getOwnerDecl();
1259712685 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
1259812686 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
12599 const field_index = enum_ty.enumTagFieldIndex(val) orelse {
12687 const field_index = enum_ty.enumTagFieldIndex(val, target) orelse {
1260012688 const msg = msg: {
1260112689 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{
1260212690 casted_operand, enum_decl.name,
......@@ -12626,8 +12714,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1262612714 const val = try sema.resolveConstValue(block, operand_src, type_info);
1262712715 const union_val = val.cast(Value.Payload.Union).?.data;
1262812716 const tag_ty = type_info_ty.unionTagType().?;
12629 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag).?;
1263012717 const target = sema.mod.getTarget();
12718 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, target).?;
1263112719 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1263212720 .Type => return Air.Inst.Ref.type_type,
1263312721 .Void => return Air.Inst.Ref.void_type,
......@@ -12646,7 +12734,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1264612734 const bits_val = struct_val[1];
1264712735
1264812736 const signedness = signedness_val.toEnum(std.builtin.Signedness);
12649 const bits = @intCast(u16, bits_val.toUnsignedInt());
12737 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
1265012738 const ty = switch (signedness) {
1265112739 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
1265212740 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
......@@ -12659,7 +12747,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1265912747 const len_val = struct_val[0];
1266012748 const child_val = struct_val[1];
1266112749
12662 const len = len_val.toUnsignedInt();
12750 const len = len_val.toUnsignedInt(target);
1266312751 var buffer: Value.ToTypeBuffer = undefined;
1266412752 const child_ty = child_val.toType(&buffer);
1266512753
......@@ -12672,7 +12760,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1267212760 // bits: comptime_int,
1267312761 const bits_val = struct_val[0];
1267412762
12675 const bits = @intCast(u16, bits_val.toUnsignedInt());
12763 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
1267612764 const ty = switch (bits) {
1267712765 16 => Type.@"f16",
1267812766 32 => Type.@"f32",
......@@ -12717,7 +12805,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1271712805 .size = ptr_size,
1271812806 .mutable = !is_const_val.toBool(),
1271912807 .@"volatile" = is_volatile_val.toBool(),
12720 .@"align" = @intCast(u16, alignment_val.toUnsignedInt()), // TODO: Validate this value.
12808 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
1272112809 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
1272212810 .pointee_type = try child_ty.copy(sema.arena),
1272312811 .@"allowzero" = is_allowzero_val.toBool(),
......@@ -12735,7 +12823,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1273512823 // sentinel: ?*const anyopaque,
1273612824 const sentinel_val = struct_val[2];
1273712825
12738 const len = len_val.toUnsignedInt();
12826 const len = len_val.toUnsignedInt(target);
1273912827 var buffer: Value.ToTypeBuffer = undefined;
1274012828 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
1274112829 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
......@@ -12746,7 +12834,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1274612834 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
1274712835 } else null;
1274812836
12749 const ty = try Type.array(sema.arena, len, sentinel, child_ty);
12837 const ty = try Type.array(sema.arena, len, sentinel, child_ty, target);
1275012838 return sema.addType(ty);
1275112839 },
1275212840 .Optional => {
......@@ -12796,7 +12884,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1279612884 const name_val = struct_val[0];
1279712885
1279812886 names.putAssumeCapacityNoClobber(
12799 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
12887 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
1280012888 {},
1280112889 );
1280212890 }
......@@ -12817,7 +12905,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1281712905 const is_tuple_val = struct_val[3];
1281812906
1281912907 // Decls
12820 if (decls_val.sliceLen() > 0) {
12908 if (decls_val.sliceLen(target) > 0) {
1282112909 return sema.fail(block, src, "reified structs must have no decls", .{});
1282212910 }
1282312911
......@@ -12847,7 +12935,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1284712935 }
1284812936
1284912937 // Decls
12850 if (decls_val.sliceLen() > 0) {
12938 if (decls_val.sliceLen(target) > 0) {
1285112939 return sema.fail(block, src, "reified enums must have no decls", .{});
1285212940 }
1285312941
......@@ -12898,11 +12986,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1289812986 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1289912987
1290012988 // Fields
12901 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
12989 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1290212990 if (fields_len > 0) {
1290312991 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1290412992 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
1290512993 .ty = enum_obj.tag_ty,
12994 .target = target,
1290612995 });
1290712996
1290812997 var i: usize = 0;
......@@ -12918,6 +13007,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1291813007 const field_name = try name_val.toAllocatedBytes(
1291913008 Type.initTag(.const_slice_u8),
1292013009 new_decl_arena_allocator,
13010 target,
1292113011 );
1292213012
1292313013 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -12929,6 +13019,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1292913019 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
1293013020 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
1293113021 .ty = enum_obj.tag_ty,
13022 .target = target,
1293213023 });
1293313024 }
1293413025 }
......@@ -12942,7 +13033,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1294213033 const decls_val = struct_val[0];
1294313034
1294413035 // Decls
12945 if (decls_val.sliceLen() > 0) {
13036 if (decls_val.sliceLen(target) > 0) {
1294613037 return sema.fail(block, src, "reified opaque must have no decls", .{});
1294713038 }
1294813039
......@@ -12993,7 +13084,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1299313084 const decls_val = struct_val[3];
1299413085
1299513086 // Decls
12996 if (decls_val.sliceLen() > 0) {
13087 if (decls_val.sliceLen(target) > 0) {
1299713088 return sema.fail(block, src, "reified unions must have no decls", .{});
1299813089 }
1299913090
......@@ -13033,7 +13124,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1303313124 };
1303413125
1303513126 // Tag type
13036 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13127 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1303713128 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
1303813129 var buffer: Value.ToTypeBuffer = undefined;
1303913130 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
......@@ -13058,6 +13149,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1305813149 const field_name = try name_val.toAllocatedBytes(
1305913150 Type.initTag(.const_slice_u8),
1306013151 new_decl_arena_allocator,
13152 target,
1306113153 );
1306213154
1306313155 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -13069,7 +13161,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1306913161 var buffer: Value.ToTypeBuffer = undefined;
1307013162 gop.value_ptr.* = .{
1307113163 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13072 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),
13164 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
1307313165 };
1307413166 }
1307513167 }
......@@ -13089,7 +13181,9 @@ fn reifyTuple(
1308913181 src: LazySrcLoc,
1309013182 fields_val: Value,
1309113183) CompileError!Air.Inst.Ref {
13092 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13184 const target = sema.mod.getTarget();
13185
13186 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1309313187 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));
1309413188
1309513189 const types = try sema.arena.alloc(Type, fields_len);
......@@ -13114,6 +13208,7 @@ fn reifyTuple(
1311413208 const field_name = try name_val.toAllocatedBytes(
1311513209 Type.initTag(.const_slice_u8),
1311613210 sema.arena,
13211 target,
1311713212 );
1311813213
1311913214 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
......@@ -13197,8 +13292,10 @@ fn reifyStruct(
1319713292 },
1319813293 };
1319913294
13295 const target = sema.mod.getTarget();
13296
1320013297 // Fields
13201 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13298 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1320213299 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1320313300 var i: usize = 0;
1320413301 while (i < fields_len) : (i += 1) {
......@@ -13219,6 +13316,7 @@ fn reifyStruct(
1321913316 const field_name = try name_val.toAllocatedBytes(
1322013317 Type.initTag(.const_slice_u8),
1322113318 new_decl_arena_allocator,
13319 target,
1322213320 );
1322313321
1322413322 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -13238,7 +13336,7 @@ fn reifyStruct(
1323813336 var buffer: Value.ToTypeBuffer = undefined;
1323913337 gop.value_ptr.* = .{
1324013338 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13241 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),
13339 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
1324213340 .default_val = default_val,
1324313341 .is_comptime = is_comptime_val.toBool(),
1324413342 .offset = undefined,
......@@ -13257,7 +13355,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1325713355 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
1325813356 defer anon_decl.deinit();
1325913357
13260 const bytes = try ty.nameAllocArena(anon_decl.arena());
13358 const target = sema.mod.getTarget();
13359 const bytes = try ty.nameAllocArena(anon_decl.arena(), target);
1326113360
1326213361 const new_decl = try anon_decl.finish(
1326313362 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
......@@ -13296,7 +13395,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1329613395 const target = sema.mod.getTarget();
1329713396 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {
1329813397 error.FloatCannotFit => {
13299 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });
13398 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{
13399 std.math.floor(val.toFloat(f64)),
13400 dest_ty.fmt(target),
13401 });
1330013402 },
1330113403 else => |e| return e,
1330213404 };
......@@ -13344,13 +13446,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1334413446 try sema.checkPtrType(block, type_src, type_res);
1334513447 try sema.resolveTypeLayout(block, src, type_res.elemType2());
1334613448 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
13449 const target = sema.mod.getTarget();
1334713450
1334813451 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
13349 const addr = val.toUnsignedInt();
13452 const addr = val.toUnsignedInt(target);
1335013453 if (!type_res.isAllowzeroPtr() and addr == 0)
13351 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res});
13454 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(target)});
1335213455 if (addr != 0 and addr % ptr_align != 0)
13353 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res});
13456 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(target)});
1335413457
1335513458 const val_payload = try sema.arena.create(Value.Payload.U64);
1335613459 val_payload.* = .{
......@@ -13394,6 +13497,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1339413497 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
1339513498 const operand = sema.resolveInst(extra.rhs);
1339613499 const operand_ty = sema.typeOf(operand);
13500 const target = sema.mod.getTarget();
1339713501 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
1339813502 try sema.checkErrorSetType(block, operand_src, operand_ty);
1339913503
......@@ -13407,7 +13511,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1340713511 block,
1340813512 src,
1340913513 "error.{s} not a member of error set '{}'",
13410 .{ error_name, dest_ty },
13514 .{ error_name, dest_ty.fmt(target) },
1341113515 );
1341213516 }
1341313517 }
......@@ -13502,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1350213606
1350313607 if (operand_info.signedness != dest_info.signedness) {
1350413608 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
13505 @tagName(dest_info.signedness), operand_ty,
13609 @tagName(dest_info.signedness), operand_ty.fmt(target),
1350613610 });
1350713611 }
1350813612 if (operand_info.bits < dest_info.bits) {
......@@ -13511,7 +13615,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1351113615 block,
1351213616 src,
1351313617 "destination type '{}' has more bits than source type '{}'",
13514 .{ dest_ty, operand_ty },
13618 .{ dest_ty.fmt(target), operand_ty.fmt(target) },
1351513619 );
1351613620 errdefer msg.destroy(sema.gpa);
1351713621 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
......@@ -13531,14 +13635,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1353113635 if (!is_vector) {
1353213636 return sema.addConstant(
1353313637 dest_ty,
13534 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits),
13638 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, target),
1353513639 );
1353613640 }
1353713641 var elem_buf: Value.ElemValueBuffer = undefined;
1353813642 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
1353913643 for (elems) |*elem, i| {
1354013644 const elem_val = val.elemValueBuffer(i, &elem_buf);
13541 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits);
13645 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);
1354213646 }
1354313647 return sema.addConstant(
1354413648 dest_ty,
......@@ -13653,7 +13757,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1365313757 block,
1365413758 ty_src,
1365513759 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
13656 .{ scalar_ty, bits },
13760 .{ scalar_ty.fmt(target), bits },
1365713761 );
1365813762 }
1365913763
......@@ -13765,6 +13869,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1376513869
1376613870 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
1376713871 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
13872 const target = sema.mod.getTarget();
1376813873
1376913874 try sema.resolveTypeLayout(block, lhs_src, ty);
1377013875 if (ty.tag() != .@"struct") {
......@@ -13772,7 +13877,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1377213877 block,
1377313878 lhs_src,
1377413879 "expected struct type, found '{}'",
13775 .{ty},
13880 .{ty.fmt(target)},
1377613881 );
1377713882 }
1377813883
......@@ -13782,11 +13887,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1378213887 block,
1378313888 rhs_src,
1378413889 "struct '{}' has no field '{s}'",
13785 .{ ty, field_name },
13890 .{ ty.fmt(target), field_name },
1378613891 );
1378713892 };
1378813893
13789 const target = sema.mod.getTarget();
1379013894 switch (ty.containerLayout()) {
1379113895 .Packed => {
1379213896 var bit_sum: u64 = 0;
......@@ -13809,18 +13913,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1380913913}
1381013914
1381113915fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
13916 const target = sema.mod.getTarget();
1381213917 switch (ty.zigTypeTag()) {
1381313918 .Struct, .Enum, .Union, .Opaque => return,
13814 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty}),
13919 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(target)}),
1381513920 }
1381613921}
1381713922
1381813923/// Returns `true` if the type was a comptime_int.
1381913924fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
13925 const target = sema.mod.getTarget();
1382013926 switch (try ty.zigTypeTagOrPoison()) {
1382113927 .ComptimeInt => return true,
1382213928 .Int => return false,
13823 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),
13929 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(target)}),
1382413930 }
1382513931}
1382613932
......@@ -13830,6 +13936,7 @@ fn checkPtrOperand(
1383013936 ty_src: LazySrcLoc,
1383113937 ty: Type,
1383213938) CompileError!void {
13939 const target = sema.mod.getTarget();
1383313940 switch (ty.zigTypeTag()) {
1383413941 .Pointer => return,
1383513942 .Fn => {
......@@ -13838,7 +13945,7 @@ fn checkPtrOperand(
1383813945 block,
1383913946 ty_src,
1384013947 "expected pointer, found {}",
13841 .{ty},
13948 .{ty.fmt(target)},
1384213949 );
1384313950 errdefer msg.destroy(sema.gpa);
1384413951
......@@ -13851,7 +13958,7 @@ fn checkPtrOperand(
1385113958 .Optional => if (ty.isPtrLikeOptional()) return,
1385213959 else => {},
1385313960 }
13854 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
13961 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
1385513962}
1385613963
1385713964fn checkPtrType(
......@@ -13860,6 +13967,7 @@ fn checkPtrType(
1386013967 ty_src: LazySrcLoc,
1386113968 ty: Type,
1386213969) CompileError!void {
13970 const target = sema.mod.getTarget();
1386313971 switch (ty.zigTypeTag()) {
1386413972 .Pointer => return,
1386513973 .Fn => {
......@@ -13868,7 +13976,7 @@ fn checkPtrType(
1386813976 block,
1386913977 ty_src,
1387013978 "expected pointer type, found '{}'",
13871 .{ty},
13979 .{ty.fmt(target)},
1387213980 );
1387313981 errdefer msg.destroy(sema.gpa);
1387413982
......@@ -13881,7 +13989,7 @@ fn checkPtrType(
1388113989 .Optional => if (ty.isPtrLikeOptional()) return,
1388213990 else => {},
1388313991 }
13884 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
13992 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
1388513993}
1388613994
1388713995fn checkVectorElemType(
......@@ -13894,7 +14002,8 @@ fn checkVectorElemType(
1389414002 .Int, .Float, .Bool => return,
1389514003 else => if (ty.isPtrAtRuntime()) return,
1389614004 }
13897 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty});
14005 const target = sema.mod.getTarget();
14006 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(target)});
1389814007}
1389914008
1390014009fn checkFloatType(
......@@ -13903,9 +14012,10 @@ fn checkFloatType(
1390314012 ty_src: LazySrcLoc,
1390414013 ty: Type,
1390514014) CompileError!void {
14015 const target = sema.mod.getTarget();
1390614016 switch (ty.zigTypeTag()) {
1390714017 .ComptimeInt, .ComptimeFloat, .Float => {},
13908 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty}),
14018 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(target)}),
1390914019 }
1391014020}
1391114021
......@@ -13915,13 +14025,14 @@ fn checkNumericType(
1391514025 ty_src: LazySrcLoc,
1391614026 ty: Type,
1391714027) CompileError!void {
14028 const target = sema.mod.getTarget();
1391814029 switch (ty.zigTypeTag()) {
1391914030 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
1392014031 .Vector => switch (ty.childType().zigTypeTag()) {
1392114032 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
1392214033 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
1392314034 },
13924 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty}),
14035 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(target)}),
1392514036 }
1392614037}
1392714038
......@@ -13957,7 +14068,7 @@ fn checkAtomicOperandType(
1395714068 block,
1395814069 ty_src,
1395914070 "expected bool, integer, float, enum, or pointer type; found {}",
13960 .{ty},
14071 .{ty.fmt(target)},
1396114072 );
1396214073 },
1396314074 };
......@@ -14021,6 +14132,7 @@ fn checkIntOrVector(
1402114132 operand_src: LazySrcLoc,
1402214133) CompileError!Type {
1402314134 const operand_ty = sema.typeOf(operand);
14135 const target = sema.mod.getTarget();
1402414136 switch (try operand_ty.zigTypeTagOrPoison()) {
1402514137 .Int => return operand_ty,
1402614138 .Vector => {
......@@ -14028,12 +14140,12 @@ fn checkIntOrVector(
1402814140 switch (try elem_ty.zigTypeTagOrPoison()) {
1402914141 .Int => return elem_ty,
1403014142 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14031 elem_ty,
14143 elem_ty.fmt(target),
1403214144 }),
1403314145 }
1403414146 },
1403514147 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14036 operand_ty,
14148 operand_ty.fmt(target),
1403714149 }),
1403814150 }
1403914151}
......@@ -14045,6 +14157,7 @@ fn checkIntOrVectorAllowComptime(
1404514157 operand_src: LazySrcLoc,
1404614158) CompileError!Type {
1404714159 const operand_ty = sema.typeOf(operand);
14160 const target = sema.mod.getTarget();
1404814161 switch (try operand_ty.zigTypeTagOrPoison()) {
1404914162 .Int, .ComptimeInt => return operand_ty,
1405014163 .Vector => {
......@@ -14052,20 +14165,21 @@ fn checkIntOrVectorAllowComptime(
1405214165 switch (try elem_ty.zigTypeTagOrPoison()) {
1405314166 .Int, .ComptimeInt => return elem_ty,
1405414167 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14055 elem_ty,
14168 elem_ty.fmt(target),
1405614169 }),
1405714170 }
1405814171 },
1405914172 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14060 operand_ty,
14173 operand_ty.fmt(target),
1406114174 }),
1406214175 }
1406314176}
1406414177
1406514178fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14179 const target = sema.mod.getTarget();
1406614180 switch (ty.zigTypeTag()) {
1406714181 .ErrorSet => return,
14068 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),
14182 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(target)}),
1406914183 }
1407014184}
1407114185
......@@ -14138,9 +14252,10 @@ fn checkVectorizableBinaryOperands(
1413814252 return sema.failWithOwnedErrorMsg(block, msg);
1413914253 }
1414014254 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
14255 const target = sema.mod.getTarget();
1414114256 const msg = msg: {
1414214257 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
14143 lhs_ty, rhs_ty,
14258 lhs_ty.fmt(target), rhs_ty.fmt(target),
1414414259 });
1414514260 errdefer msg.destroy(sema.gpa);
1414614261 if (lhs_zig_ty_tag == .Vector) {
......@@ -14179,8 +14294,9 @@ fn resolveExportOptions(
1417914294 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
1418014295 }
1418114296 const name_ty = Type.initTag(.const_slice_u8);
14297 const target = sema.mod.getTarget();
1418214298 return std.builtin.ExportOptions{
14183 .name = try name_val.toAllocatedBytes(name_ty, sema.arena),
14299 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, target),
1418414300 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
1418514301 .section = null, // TODO
1418614302 };
......@@ -14239,12 +14355,13 @@ fn zirCmpxchg(
1423914355 const ptr_ty = sema.typeOf(ptr);
1424014356 const elem_ty = ptr_ty.elemType();
1424114357 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
14358 const target = sema.mod.getTarget();
1424214359 if (elem_ty.zigTypeTag() == .Float) {
1424314360 return sema.fail(
1424414361 block,
1424514362 elem_ty_src,
1424614363 "expected bool, integer, enum, or pointer type; found '{}'",
14247 .{elem_ty},
14364 .{elem_ty.fmt(target)},
1424814365 );
1424914366 }
1425014367 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
......@@ -14281,7 +14398,7 @@ fn zirCmpxchg(
1428114398 return sema.addConstUndef(result_ty);
1428214399 }
1428314400 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
14284 const result_val = if (stored_val.eql(expected_val, elem_ty)) blk: {
14401 const result_val = if (stored_val.eql(expected_val, elem_ty, target)) blk: {
1428514402 try sema.storePtr(block, src, ptr, new_value);
1428614403 break :blk Value.@"null";
1428714404 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
......@@ -14343,9 +14460,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1434314460 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");
1434414461 const operand = sema.resolveInst(extra.rhs);
1434514462 const operand_ty = sema.typeOf(operand);
14463 const target = sema.mod.getTarget();
1434614464
1434714465 if (operand_ty.zigTypeTag() != .Vector) {
14348 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty});
14466 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(target)});
1434914467 }
1435014468
1435114469 const scalar_ty = operand_ty.childType();
......@@ -14355,13 +14473,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1435514473 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
1435614474 .Int, .Bool => {},
1435714475 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{
14358 @tagName(operation), operand_ty,
14476 @tagName(operation), operand_ty.fmt(target),
1435914477 }),
1436014478 },
1436114479 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
1436214480 .Int, .Float => {},
1436314481 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{
14364 @tagName(operation), operand_ty,
14482 @tagName(operation), operand_ty.fmt(target),
1436514483 }),
1436614484 },
1436714485 }
......@@ -14376,18 +14494,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1437614494 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
1437714495 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
1437814496
14379 const target = sema.mod.getTarget();
1438014497 var accum: Value = try operand_val.elemValue(sema.arena, 0);
1438114498 var elem_buf: Value.ElemValueBuffer = undefined;
1438214499 var i: u32 = 1;
1438314500 while (i < vec_len) : (i += 1) {
1438414501 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);
1438514502 switch (operation) {
14386 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena),
14387 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena),
14388 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena),
14389 .Min => accum = accum.numberMin(elem_val),
14390 .Max => accum = accum.numberMax(elem_val),
14503 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),
14504 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),
14505 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target),
14506 .Min => accum = accum.numberMin(elem_val, target),
14507 .Max => accum = accum.numberMax(elem_val, target),
1439114508 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),
1439214509 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),
1439314510 }
......@@ -14417,10 +14534,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1441714534 var b = sema.resolveInst(extra.b);
1441814535 var mask = sema.resolveInst(extra.mask);
1441914536 var mask_ty = sema.typeOf(mask);
14537 const target = sema.mod.getTarget();
1442014538
1442114539 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
1442214540 .Array, .Vector => sema.typeOf(mask).arrayLen(),
14423 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask)}),
14541 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(target)}),
1442414542 };
1442514543 mask_ty = try Type.Tag.vector.create(sema.arena, .{
1442614544 .len = mask_len,
......@@ -14452,20 +14570,21 @@ fn analyzeShuffle(
1445214570 .elem_type = elem_ty,
1445314571 });
1445414572
14573 const target = sema.mod.getTarget();
1445514574 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
1445614575 .Array, .Vector => sema.typeOf(a).arrayLen(),
1445714576 .Undefined => null,
1445814577 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{
14459 elem_ty,
14460 sema.typeOf(a),
14578 elem_ty.fmt(target),
14579 sema.typeOf(a).fmt(target),
1446114580 }),
1446214581 };
1446314582 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
1446414583 .Array, .Vector => sema.typeOf(b).arrayLen(),
1446514584 .Undefined => null,
1446614585 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{
14467 elem_ty,
14468 sema.typeOf(b),
14586 elem_ty.fmt(target),
14587 sema.typeOf(b).fmt(target),
1446914588 }),
1447014589 };
1447114590 if (maybe_a_len == null and maybe_b_len == null) {
......@@ -14513,7 +14632,7 @@ fn analyzeShuffle(
1451314632
1451414633 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{
1451514634 unsigned,
14516 operand_info[chosen][2],
14635 operand_info[chosen][2].fmt(target),
1451714636 });
1451814637
1451914638 if (chosen == 1) {
......@@ -14704,12 +14823,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1470414823 .Xchg => operand_val,
1470514824 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),
1470614825 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),
14707 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena),
14826 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena, target),
1470814827 .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),
14709 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena),
14710 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena),
14711 .Max => stored_val.numberMax (operand_val),
14712 .Min => stored_val.numberMin (operand_val),
14828 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena, target),
14829 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena, target),
14830 .Max => stored_val.numberMax (operand_val, target),
14831 .Min => stored_val.numberMin (operand_val, target),
1471314832 // zig fmt: on
1471414833 };
1471514834 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);
......@@ -14788,7 +14907,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1478814907
1478914908 switch (ty.zigTypeTag()) {
1479014909 .ComptimeFloat, .Float, .Vector => {},
14791 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}),
14910 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(target)}),
1479214911 }
1479314912
1479414913 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
......@@ -14814,7 +14933,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1481414933 const scalar_ty = ty.scalarType();
1481514934 switch (scalar_ty.zigTypeTag()) {
1481614935 .ComptimeFloat, .Float => {},
14817 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty}),
14936 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty.fmt(target)}),
1481814937 }
1481914938
1482014939 const vec_len = ty.vectorLen();
......@@ -14906,9 +15025,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1490615025 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);
1490715026 };
1490815027
15028 const target = sema.mod.getTarget();
1490915029 const args_ty = sema.typeOf(args);
1491015030 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {
14911 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty});
15031 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(target)});
1491215032 }
1491315033
1491415034 var resolved_args: []Air.Inst.Ref = undefined;
......@@ -14945,9 +15065,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1494515065 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);
1494615066 const field_ptr = sema.resolveInst(extra.field_ptr);
1494715067 const field_ptr_ty = sema.typeOf(field_ptr);
15068 const target = sema.mod.getTarget();
1494815069
1494915070 if (struct_ty.zigTypeTag() != .Struct) {
14950 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty});
15071 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(target)});
1495115072 }
1495215073 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1495315074
......@@ -14956,7 +15077,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1495615077 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
1495715078
1495815079 if (field_ptr_ty.zigTypeTag() != .Pointer) {
14959 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty});
15080 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(target)});
1496015081 }
1496115082 const field = struct_obj.fields.values()[field_index];
1496215083 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
......@@ -14973,7 +15094,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1497315094 ptr_ty_data.@"align" = field.abi_align;
1497415095 }
1497515096
14976 const target = sema.mod.getTarget();
1497715097 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1497815098 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
1497915099
......@@ -15042,8 +15162,9 @@ fn analyzeMinMax(
1504215162 .max => Value.numberMax,
1504315163 else => unreachable,
1504415164 };
15165 const target = sema.mod.getTarget();
1504515166 const vec_len = simd_op.len orelse {
15046 const result_val = opFunc(lhs_val, rhs_val);
15167 const result_val = opFunc(lhs_val, rhs_val, target);
1504715168 return sema.addConstant(simd_op.result_ty, result_val);
1504815169 };
1504915170 var lhs_buf: Value.ElemValueBuffer = undefined;
......@@ -15052,7 +15173,7 @@ fn analyzeMinMax(
1505215173 for (elems) |*elem, i| {
1505315174 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);
1505415175 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);
15055 elem.* = opFunc(lhs_elem_val, rhs_elem_val);
15176 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
1505615177 }
1505715178 return sema.addConstant(
1505815179 simd_op.result_ty,
......@@ -15078,17 +15199,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1507815199 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1507915200 const dest_ptr = sema.resolveInst(extra.dest);
1508015201 const dest_ptr_ty = sema.typeOf(dest_ptr);
15202 const target = sema.mod.getTarget();
1508115203
1508215204 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
1508315205 if (dest_ptr_ty.isConstPtr()) {
15084 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});
15206 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
1508515207 }
1508615208
1508715209 const uncasted_src_ptr = sema.resolveInst(extra.source);
1508815210 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);
1508915211 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);
1509015212 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
15091 const target = sema.mod.getTarget();
1509215213 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{
1509315214 .pointee_type = dest_ptr_ty.elemType2(),
1509415215 .@"align" = src_ptr_info.@"align",
......@@ -15136,9 +15257,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1513615257 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1513715258 const dest_ptr = sema.resolveInst(extra.dest);
1513815259 const dest_ptr_ty = sema.typeOf(dest_ptr);
15260 const target = sema.mod.getTarget();
1513915261 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
1514015262 if (dest_ptr_ty.isConstPtr()) {
15141 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});
15263 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
1514215264 }
1514315265 const elem_ty = dest_ptr_ty.elemType2();
1514415266 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);
......@@ -15452,6 +15574,7 @@ fn zirPrefetch(
1545215574 const ptr = sema.resolveInst(extra.lhs);
1545315575 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
1545415576 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);
15577 const target = sema.mod.getTarget();
1545515578
1545615579 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
1545715580 const rw_val = try sema.resolveConstValue(block, opts_src, rw);
......@@ -15459,7 +15582,7 @@ fn zirPrefetch(
1545915582
1546015583 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
1546115584 const locality_val = try sema.resolveConstValue(block, opts_src, locality);
15462 const locality_int = @intCast(u2, locality_val.toUnsignedInt());
15585 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1546315586
1546415587 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
1546515588 const cache_val = try sema.resolveConstValue(block, opts_src, cache);
......@@ -15492,6 +15615,7 @@ fn zirBuiltinExtern(
1549215615
1549315616 var ty = try sema.resolveType(block, ty_src, extra.lhs);
1549415617 const options_inst = sema.resolveInst(extra.rhs);
15618 const target = sema.mod.getTarget();
1549515619
1549615620 const options = options: {
1549715621 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");
......@@ -15512,11 +15636,11 @@ fn zirBuiltinExtern(
1551215636 var library_name: ?[]const u8 = null;
1551315637 if (!library_name_val.isNull()) {
1551415638 const payload = library_name_val.castTag(.opt_payload).?.data;
15515 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena);
15639 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);
1551615640 }
1551715641
1551815642 break :options std.builtin.ExternOptions{
15519 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
15643 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
1552015644 .library_name = library_name,
1552115645 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
1552215646 .is_thread_local = is_thread_local_val.toBool(),
......@@ -15609,8 +15733,9 @@ fn validateVarType(
1560915733) CompileError!void {
1561015734 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
1561115735
15736 const target = sema.mod.getTarget();
1561215737 const msg = msg: {
15613 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty});
15738 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(target)});
1561415739 errdefer msg.destroy(sema.gpa);
1561515740
1561615741 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);
......@@ -15685,6 +15810,7 @@ fn explainWhyTypeIsComptime(
1568515810 ty: Type,
1568615811) CompileError!void {
1568715812 const mod = sema.mod;
15813 const target = mod.getTarget();
1568815814 switch (ty.zigTypeTag()) {
1568915815 .Bool,
1569015816 .Int,
......@@ -15698,7 +15824,7 @@ fn explainWhyTypeIsComptime(
1569815824
1569915825 .Fn => {
1570015826 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
15701 ty,
15827 ty.fmt(target),
1570215828 });
1570315829 },
1570415830
......@@ -15941,6 +16067,8 @@ fn fieldVal(
1594116067 else
1594216068 object_ty;
1594316069
16070 const target = sema.mod.getTarget();
16071
1594416072 switch (inner_ty.zigTypeTag()) {
1594516073 .Array => {
1594616074 if (mem.eql(u8, field_name, "len")) {
......@@ -15953,7 +16081,7 @@ fn fieldVal(
1595316081 block,
1595416082 field_name_src,
1595516083 "no member named '{s}' in '{}'",
15956 .{ field_name, object_ty },
16084 .{ field_name, object_ty.fmt(target) },
1595716085 );
1595816086 }
1595916087 },
......@@ -15977,7 +16105,7 @@ fn fieldVal(
1597716105 block,
1597816106 field_name_src,
1597916107 "no member named '{s}' in '{}'",
15980 .{ field_name, object_ty },
16108 .{ field_name, object_ty.fmt(target) },
1598116109 );
1598216110 }
1598316111 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
......@@ -15991,7 +16119,7 @@ fn fieldVal(
1599116119 block,
1599216120 field_name_src,
1599316121 "no member named '{s}' in '{}'",
15994 .{ field_name, ptr_info.pointee_type },
16122 .{ field_name, ptr_info.pointee_type.fmt(target) },
1599516123 );
1599616124 }
1599716125 }
......@@ -16013,7 +16141,7 @@ fn fieldVal(
1601316141 break :blk entry.key_ptr.*;
1601416142 }
1601516143 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16016 field_name, child_type,
16144 field_name, child_type.fmt(target),
1601716145 });
1601816146 } else (try sema.mod.getErrorValue(field_name)).key;
1601916147
......@@ -16067,10 +16195,10 @@ fn fieldVal(
1606716195 else => unreachable,
1606816196 };
1606916197 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{
16070 kw_name, child_type, field_name,
16198 kw_name, child_type.fmt(target), field_name,
1607116199 });
1607216200 },
16073 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),
16201 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
1607416202 }
1607516203 },
1607616204 .Struct => if (is_pointer_to) {
......@@ -16089,7 +16217,7 @@ fn fieldVal(
1608916217 },
1609016218 else => {},
1609116219 }
16092 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty});
16220 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(target)});
1609316221}
1609416222
1609516223fn fieldPtr(
......@@ -16103,11 +16231,12 @@ fn fieldPtr(
1610316231 // When editing this function, note that there is corresponding logic to be edited
1610416232 // in `fieldVal`. This function takes a pointer and returns a pointer.
1610516233
16234 const target = sema.mod.getTarget();
1610616235 const object_ptr_src = src; // TODO better source location
1610716236 const object_ptr_ty = sema.typeOf(object_ptr);
1610816237 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
1610916238 .Pointer => object_ptr_ty.elemType(),
16110 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}),
16239 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(target)}),
1611116240 };
1611216241
1611316242 // Zig allows dereferencing a single pointer during field lookup. Note that
......@@ -16120,8 +16249,6 @@ fn fieldPtr(
1612016249 else
1612116250 object_ty;
1612216251
16123 const target = sema.mod.getTarget();
16124
1612516252 switch (inner_ty.zigTypeTag()) {
1612616253 .Array => {
1612716254 if (mem.eql(u8, field_name, "len")) {
......@@ -16137,7 +16264,7 @@ fn fieldPtr(
1613716264 block,
1613816265 field_name_src,
1613916266 "no member named '{s}' in '{}'",
16140 .{ field_name, object_ty },
16267 .{ field_name, object_ty.fmt(target) },
1614116268 );
1614216269 }
1614316270 },
......@@ -16177,7 +16304,7 @@ fn fieldPtr(
1617716304
1617816305 return sema.analyzeDeclRef(try anon_decl.finish(
1617916306 Type.usize,
16180 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),
16307 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(target)),
1618116308 0, // default alignment
1618216309 ));
1618316310 }
......@@ -16195,7 +16322,7 @@ fn fieldPtr(
1619516322 block,
1619616323 field_name_src,
1619716324 "no member named '{s}' in '{}'",
16198 .{ field_name, object_ty },
16325 .{ field_name, object_ty.fmt(target) },
1619916326 );
1620016327 }
1620116328 },
......@@ -16219,7 +16346,7 @@ fn fieldPtr(
1621916346 break :blk entry.key_ptr.*;
1622016347 }
1622116348 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16222 field_name, child_type,
16349 field_name, child_type.fmt(target),
1622316350 });
1622416351 } else (try sema.mod.getErrorValue(field_name)).key;
1622516352
......@@ -16277,7 +16404,7 @@ fn fieldPtr(
1627716404 }
1627816405 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
1627916406 },
16280 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),
16407 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
1628116408 }
1628216409 },
1628316410 .Struct => {
......@@ -16296,7 +16423,7 @@ fn fieldPtr(
1629616423 },
1629716424 else => {},
1629816425 }
16299 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty, object_ptr_ty, field_name });
16426 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(target), object_ptr_ty.fmt(target), field_name });
1630016427}
1630116428
1630216429fn fieldCallBind(
......@@ -16310,12 +16437,13 @@ fn fieldCallBind(
1631016437 // When editing this function, note that there is corresponding logic to be edited
1631116438 // in `fieldVal`. This function takes a pointer and returns a pointer.
1631216439
16440 const target = sema.mod.getTarget();
1631316441 const raw_ptr_src = src; // TODO better source location
1631416442 const raw_ptr_ty = sema.typeOf(raw_ptr);
1631516443 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)
1631616444 raw_ptr_ty.childType()
1631716445 else
16318 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty});
16446 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(target)});
1631916447
1632016448 // Optionally dereference a second pointer to get the concrete type.
1632116449 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
......@@ -16375,7 +16503,7 @@ fn fieldCallBind(
1637516503 first_param_type.zigTypeTag() == .Pointer and
1637616504 (first_param_type.ptrSize() == .One or
1637716505 first_param_type.ptrSize() == .C) and
16378 first_param_type.childType().eql(concrete_ty)))
16506 first_param_type.childType().eql(concrete_ty, target)))
1637916507 {
1638016508 // zig fmt: on
1638116509 // TODO: bound fn calls on rvalues should probably
......@@ -16386,7 +16514,7 @@ fn fieldCallBind(
1638616514 .arg0_inst = object_ptr,
1638716515 });
1638816516 return sema.addConstant(ty, value);
16389 } else if (first_param_type.eql(concrete_ty)) {
16517 } else if (first_param_type.eql(concrete_ty, target)) {
1639016518 var deref = try sema.analyzeLoad(block, src, object_ptr, src);
1639116519 const ty = Type.Tag.bound_fn.init();
1639216520 const value = try Value.Tag.bound_fn.create(arena, .{
......@@ -16402,7 +16530,7 @@ fn fieldCallBind(
1640216530 else => {},
1640316531 }
1640416532
16405 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name });
16533 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(target), field_name });
1640616534}
1640716535
1640816536fn finishFieldCallBind(
......@@ -16540,10 +16668,11 @@ fn structFieldPtrByIndex(
1654016668 .@"addrspace" = struct_ptr_ty_info.@"addrspace",
1654116669 };
1654216670
16671 const target = sema.mod.getTarget();
16672
1654316673 // TODO handle when the struct pointer is overaligned, we should return a potentially
1654416674 // over-aligned field pointer too.
1654516675 if (struct_obj.layout == .Packed) {
16546 const target = sema.mod.getTarget();
1654716676 comptime assert(Type.packed_struct_layout_version == 2);
1654816677
1654916678 var running_bits: u16 = 0;
......@@ -16567,7 +16696,6 @@ fn structFieldPtrByIndex(
1656716696 ptr_ty_data.@"align" = field.abi_align;
1656816697 }
1656916698
16570 const target = sema.mod.getTarget();
1657116699 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1657216700
1657316701 if (field.is_comptime) {
......@@ -16667,14 +16795,15 @@ fn tupleFieldIndex(
1666716795 field_name: []const u8,
1666816796 field_name_src: LazySrcLoc,
1666916797) CompileError!u32 {
16798 const target = sema.mod.getTarget();
1667016799 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
1667116800 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
16672 tuple_ty, field_name, @errorName(err),
16801 tuple_ty.fmt(target), field_name, @errorName(err),
1667316802 });
1667416803 };
1667516804 if (field_index >= tuple_ty.structFieldCount()) {
1667616805 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{
16677 tuple_ty, field_name,
16806 tuple_ty.fmt(target), field_name,
1667816807 });
1667916808 }
1668016809 return field_index;
......@@ -16749,7 +16878,7 @@ fn unionFieldPtr(
1674916878 // .data = field_index,
1675016879 //};
1675116880 //const field_tag = Value.initPayload(&field_tag_buf.base);
16752 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
16881 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
1675316882 //if (!tag_matches) {
1675416883 // // TODO enhance this saying which one was active
1675516884 // // and which one was accessed, and showing where the union was declared.
......@@ -16798,7 +16927,8 @@ fn unionFieldVal(
1679816927 .data = field_index,
1679916928 };
1680016929 const field_tag = Value.initPayload(&field_tag_buf.base);
16801 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
16930 const target = sema.mod.getTarget();
16931 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
1680216932 switch (union_obj.layout) {
1680316933 .Auto => {
1680416934 if (tag_matches) {
......@@ -16813,7 +16943,7 @@ fn unionFieldVal(
1681316943 if (tag_matches) {
1681416944 return sema.addConstant(field.ty, tag_and_val.val);
1681516945 } else {
16816 const old_ty = union_ty.unionFieldType(tag_and_val.tag);
16946 const old_ty = union_ty.unionFieldType(tag_and_val.tag, target);
1681716947 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
1681816948 return sema.addConstant(field.ty, new_val);
1681916949 }
......@@ -16835,19 +16965,19 @@ fn elemPtr(
1683516965) CompileError!Air.Inst.Ref {
1683616966 const indexable_ptr_src = src; // TODO better source location
1683716967 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
16968 const target = sema.mod.getTarget();
1683816969 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
1683916970 .Pointer => indexable_ptr_ty.elemType(),
16840 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty}),
16971 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(target)}),
1684116972 };
1684216973 if (!indexable_ty.isIndexable()) {
16843 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});
16974 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
1684416975 }
1684516976
1684616977 switch (indexable_ty.zigTypeTag()) {
1684716978 .Pointer => {
1684816979 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
1684916980 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
16850 const target = sema.mod.getTarget();
1685116981 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);
1685216982 switch (indexable_ty.ptrSize()) {
1685316983 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),
......@@ -16858,8 +16988,8 @@ fn elemPtr(
1685816988 const runtime_src = rs: {
1685916989 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;
1686016990 const index_val = maybe_index_val orelse break :rs elem_index_src;
16861 const index = @intCast(usize, index_val.toUnsignedInt());
16862 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index);
16991 const index = @intCast(usize, index_val.toUnsignedInt(target));
16992 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, target);
1686316993 return sema.addConstant(result_ty, elem_ptr);
1686416994 };
1686516995
......@@ -16876,7 +17006,7 @@ fn elemPtr(
1687617006 .Struct => {
1687717007 // Tuple field access.
1687817008 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16879 const index = @intCast(u32, index_val.toUnsignedInt());
17009 const index = @intCast(u32, index_val.toUnsignedInt(target));
1688017010 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
1688117011 },
1688217012 else => unreachable,
......@@ -16893,9 +17023,10 @@ fn elemVal(
1689317023) CompileError!Air.Inst.Ref {
1689417024 const indexable_src = src; // TODO better source location
1689517025 const indexable_ty = sema.typeOf(indexable);
17026 const target = sema.mod.getTarget();
1689617027
1689717028 if (!indexable_ty.isIndexable()) {
16898 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});
17029 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
1689917030 }
1690017031
1690117032 // TODO in case of a vector of pointers, we need to detect whether the element
......@@ -16912,7 +17043,7 @@ fn elemVal(
1691217043 const runtime_src = rs: {
1691317044 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
1691417045 const index_val = maybe_index_val orelse break :rs elem_index_src;
16915 const index = @intCast(usize, index_val.toUnsignedInt());
17046 const index = @intCast(usize, index_val.toUnsignedInt(target));
1691617047 const elem_ty = indexable_ty.elemType2();
1691717048
1691817049 var payload: Value.Payload.ElemPtr = .{ .data = .{
......@@ -16945,7 +17076,7 @@ fn elemVal(
1694517076 .Struct => {
1694617077 // Tuple field access.
1694717078 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16948 const index = @intCast(u32, index_val.toUnsignedInt());
17079 const index = @intCast(u32, index_val.toUnsignedInt(target));
1694917080 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
1695017081 },
1695117082 else => unreachable,
......@@ -17056,9 +17187,10 @@ fn elemValArray(
1705617187 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);
1705717188 // index must be defined since it can access out of bounds
1705817189 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17190 const target = sema.mod.getTarget();
1705917191
1706017192 if (maybe_index_val) |index_val| {
17061 const index = @intCast(usize, index_val.toUnsignedInt());
17193 const index = @intCast(usize, index_val.toUnsignedInt(target));
1706217194 if (index >= array_len_s) {
1706317195 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
1706417196 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -17069,7 +17201,7 @@ fn elemValArray(
1706917201 return sema.addConstUndef(elem_ty);
1707017202 }
1707117203 if (maybe_index_val) |index_val| {
17072 const index = @intCast(usize, index_val.toUnsignedInt());
17204 const index = @intCast(usize, index_val.toUnsignedInt(target));
1707317205 const elem_val = try array_val.elemValue(sema.arena, index);
1707417206 return sema.addConstant(elem_ty, elem_val);
1707517207 }
......@@ -17114,7 +17246,7 @@ fn elemPtrArray(
1711417246 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
1711517247
1711617248 if (maybe_index_val) |index_val| {
17117 const index = @intCast(usize, index_val.toUnsignedInt());
17249 const index = @intCast(usize, index_val.toUnsignedInt(target));
1711817250 if (index >= array_len_s) {
1711917251 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
1712017252 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -17125,8 +17257,8 @@ fn elemPtrArray(
1712517257 return sema.addConstUndef(elem_ptr_ty);
1712617258 }
1712717259 if (maybe_index_val) |index_val| {
17128 const index = @intCast(usize, index_val.toUnsignedInt());
17129 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index);
17260 const index = @intCast(usize, index_val.toUnsignedInt(target));
17261 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, target);
1713017262 return sema.addConstant(elem_ptr_ty, elem_ptr);
1713117263 }
1713217264 }
......@@ -17162,16 +17294,17 @@ fn elemValSlice(
1716217294 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
1716317295 // index must be defined since it can index out of bounds
1716417296 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17297 const target = sema.mod.getTarget();
1716517298
1716617299 if (maybe_slice_val) |slice_val| {
1716717300 runtime_src = elem_index_src;
17168 const slice_len = slice_val.sliceLen();
17301 const slice_len = slice_val.sliceLen(target);
1716917302 const slice_len_s = slice_len + @boolToInt(slice_sent);
1717017303 if (slice_len_s == 0) {
1717117304 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
1717217305 }
1717317306 if (maybe_index_val) |index_val| {
17174 const index = @intCast(usize, index_val.toUnsignedInt());
17307 const index = @intCast(usize, index_val.toUnsignedInt(target));
1717517308 if (index >= slice_len_s) {
1717617309 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
1717717310 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
......@@ -17192,7 +17325,7 @@ fn elemValSlice(
1719217325 try sema.requireRuntimeBlock(block, runtime_src);
1719317326 if (block.wantSafety()) {
1719417327 const len_inst = if (maybe_slice_val) |slice_val|
17195 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen())
17328 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target))
1719617329 else
1719717330 try block.addTyOp(.slice_len, Type.usize, slice);
1719817331 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -17223,18 +17356,18 @@ fn elemPtrSlice(
1722317356 if (slice_val.isUndef()) {
1722417357 return sema.addConstUndef(elem_ptr_ty);
1722517358 }
17226 const slice_len = slice_val.sliceLen();
17359 const slice_len = slice_val.sliceLen(target);
1722717360 const slice_len_s = slice_len + @boolToInt(slice_sent);
1722817361 if (slice_len_s == 0) {
1722917362 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
1723017363 }
1723117364 if (maybe_index_val) |index_val| {
17232 const index = @intCast(usize, index_val.toUnsignedInt());
17365 const index = @intCast(usize, index_val.toUnsignedInt(target));
1723317366 if (index >= slice_len_s) {
1723417367 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
1723517368 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
1723617369 }
17237 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index);
17370 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);
1723817371 return sema.addConstant(elem_ptr_ty, elem_ptr_val);
1723917372 }
1724017373 }
......@@ -17245,7 +17378,7 @@ fn elemPtrSlice(
1724517378 const len_inst = len: {
1724617379 if (maybe_undef_slice_val) |slice_val|
1724717380 if (!slice_val.isUndef())
17248 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen());
17381 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
1724917382 break :len try block.addTyOp(.slice_len, Type.usize, slice);
1725017383 };
1725117384 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -17270,12 +17403,12 @@ fn coerce(
1727017403 const dest_ty_src = inst_src; // TODO better source location
1727117404 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);
1727217405 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));
17406 const target = sema.mod.getTarget();
1727317407 // If the types are the same, we can return the operand.
17274 if (dest_ty.eql(inst_ty))
17408 if (dest_ty.eql(inst_ty, target))
1727517409 return inst;
1727617410
1727717411 const arena = sema.arena;
17278 const target = sema.mod.getTarget();
1727917412 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);
1728017413
1728117414 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
......@@ -17379,7 +17512,7 @@ fn coerce(
1737917512 // *[N:s]T to [*]T
1738017513 if (dest_info.sentinel) |dst_sentinel| {
1738117514 if (array_ty.sentinel()) |src_sentinel| {
17382 if (src_sentinel.eql(dst_sentinel, dst_elem_type)) {
17515 if (src_sentinel.eql(dst_sentinel, dst_elem_type, target)) {
1738317516 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
1738417517 }
1738517518 }
......@@ -17448,7 +17581,7 @@ fn coerce(
1744817581 }
1744917582 if (inst_info.size == .Slice) {
1745017583 if (dest_info.sentinel == null or inst_info.sentinel == null or
17451 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))
17584 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
1745217585 break :p;
1745317586
1745417587 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -17515,7 +17648,7 @@ fn coerce(
1751517648 }
1751617649
1751717650 if (dest_info.sentinel == null or inst_info.sentinel == null or
17518 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))
17651 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
1751917652 break :p;
1752017653
1752117654 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -17528,11 +17661,11 @@ fn coerce(
1752817661 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
1752917662
1753017663 if (val.floatHasFraction()) {
17531 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty });
17664 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty, target), dest_ty.fmt(target) });
1753217665 }
1753317666 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {
1753417667 error.FloatCannotFit => {
17535 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });
17668 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(target) });
1753617669 },
1753717670 else => |e| return e,
1753817671 };
......@@ -17542,7 +17675,7 @@ fn coerce(
1754217675 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
1754317676 // comptime known integer to other number
1754417677 if (!val.intFitsInType(dest_ty, target)) {
17545 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val.fmtValue(inst_ty) });
17678 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) });
1754617679 }
1754717680 return try sema.addConstant(dest_ty, val);
1754817681 }
......@@ -17572,12 +17705,12 @@ fn coerce(
1757217705 .Float => {
1757317706 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
1757417707 const result_val = try val.floatCast(sema.arena, dest_ty, target);
17575 if (!val.eql(result_val, dest_ty)) {
17708 if (!val.eql(result_val, dest_ty, target)) {
1757617709 return sema.fail(
1757717710 block,
1757817711 inst_src,
1757917712 "type {} cannot represent float value {}",
17580 .{ dest_ty, val.fmtValue(inst_ty) },
17713 .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) },
1758117714 );
1758217715 }
1758317716 return try sema.addConstant(dest_ty, result_val);
......@@ -17596,12 +17729,12 @@ fn coerce(
1759617729 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
1759717730 // TODO implement this compile error
1759817731 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
17599 //if (!int_again_val.eql(val, inst_ty)) {
17732 //if (!int_again_val.eql(val, inst_ty, target)) {
1760017733 // return sema.fail(
1760117734 // block,
1760217735 // inst_src,
1760317736 // "type {} cannot represent integer value {}",
17604 // .{ dest_ty, val },
17737 // .{ dest_ty.fmt(target), val },
1760517738 // );
1760617739 //}
1760717740 return try sema.addConstant(dest_ty, result_val);
......@@ -17622,7 +17755,7 @@ fn coerce(
1762217755 block,
1762317756 inst_src,
1762417757 "enum '{}' has no field named '{s}'",
17625 .{ dest_ty, bytes },
17758 .{ dest_ty.fmt(target), bytes },
1762617759 );
1762717760 errdefer msg.destroy(sema.gpa);
1762817761 try sema.mod.errNoteNonLazy(
......@@ -17643,7 +17776,7 @@ fn coerce(
1764317776 .Union => blk: {
1764417777 // union to its own tag type
1764517778 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;
17646 if (union_tag_ty.eql(dest_ty)) {
17779 if (union_tag_ty.eql(dest_ty, target)) {
1764717780 return sema.unionToTag(block, dest_ty, inst, inst_src);
1764817781 }
1764917782 },
......@@ -17743,7 +17876,7 @@ fn coerce(
1774317876 return sema.addConstUndef(dest_ty);
1774417877 }
1774517878
17746 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty });
17879 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(target), inst_ty.fmt(target) });
1774717880}
1774817881
1774917882const InMemoryCoercionResult = enum {
......@@ -17772,7 +17905,7 @@ fn coerceInMemoryAllowed(
1777217905 dest_src: LazySrcLoc,
1777317906 src_src: LazySrcLoc,
1777417907) CompileError!InMemoryCoercionResult {
17775 if (dest_ty.eql(src_ty))
17908 if (dest_ty.eql(src_ty, target))
1777617909 return .ok;
1777717910
1777817911 // Pointers / Pointer-like Optionals
......@@ -17823,7 +17956,7 @@ fn coerceInMemoryAllowed(
1782317956 }
1782417957 const ok_sent = dest_info.sentinel == null or
1782517958 (src_info.sentinel != null and
17826 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type));
17959 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, target));
1782717960 if (!ok_sent) {
1782817961 return .no_match;
1782917962 }
......@@ -18050,7 +18183,7 @@ fn coerceInMemoryAllowedPtrs(
1805018183
1805118184 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
1805218185 (src_info.sentinel != null and
18053 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type));
18186 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, target));
1805418187 if (!ok_sent) {
1805518188 return .no_match;
1805618189 }
......@@ -18091,7 +18224,7 @@ fn coerceInMemoryAllowedPtrs(
1809118224 // resolved and we compare the alignment numerically.
1809218225 alignment: {
1809318226 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
18094 dest_info.pointee_type.eql(src_info.pointee_type))
18227 dest_info.pointee_type.eql(src_info.pointee_type, target))
1809518228 {
1809618229 break :alignment;
1809718230 }
......@@ -18246,7 +18379,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
1824618379 // We have a pointer-to-array and a pointer-to-vector. If the elements and
1824718380 // lengths match, return the result.
1824818381 const vector_ty = sema.typeOf(prev_ptr).childType();
18249 if (array_ty.childType().eql(vector_ty.childType()) and
18382 const target = sema.mod.getTarget();
18383 if (array_ty.childType().eql(vector_ty.childType(), target) and
1825018384 array_ty.arrayLen() == vector_ty.vectorLen())
1825118385 {
1825218386 return prev_ptr;
......@@ -18265,15 +18399,15 @@ fn storePtrVal(
1826518399 operand_val: Value,
1826618400 operand_ty: Type,
1826718401) !void {
18268 var kit = try beginComptimePtrMutation(sema, block, src, ptr_val);
18269 try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut);
18402 var mut_kit = try beginComptimePtrMutation(sema, block, src, ptr_val);
18403 try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);
1827018404
18271 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty, 0);
18405 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
1827218406
18273 const arena = kit.beginArena(sema.gpa);
18274 defer kit.finishArena();
18407 const arena = mut_kit.beginArena(sema.gpa);
18408 defer mut_kit.finishArena();
1827518409
18276 kit.val.* = try bitcasted_val.copy(arena);
18410 mut_kit.val.* = try bitcasted_val.copy(arena);
1827718411}
1827818412
1827918413const ComptimePtrMutationKit = struct {
......@@ -18668,10 +18802,10 @@ fn beginComptimePtrLoad(
1866818802 if (maybe_array_ty) |load_ty| {
1866918803 // It's possible that we're loading a [N]T, in which case we'd like to slice
1867018804 // the pointee array directly from our parent array.
18671 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty)) {
18805 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty, target)) {
1867218806 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
1867318807 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
18674 .ty = try Type.array(sema.arena, N, null, elem_ty),
18808 .ty = try Type.array(sema.arena, N, null, elem_ty, target),
1867518809 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),
1867618810 } else null;
1867718811 break :blk deref;
......@@ -18807,11 +18941,11 @@ pub fn bitCastVal(
1880718941 new_ty: Type,
1880818942 buffer_offset: usize,
1880918943) !Value {
18810 if (old_ty.eql(new_ty)) return val;
18944 const target = sema.mod.getTarget();
18945 if (old_ty.eql(new_ty, target)) return val;
1881118946
1881218947 // For types with well-defined memory layouts, we serialize them a byte buffer,
1881318948 // then deserialize to the new type.
18814 const target = sema.mod.getTarget();
1881518949 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
1881618950 const buffer = try sema.gpa.alloc(u8, abi_size);
1881718951 defer sema.gpa.free(buffer);
......@@ -18864,11 +18998,12 @@ fn coerceEnumToUnion(
1886418998 inst_src: LazySrcLoc,
1886518999) !Air.Inst.Ref {
1886619000 const inst_ty = sema.typeOf(inst);
19001 const target = sema.mod.getTarget();
1886719002
1886819003 const tag_ty = union_ty.unionTagType() orelse {
1886919004 const msg = msg: {
1887019005 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
18871 union_ty, inst_ty,
19006 union_ty.fmt(target), inst_ty.fmt(target),
1887219007 });
1887319008 errdefer msg.destroy(sema.gpa);
1887419009 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
......@@ -18881,10 +19016,10 @@ fn coerceEnumToUnion(
1888119016 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
1888219017 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
1888319018 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
18884 const field_index = union_obj.tag_ty.enumTagFieldIndex(val) orelse {
19019 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, target) orelse {
1888519020 const msg = msg: {
1888619021 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
18887 union_ty, val.fmtValue(tag_ty),
19022 union_ty.fmt(target), val.fmtValue(tag_ty, target),
1888819023 });
1888919024 errdefer msg.destroy(sema.gpa);
1889019025 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -18899,7 +19034,7 @@ fn coerceEnumToUnion(
1889919034 // also instead of 'union declared here' make it 'field "foo" declared here'.
1890019035 const msg = msg: {
1890119036 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{
18902 union_ty, field_ty,
19037 union_ty.fmt(target), field_ty.fmt(target),
1890319038 });
1890419039 errdefer msg.destroy(sema.gpa);
1890519040 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -18919,7 +19054,7 @@ fn coerceEnumToUnion(
1891919054 if (tag_ty.isNonexhaustiveEnum()) {
1892019055 const msg = msg: {
1892119056 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{
18922 union_ty,
19057 union_ty.fmt(target),
1892319058 });
1892419059 errdefer msg.destroy(sema.gpa);
1892519060 try sema.addDeclaredHereNote(msg, tag_ty);
......@@ -18937,7 +19072,7 @@ fn coerceEnumToUnion(
1893719072 // instead of the "union declared here" hint
1893819073 const msg = msg: {
1893919074 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{
18940 union_ty,
19075 union_ty.fmt(target),
1894119076 });
1894219077 errdefer msg.destroy(sema.gpa);
1894319078 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -19020,11 +19155,12 @@ fn coerceArrayLike(
1902019155 const inst_ty = sema.typeOf(inst);
1902119156 const inst_len = inst_ty.arrayLen();
1902219157 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19158 const target = sema.mod.getTarget();
1902319159
1902419160 if (dest_len != inst_len) {
1902519161 const msg = msg: {
1902619162 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19027 dest_ty, inst_ty,
19163 dest_ty.fmt(target), inst_ty.fmt(target),
1902819164 });
1902919165 errdefer msg.destroy(sema.gpa);
1903019166 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
......@@ -19034,7 +19170,6 @@ fn coerceArrayLike(
1903419170 return sema.failWithOwnedErrorMsg(block, msg);
1903519171 }
1903619172
19037 const target = sema.mod.getTarget();
1903819173 const dest_elem_ty = dest_ty.childType();
1903919174 const inst_elem_ty = inst_ty.childType();
1904019175 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);
......@@ -19092,11 +19227,12 @@ fn coerceTupleToArray(
1909219227 const inst_ty = sema.typeOf(inst);
1909319228 const inst_len = inst_ty.arrayLen();
1909419229 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19230 const target = sema.mod.getTarget();
1909519231
1909619232 if (dest_len != inst_len) {
1909719233 const msg = msg: {
1909819234 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19099 dest_ty, inst_ty,
19235 dest_ty.fmt(target), inst_ty.fmt(target),
1910019236 });
1910119237 errdefer msg.destroy(sema.gpa);
1910219238 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
......@@ -19149,7 +19285,8 @@ fn coerceTupleToSlicePtrs(
1914919285 const tuple_ty = sema.typeOf(ptr_tuple).childType();
1915019286 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
1915119287 const slice_info = slice_ty.ptrInfo().data;
19152 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type);
19288 const target = sema.mod.getTarget();
19289 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, target);
1915319290 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
1915419291 if (slice_info.@"align" != 0) {
1915519292 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
......@@ -19398,10 +19535,11 @@ fn analyzeLoad(
1939819535 ptr: Air.Inst.Ref,
1939919536 ptr_src: LazySrcLoc,
1940019537) CompileError!Air.Inst.Ref {
19538 const target = sema.mod.getTarget();
1940119539 const ptr_ty = sema.typeOf(ptr);
1940219540 const elem_ty = switch (ptr_ty.zigTypeTag()) {
1940319541 .Pointer => ptr_ty.childType(),
19404 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),
19542 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)}),
1940519543 };
1940619544 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
1940719545 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {
......@@ -19440,7 +19578,8 @@ fn analyzeSliceLen(
1944019578 if (slice_val.isUndef()) {
1944119579 return sema.addConstUndef(Type.usize);
1944219580 }
19443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen());
19581 const target = sema.mod.getTarget();
19582 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
1944419583 }
1944519584 try sema.requireRuntimeBlock(block, src);
1944619585 return block.addTyOp(.slice_len, Type.usize, slice_inst);
......@@ -19522,9 +19661,10 @@ fn analyzeSlice(
1952219661 // Slice expressions can operate on a variable whose type is an array. This requires
1952319662 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
1952419663 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
19664 const target = sema.mod.getTarget();
1952519665 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
1952619666 .Pointer => ptr_ptr_ty.elemType(),
19527 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty}),
19667 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(target)}),
1952819668 };
1952919669
1953019670 var array_ty = ptr_ptr_child_ty;
......@@ -19564,7 +19704,7 @@ fn analyzeSlice(
1956419704 elem_ty = ptr_ptr_child_ty.childType();
1956519705 },
1956619706 },
19567 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty}),
19707 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(target)}),
1956819708 }
1956919709
1957019710 const ptr = if (slice_ty.isSlice())
......@@ -19587,15 +19727,18 @@ fn analyzeSlice(
1958719727 if (!end_is_len) {
1958819728 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
1958919729 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {
19590 if (end_val.compare(.gt, len_val, Type.usize)) {
19730 if (end_val.compare(.gt, len_val, Type.usize, target)) {
1959119731 return sema.fail(
1959219732 block,
1959319733 end_src,
1959419734 "end index {} out of bounds for array of length {}",
19595 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },
19735 .{
19736 end_val.fmtValue(Type.usize, target),
19737 len_val.fmtValue(Type.usize, target),
19738 },
1959619739 );
1959719740 }
19598 if (end_val.eql(len_val, Type.usize)) {
19741 if (end_val.eql(len_val, Type.usize, target)) {
1959919742 end_is_len = true;
1960019743 }
1960119744 }
......@@ -19610,18 +19753,21 @@ fn analyzeSlice(
1961019753 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
1961119754 var int_payload: Value.Payload.U64 = .{
1961219755 .base = .{ .tag = .int_u64 },
19613 .data = slice_val.sliceLen(),
19756 .data = slice_val.sliceLen(target),
1961419757 };
1961519758 const slice_len_val = Value.initPayload(&int_payload.base);
19616 if (end_val.compare(.gt, slice_len_val, Type.usize)) {
19759 if (end_val.compare(.gt, slice_len_val, Type.usize, target)) {
1961719760 return sema.fail(
1961819761 block,
1961919762 end_src,
1962019763 "end index {} out of bounds for slice of length {}",
19621 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },
19764 .{
19765 end_val.fmtValue(Type.usize, target),
19766 slice_len_val.fmtValue(Type.usize, target),
19767 },
1962219768 );
1962319769 }
19624 if (end_val.eql(slice_len_val, Type.usize)) {
19770 if (end_val.eql(slice_len_val, Type.usize, target)) {
1962519771 end_is_len = true;
1962619772 }
1962719773 }
......@@ -19654,12 +19800,15 @@ fn analyzeSlice(
1965419800 // requirement: start <= end
1965519801 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {
1965619802 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {
19657 if (start_val.compare(.gt, end_val, Type.usize)) {
19803 if (start_val.compare(.gt, end_val, Type.usize, target)) {
1965819804 return sema.fail(
1965919805 block,
1966019806 start_src,
1966119807 "start index {} is larger than end index {}",
19662 .{ start_val.fmtValue(Type.usize), end_val.fmtValue(Type.usize) },
19808 .{
19809 start_val.fmtValue(Type.usize, target),
19810 end_val.fmtValue(Type.usize, target),
19811 },
1966319812 );
1966419813 }
1966519814 }
......@@ -19670,13 +19819,12 @@ fn analyzeSlice(
1967019819
1967119820 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;
1967219821 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
19673 const target = sema.mod.getTarget();
1967419822
1967519823 if (opt_new_len_val) |new_len_val| {
19676 const new_len_int = new_len_val.toUnsignedInt();
19824 const new_len_int = new_len_val.toUnsignedInt(target);
1967719825
1967819826 const return_ty = try Type.ptr(sema.arena, target, .{
19679 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty),
19827 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, target),
1968019828 .sentinel = null,
1968119829 .@"align" = new_ptr_ty_info.@"align",
1968219830 .@"addrspace" = new_ptr_ty_info.@"addrspace",
......@@ -19746,6 +19894,7 @@ fn cmpNumeric(
1974619894
1974719895 const lhs_ty_tag = lhs_ty.zigTypeTag();
1974819896 const rhs_ty_tag = rhs_ty.zigTypeTag();
19897 const target = sema.mod.getTarget();
1974919898
1975019899 const runtime_src: LazySrcLoc = src: {
1975119900 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
......@@ -19760,7 +19909,7 @@ fn cmpNumeric(
1976019909 return Air.Inst.Ref.bool_false;
1976119910 }
1976219911 }
19763 if (Value.compareHetero(lhs_val, op, rhs_val)) {
19912 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, target, sema.kit(block, src))) {
1976419913 return Air.Inst.Ref.bool_true;
1976519914 } else {
1976619915 return Air.Inst.Ref.bool_false;
......@@ -19789,7 +19938,6 @@ fn cmpNumeric(
1978919938 .Float, .ComptimeFloat => true,
1979019939 else => false,
1979119940 };
19792 const target = sema.mod.getTarget();
1979319941 if (lhs_is_float and rhs_is_float) {
1979419942 // Implicit cast the smaller one to the larger one.
1979519943 const dest_ty = x: {
......@@ -19846,7 +19994,7 @@ fn cmpNumeric(
1984619994 }
1984719995 if (lhs_is_float) {
1984819996 var bigint_space: Value.BigIntSpace = undefined;
19849 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
19997 var bigint = try lhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
1985019998 defer bigint.deinit();
1985119999 if (lhs_val.floatHasFraction()) {
1985220000 switch (op) {
......@@ -19892,7 +20040,7 @@ fn cmpNumeric(
1989220040 }
1989320041 if (rhs_is_float) {
1989420042 var bigint_space: Value.BigIntSpace = undefined;
19895 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
20043 var bigint = try rhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
1989620044 defer bigint.deinit();
1989720045 if (rhs_val.floatHasFraction()) {
1989820046 switch (op) {
......@@ -19950,6 +20098,7 @@ fn cmpVector(
1995020098 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1995120099
1995220100 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");
20101 const target = sema.mod.getTarget();
1995320102
1995420103 const runtime_src: LazySrcLoc = src: {
1995520104 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
......@@ -19957,7 +20106,7 @@ fn cmpVector(
1995720106 if (lhs_val.isUndef() or rhs_val.isUndef()) {
1995820107 return sema.addConstUndef(result_ty);
1995920108 }
19960 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena);
20109 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, target);
1996120110 return sema.addConstant(result_ty, cmp_val);
1996220111 } else {
1996320112 break :src rhs_src;
......@@ -20108,7 +20257,7 @@ fn resolvePeerTypes(
2010820257 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
2010920258 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
2011020259
20111 if (candidate_ty.eql(chosen_ty))
20260 if (candidate_ty.eql(chosen_ty, target))
2011220261 continue;
2011320262
2011420263 switch (candidate_ty_tag) {
......@@ -20522,14 +20671,17 @@ fn resolvePeerTypes(
2052220671 );
2052320672
2052420673 const msg = msg: {
20525 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty });
20674 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
20675 chosen_ty.fmt(target),
20676 candidate_ty.fmt(target),
20677 });
2052620678 errdefer msg.destroy(sema.gpa);
2052720679
2052820680 if (chosen_src) |src_loc|
20529 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty});
20681 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(target)});
2053020682
2053120683 if (candidate_src) |src_loc|
20532 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty});
20684 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(target)});
2053320685
2053420686 break :msg msg;
2053520687 };
......@@ -20557,7 +20709,7 @@ fn resolvePeerTypes(
2055720709 else
2055820710 new_ptr_ty;
2055920711 const set_ty = err_set_ty orelse return opt_ptr_ty;
20560 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20712 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2056120713 }
2056220714
2056320715 if (seen_const) {
......@@ -20573,7 +20725,7 @@ fn resolvePeerTypes(
2057320725 else
2057420726 new_ptr_ty;
2057520727 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
20576 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20728 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2057720729 },
2057820730 .Pointer => {
2057920731 var info = chosen_ty.ptrInfo();
......@@ -20584,7 +20736,7 @@ fn resolvePeerTypes(
2058420736 else
2058520737 new_ptr_ty;
2058620738 const set_ty = err_set_ty orelse return opt_ptr_ty;
20587 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20739 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2058820740 },
2058920741 else => return chosen_ty,
2059020742 }
......@@ -20596,16 +20748,16 @@ fn resolvePeerTypes(
2059620748 else => try Type.optional(sema.arena, chosen_ty),
2059720749 };
2059820750 const set_ty = err_set_ty orelse return opt_ty;
20599 return try Module.errorUnionType(sema.arena, set_ty, opt_ty);
20751 return try Type.errorUnion(sema.arena, set_ty, opt_ty, target);
2060020752 }
2060120753
2060220754 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
2060320755 .ErrorSet => return ty,
2060420756 .ErrorUnion => {
2060520757 const payload_ty = chosen_ty.errorUnionPayload();
20606 return try Module.errorUnionType(sema.arena, ty, payload_ty);
20758 return try Type.errorUnion(sema.arena, ty, payload_ty, target);
2060720759 },
20608 else => return try Module.errorUnionType(sema.arena, ty, chosen_ty),
20760 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, target),
2060920761 };
2061020762
2061120763 return chosen_ty;
......@@ -20624,7 +20776,7 @@ pub fn resolveFnTypes(
2062420776 }
2062520777}
2062620778
20627fn resolveTypeLayout(
20779pub fn resolveTypeLayout(
2062820780 sema: *Sema,
2062920781 block: *Block,
2063020782 src: LazySrcLoc,
......@@ -20662,11 +20814,12 @@ fn resolveStructLayout(
2066220814) CompileError!void {
2066320815 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
2066420816 if (resolved_ty.castTag(.@"struct")) |payload| {
20817 const target = sema.mod.getTarget();
2066520818 const struct_obj = payload.data;
2066620819 switch (struct_obj.status) {
2066720820 .none, .have_field_types => {},
2066820821 .field_types_wip, .layout_wip => {
20669 return sema.fail(block, src, "struct {} depends on itself", .{ty});
20822 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
2067020823 },
2067120824 .have_layout, .fully_resolved_wip, .fully_resolved => return,
2067220825 }
......@@ -20694,10 +20847,11 @@ fn resolveUnionLayout(
2069420847) CompileError!void {
2069520848 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
2069620849 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
20850 const target = sema.mod.getTarget();
2069720851 switch (union_obj.status) {
2069820852 .none, .have_field_types => {},
2069920853 .field_types_wip, .layout_wip => {
20700 return sema.fail(block, src, "union {} depends on itself", .{ty});
20854 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
2070120855 },
2070220856 .have_layout, .fully_resolved_wip, .fully_resolved => return,
2070320857 }
......@@ -20793,7 +20947,7 @@ fn resolveUnionFully(
2079320947 union_obj.status = .fully_resolved;
2079420948}
2079520949
20796fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type {
20950pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type {
2079720951 switch (ty.tag()) {
2079820952 .@"struct" => {
2079920953 const struct_obj = ty.castTag(.@"struct").?.data;
......@@ -20828,10 +20982,11 @@ fn resolveTypeFieldsStruct(
2082820982 ty: Type,
2082920983 struct_obj: *Module.Struct,
2083020984) CompileError!void {
20985 const target = sema.mod.getTarget();
2083120986 switch (struct_obj.status) {
2083220987 .none => {},
2083320988 .field_types_wip => {
20834 return sema.fail(block, src, "struct {} depends on itself", .{ty});
20989 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
2083520990 },
2083620991 .have_field_types,
2083720992 .have_layout,
......@@ -20858,10 +21013,11 @@ fn resolveTypeFieldsUnion(
2085821013 ty: Type,
2085921014 union_obj: *Module.Union,
2086021015) CompileError!void {
21016 const target = sema.mod.getTarget();
2086121017 switch (union_obj.status) {
2086221018 .none => {},
2086321019 .field_types_wip => {
20864 return sema.fail(block, src, "union {} depends on itself", .{ty});
21020 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
2086521021 },
2086621022 .have_field_types,
2086721023 .have_layout,
......@@ -21218,6 +21374,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2121821374 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
2121921375 }
2122021376
21377 const target = sema.mod.getTarget();
21378
2122121379 const bits_per_field = 4;
2122221380 const fields_per_u32 = 32 / bits_per_field;
2122321381 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
......@@ -21275,16 +21433,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2127521433 // This puts the memory into the union arena, not the enum arena, but
2127621434 // it is OK since they share the same lifetime.
2127721435 const copied_val = try val.copy(decl_arena_allocator);
21278 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
21436 map.putAssumeCapacityContext(copied_val, {}, .{
21437 .ty = int_tag_ty,
21438 .target = target,
21439 });
2127921440 } else {
2128021441 const val = if (last_tag_val) |val|
21281 try val.intAdd(Value.one, int_tag_ty, sema.arena)
21442 try val.intAdd(Value.one, int_tag_ty, sema.arena, target)
2128221443 else
2128321444 Value.zero;
2128421445 last_tag_val = val;
2128521446
2128621447 const copied_val = try val.copy(decl_arena_allocator);
21287 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
21448 map.putAssumeCapacityContext(copied_val, {}, .{
21449 .ty = int_tag_ty,
21450 .target = target,
21451 });
2128821452 }
2128921453 }
2129021454
......@@ -21359,7 +21523,10 @@ fn generateUnionTagTypeNumbered(
2135921523 };
2136021524 // Here we pre-allocate the maps using the decl arena.
2136121525 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
21362 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{ .ty = int_ty });
21526 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
21527 .ty = int_ty,
21528 .target = sema.mod.getTarget(),
21529 });
2136321530 try new_decl.finalizeNewArena(&new_decl_arena);
2136421531 return enum_ty;
2136521532}
......@@ -21962,7 +22129,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
2196222129 // The type is not in-memory coercible or the direct dereference failed, so it must
2196322130 // be bitcast according to the pointer type we are performing the load through.
2196422131 if (!load_ty.hasWellDefinedLayout())
21965 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty});
22132 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(target)});
2196622133
2196722134 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2196822135
......@@ -21977,11 +22144,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
2197722144 if (deref.ty_without_well_defined_layout) |bad_ty| {
2197822145 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
2197922146 // is that some type we encountered when de-referencing does not have a well-defined layout.
21980 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty});
22147 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(target)});
2198122148 } else {
2198222149 // If all encountered types had well-defined layouts, the parent is the root decl and it just
2198322150 // wasn't big enough for the load.
21984 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty, deref.parent.?.tv.ty });
22151 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(target), deref.parent.?.tv.ty.fmt(target) });
2198522152 }
2198622153}
2198722154
......@@ -22060,7 +22227,9 @@ fn typePtrOrOptionalPtrTy(
2206022227/// This function returns false negatives when structs and unions are having their
2206122228/// field types resolved.
2206222229/// TODO assert the return value matches `ty.comptimeOnly`
22063fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
22230/// TODO merge these implementations together with the "advanced"/sema_kit pattern seen
22231/// elsewhere in value.zig
22232pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
2206422233 return switch (ty.tag()) {
2206522234 .u1,
2206622235 .u8,
......@@ -22266,6 +22435,7 @@ fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 {
2226622435 return ty.abiSize(target);
2226722436}
2226822437
22438/// TODO merge with Type.abiAlignmentAdvanced
2226922439fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 {
2227022440 try sema.resolveTypeLayout(block, src, ty);
2227122441 const target = sema.mod.getTarget();
......@@ -22344,7 +22514,12 @@ fn anonStructFieldIndex(
2234422514 return @intCast(u32, i);
2234522515 }
2234622516 }
22517 const target = sema.mod.getTarget();
2234722518 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{
22348 struct_ty, field_name,
22519 struct_ty.fmt(target), field_name,
2234922520 });
2235022521}
22522
22523fn kit(sema: *Sema, block: *Block, src: LazySrcLoc) Module.WipAnalysis {
22524 return .{ .sema = sema, .block = block, .src = src };
22525}
src/TypedValue.zig+35-22
......@@ -3,6 +3,7 @@ const Type = @import("type.zig").Type;
33const Value = @import("value.zig").Value;
44const Allocator = std.mem.Allocator;
55const TypedValue = @This();
6const Target = std.Target;
67
78ty: Type,
89val: Value,
......@@ -30,13 +31,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
3031 };
3132}
3233
33pub fn eql(a: TypedValue, b: TypedValue) bool {
34 if (!a.ty.eql(b.ty)) return false;
35 return a.val.eql(b.val, a.ty);
34pub fn eql(a: TypedValue, b: TypedValue, target: std.Target) bool {
35 if (!a.ty.eql(b.ty, target)) return false;
36 return a.val.eql(b.val, a.ty, target);
3637}
3738
38pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash) void {
39 return tv.val.hash(tv.ty, hasher);
39pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, target: std.Target) void {
40 return tv.val.hash(tv.ty, hasher, target);
4041}
4142
4243pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
......@@ -45,21 +46,28 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
4546
4647const max_aggregate_items = 100;
4748
48pub fn format(
49const FormatContext = struct {
4950 tv: TypedValue,
51 target: Target,
52};
53
54pub fn format(
55 ctx: FormatContext,
5056 comptime fmt: []const u8,
5157 options: std.fmt.FormatOptions,
5258 writer: anytype,
5359) !void {
60 _ = options;
5461 comptime std.debug.assert(fmt.len == 0);
55 return tv.print(options, writer, 3);
62 return ctx.tv.print(writer, 3, ctx.target);
5663}
5764
65/// Prints the Value according to the Type, not according to the Value Tag.
5866pub fn print(
5967 tv: TypedValue,
60 options: std.fmt.FormatOptions,
6168 writer: anytype,
6269 level: u8,
70 target: std.Target,
6371) @TypeOf(writer).Error!void {
6472 var val = tv.val;
6573 var ty = tv.ty;
......@@ -148,7 +156,7 @@ pub fn print(
148156 try print(.{
149157 .ty = fields[i].ty,
150158 .val = vals[i],
151 }, options, writer, level - 1);
159 }, writer, level - 1, target);
152160 }
153161 return writer.writeAll(" }");
154162 } else {
......@@ -162,7 +170,7 @@ pub fn print(
162170 try print(.{
163171 .ty = elem_ty,
164172 .val = vals[i],
165 }, options, writer, level - 1);
173 }, writer, level - 1, target);
166174 }
167175 return writer.writeAll(" }");
168176 }
......@@ -177,12 +185,12 @@ pub fn print(
177185 try print(.{
178186 .ty = ty.unionTagType().?,
179187 .val = union_val.tag,
180 }, options, writer, level - 1);
188 }, writer, level - 1, target);
181189 try writer.writeAll(" = ");
182190 try print(.{
183 .ty = ty.unionFieldType(union_val.tag),
191 .ty = ty.unionFieldType(union_val.tag, target),
184192 .val = union_val.val,
185 }, options, writer, level - 1);
193 }, writer, level - 1, target);
186194
187195 return writer.writeAll(" }");
188196 },
......@@ -197,7 +205,7 @@ pub fn print(
197205 },
198206 .bool_true => return writer.writeAll("true"),
199207 .bool_false => return writer.writeAll("false"),
200 .ty => return val.castTag(.ty).?.data.format("", options, writer),
208 .ty => return val.castTag(.ty).?.data.print(writer, target),
201209 .int_type => {
202210 const int_type = val.castTag(.int_type).?.data;
203211 return writer.print("{s}{d}", .{
......@@ -205,10 +213,15 @@ pub fn print(
205213 int_type.bits,
206214 });
207215 },
208 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, writer),
209 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, writer),
216 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
217 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
210218 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
211219 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),
220 .lazy_align => {
221 const sub_ty = val.castTag(.lazy_align).?.data;
222 const x = sub_ty.abiAlignment(target);
223 return writer.print("{d}", .{x});
224 },
212225 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),
213226 .extern_fn => return writer.writeAll("(extern function)"),
214227 .variable => return writer.writeAll("(variable)"),
......@@ -220,7 +233,7 @@ pub fn print(
220233 return print(.{
221234 .ty = decl.ty,
222235 .val = decl.val,
223 }, options, writer, level - 1);
236 }, writer, level - 1, target);
224237 },
225238 .decl_ref => {
226239 const decl = val.castTag(.decl_ref).?.data;
......@@ -230,7 +243,7 @@ pub fn print(
230243 return print(.{
231244 .ty = decl.ty,
232245 .val = decl.val,
233 }, options, writer, level - 1);
246 }, writer, level - 1, target);
234247 },
235248 .elem_ptr => {
236249 const elem_ptr = val.castTag(.elem_ptr).?.data;
......@@ -238,7 +251,7 @@ pub fn print(
238251 try print(.{
239252 .ty = elem_ptr.elem_ty,
240253 .val = elem_ptr.array_ptr,
241 }, options, writer, level - 1);
254 }, writer, level - 1, target);
242255 return writer.print("[{}]", .{elem_ptr.index});
243256 },
244257 .field_ptr => {
......@@ -247,7 +260,7 @@ pub fn print(
247260 try print(.{
248261 .ty = field_ptr.container_ty,
249262 .val = field_ptr.container_ptr,
250 }, options, writer, level - 1);
263 }, writer, level - 1, target);
251264
252265 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
253266 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
......@@ -275,7 +288,7 @@ pub fn print(
275288 };
276289 while (i < max_aggregate_items) : (i += 1) {
277290 if (i != 0) try writer.writeAll(", ");
278 try print(elem_tv, options, writer, level - 1);
291 try print(elem_tv, writer, level - 1, target);
279292 }
280293 return writer.writeAll(" }");
281294 },
......@@ -287,7 +300,7 @@ pub fn print(
287300 try print(.{
288301 .ty = ty.elemType2(),
289302 .val = ty.sentinel().?,
290 }, options, writer, level - 1);
303 }, writer, level - 1, target);
291304 return writer.writeAll(" }");
292305 },
293306 .slice => return writer.writeAll("(slice)"),
src/arch/aarch64/CodeGen.zig+20-13
......@@ -796,7 +796,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
796796 const index = dbg_out.dbg_info.items.len;
797797 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
798798
799 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);
799 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.gpa, ty, .{
800 .target = self.target.*,
801 });
800802 if (!gop.found_existing) {
801803 gop.value_ptr.* = .{
802804 .off = undefined,
......@@ -835,8 +837,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
835837 return self.next_stack_offset;
836838 }
837839
840 const target = self.target.*;
838841 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
839 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
842 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
840843 };
841844 // TODO swap this for inst.ty.ptrAlign
842845 const abi_align = elem_ty.abiAlignment(self.target.*);
......@@ -845,8 +848,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
845848
846849fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
847850 const elem_ty = self.air.typeOfIndex(inst);
851 const target = self.target.*;
848852 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
849 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
853 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
850854 };
851855 const abi_align = elem_ty.abiAlignment(self.target.*);
852856 if (abi_align > self.stack_align)
......@@ -1372,6 +1376,7 @@ fn binOp(
13721376 lhs_ty: Type,
13731377 rhs_ty: Type,
13741378) InnerError!MCValue {
1379 const target = self.target.*;
13751380 switch (tag) {
13761381 // Arithmetic operations on integers and floats
13771382 .add,
......@@ -1381,7 +1386,7 @@ fn binOp(
13811386 .Float => return self.fail("TODO binary operations on floats", .{}),
13821387 .Vector => return self.fail("TODO binary operations on vectors", .{}),
13831388 .Int => {
1384 assert(lhs_ty.eql(rhs_ty));
1389 assert(lhs_ty.eql(rhs_ty, target));
13851390 const int_info = lhs_ty.intInfo(self.target.*);
13861391 if (int_info.bits <= 64) {
13871392 // Only say yes if the operation is
......@@ -1418,7 +1423,7 @@ fn binOp(
14181423 switch (lhs_ty.zigTypeTag()) {
14191424 .Vector => return self.fail("TODO binary operations on vectors", .{}),
14201425 .Int => {
1421 assert(lhs_ty.eql(rhs_ty));
1426 assert(lhs_ty.eql(rhs_ty, target));
14221427 const int_info = lhs_ty.intInfo(self.target.*);
14231428 if (int_info.bits <= 64) {
14241429 // TODO add optimisations for multiplication
......@@ -1440,7 +1445,7 @@ fn binOp(
14401445 switch (lhs_ty.zigTypeTag()) {
14411446 .Vector => return self.fail("TODO binary operations on vectors", .{}),
14421447 .Int => {
1443 assert(lhs_ty.eql(rhs_ty));
1448 assert(lhs_ty.eql(rhs_ty, target));
14441449 const int_info = lhs_ty.intInfo(self.target.*);
14451450 if (int_info.bits <= 64) {
14461451 // TODO implement bitwise operations with immediates
......@@ -2348,11 +2353,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
23482353 const ty = self.air.typeOfIndex(inst);
23492354
23502355 const result = self.args[arg_index];
2356 const target = self.target.*;
23512357 const mcv = switch (result) {
23522358 // Copy registers to the stack
23532359 .register => |reg| blk: {
23542360 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {
2355 return self.fail("type '{}' too big to fit into stack frame", .{ty});
2361 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(target)});
23562362 };
23572363 const abi_align = ty.abiAlignment(self.target.*);
23582364 const stack_offset = try self.allocMem(inst, abi_size, abi_align);
......@@ -3879,7 +3885,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
38793885}
38803886
38813887fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
3882 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });
3888 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });
38833889 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
38843890 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
38853891 };
......@@ -3907,6 +3913,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
39073913 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
39083914 return self.lowerDeclRef(typed_value, payload.data.decl);
39093915 }
3916 const target = self.target.*;
39103917
39113918 switch (typed_value.ty.zigTypeTag()) {
39123919 .Pointer => switch (typed_value.ty.ptrSize()) {
......@@ -3916,7 +3923,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
39163923 else => {
39173924 switch (typed_value.val.tag()) {
39183925 .int_u64 => {
3919 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
3926 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
39203927 },
39213928 .slice => {
39223929 return self.lowerUnnamedConst(typed_value);
......@@ -3935,7 +3942,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
39353942 const signed = typed_value.val.toSignedInt();
39363943 break :blk @bitCast(u64, signed);
39373944 },
3938 .unsigned => typed_value.val.toUnsignedInt(),
3945 .unsigned => typed_value.val.toUnsignedInt(target),
39393946 };
39403947
39413948 return MCValue{ .immediate = unsigned };
......@@ -4004,20 +4011,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
40044011 }
40054012
40064013 _ = pl;
4007 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});
4014 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()});
40084015 } else {
40094016 if (!payload_type.hasRuntimeBits()) {
40104017 // We use the error type directly as the type.
40114018 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
40124019 }
40134020
4014 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});
4021 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()});
40154022 }
40164023 },
40174024 .Struct => {
40184025 return self.lowerUnnamedConst(typed_value);
40194026 },
4020 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),
4027 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
40214028 }
40224029}
40234030
src/arch/arm/CodeGen.zig+14-10
......@@ -801,8 +801,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
801801 return self.next_stack_offset;
802802 }
803803
804 const target = self.target.*;
804805 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
805 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
806 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
806807 };
807808 // TODO swap this for inst.ty.ptrAlign
808809 const abi_align = elem_ty.abiAlignment(self.target.*);
......@@ -811,8 +812,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
811812
812813fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
813814 const elem_ty = self.air.typeOfIndex(inst);
815 const target = self.target.*;
814816 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
815 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
817 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
816818 };
817819 const abi_align = elem_ty.abiAlignment(self.target.*);
818820 if (abi_align > self.stack_align)
......@@ -2195,6 +2197,7 @@ fn binOp(
21952197 lhs_ty: Type,
21962198 rhs_ty: Type,
21972199) InnerError!MCValue {
2200 const target = self.target.*;
21982201 switch (tag) {
21992202 .add,
22002203 .sub,
......@@ -2204,7 +2207,7 @@ fn binOp(
22042207 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
22052208 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
22062209 .Int => {
2207 assert(lhs_ty.eql(rhs_ty));
2210 assert(lhs_ty.eql(rhs_ty, target));
22082211 const int_info = lhs_ty.intInfo(self.target.*);
22092212 if (int_info.bits <= 32) {
22102213 // Only say yes if the operation is
......@@ -2245,7 +2248,7 @@ fn binOp(
22452248 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
22462249 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
22472250 .Int => {
2248 assert(lhs_ty.eql(rhs_ty));
2251 assert(lhs_ty.eql(rhs_ty, target));
22492252 const int_info = lhs_ty.intInfo(self.target.*);
22502253 if (int_info.bits <= 32) {
22512254 // TODO add optimisations for multiplication
......@@ -2299,7 +2302,7 @@ fn binOp(
22992302 switch (lhs_ty.zigTypeTag()) {
23002303 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
23012304 .Int => {
2302 assert(lhs_ty.eql(rhs_ty));
2305 assert(lhs_ty.eql(rhs_ty, target));
23032306 const int_info = lhs_ty.intInfo(self.target.*);
23042307 if (int_info.bits <= 32) {
23052308 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
......@@ -4376,6 +4379,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
43764379 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
43774380 return self.lowerDeclRef(typed_value, payload.data.decl);
43784381 }
4382 const target = self.target.*;
43794383
43804384 switch (typed_value.ty.zigTypeTag()) {
43814385 .Array => {
......@@ -4388,7 +4392,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
43884392 else => {
43894393 switch (typed_value.val.tag()) {
43904394 .int_u64 => {
4391 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt()) };
4395 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) };
43924396 },
43934397 .slice => {
43944398 return self.lowerUnnamedConst(typed_value);
......@@ -4407,7 +4411,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
44074411 const signed = @intCast(i32, typed_value.val.toSignedInt());
44084412 break :blk @bitCast(u32, signed);
44094413 },
4410 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt()),
4414 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt(target)),
44114415 };
44124416
44134417 return MCValue{ .immediate = unsigned };
......@@ -4476,20 +4480,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
44764480 }
44774481
44784482 _ = pl;
4479 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});
4483 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()});
44804484 } else {
44814485 if (!payload_type.hasRuntimeBits()) {
44824486 // We use the error type directly as the type.
44834487 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
44844488 }
44854489
4486 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});
4490 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()});
44874491 }
44884492 },
44894493 .Struct => {
44904494 return self.lowerUnnamedConst(typed_value);
44914495 },
4492 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),
4496 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
44934497 }
44944498}
44954499
src/arch/arm/Emit.zig+3-2
......@@ -384,7 +384,7 @@ fn addDbgInfoTypeReloc(self: *Emit, ty: Type) !void {
384384 const index = dbg_out.dbg_info.items.len;
385385 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
386386
387 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.bin_file.allocator, ty);
387 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.bin_file.allocator, ty, .{ .target = self.target.* });
388388 if (!gop.found_existing) {
389389 gop.value_ptr.* = .{
390390 .off = undefined,
......@@ -404,6 +404,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
404404 const ty = self.function.air.instructions.items(.data)[inst].ty;
405405 const name = self.function.mod_fn.getParamName(arg_index);
406406 const name_with_null = name.ptr[0 .. name.len + 1];
407 const target = self.target.*;
407408
408409 switch (mcv) {
409410 .register => |reg| {
......@@ -429,7 +430,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
429430 switch (self.debug_output) {
430431 .dwarf => |dbg_out| {
431432 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {
432 return self.fail("type '{}' too big to fit into stack frame", .{ty});
433 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(target)});
433434 };
434435 const adjusted_stack_offset = switch (mcv) {
435436 .stack_offset => |offset| math.negateCast(offset + abi_size) catch {
src/arch/riscv64/CodeGen.zig+15-10
......@@ -749,7 +749,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
749749 const index = dbg_out.dbg_info.items.len;
750750 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
751751
752 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);
752 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(self.gpa, ty, .{
753 .target = self.target.*,
754 });
753755 if (!gop.found_existing) {
754756 gop.value_ptr.* = .{
755757 .off = undefined,
......@@ -781,8 +783,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
781783/// Use a pointer instruction as the basis for allocating stack memory.
782784fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
783785 const elem_ty = self.air.typeOfIndex(inst).elemType();
786 const target = self.target.*;
784787 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
785 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
788 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
786789 };
787790 // TODO swap this for inst.ty.ptrAlign
788791 const abi_align = elem_ty.abiAlignment(self.target.*);
......@@ -791,8 +794,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
791794
792795fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
793796 const elem_ty = self.air.typeOfIndex(inst);
797 const target = self.target.*;
794798 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
795 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
799 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
796800 };
797801 const abi_align = elem_ty.abiAlignment(self.target.*);
798802 if (abi_align > self.stack_align)
......@@ -1048,7 +1052,7 @@ fn binOp(
10481052 .Float => return self.fail("TODO binary operations on floats", .{}),
10491053 .Vector => return self.fail("TODO binary operations on vectors", .{}),
10501054 .Int => {
1051 assert(lhs_ty.eql(rhs_ty));
1055 assert(lhs_ty.eql(rhs_ty, self.target.*));
10521056 const int_info = lhs_ty.intInfo(self.target.*);
10531057 if (int_info.bits <= 64) {
10541058 // TODO immediate operands
......@@ -1778,7 +1782,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
17781782 if (self.liveness.isUnused(inst))
17791783 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
17801784 const ty = self.air.typeOf(bin_op.lhs);
1781 assert(ty.eql(self.air.typeOf(bin_op.rhs)));
1785 assert(ty.eql(self.air.typeOf(bin_op.rhs), self.target.*));
17821786 if (ty.zigTypeTag() == .ErrorSet)
17831787 return self.fail("TODO implement cmp for errors", .{});
17841788
......@@ -2531,6 +2535,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25312535 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
25322536 return self.lowerDeclRef(typed_value, payload.data.decl);
25332537 }
2538 const target = self.target.*;
25342539 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
25352540 switch (typed_value.ty.zigTypeTag()) {
25362541 .Pointer => switch (typed_value.ty.ptrSize()) {
......@@ -2538,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25382543 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
25392544 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);
25402545 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });
2541 const slice_len = typed_value.val.sliceLen();
2546 const slice_len = typed_value.val.sliceLen(target);
25422547 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean
25432548 // the Sema code needs to use anonymous Decls or alloca instructions to store data.
25442549 const ptr_imm = ptr_mcv.memory;
......@@ -2549,7 +2554,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25492554 },
25502555 else => {
25512556 if (typed_value.val.tag() == .int_u64) {
2552 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
2557 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
25532558 }
25542559 return self.fail("TODO codegen more kinds of const pointers", .{});
25552560 },
......@@ -2559,7 +2564,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25592564 if (info.bits > ptr_bits or info.signedness == .signed) {
25602565 return self.fail("TODO const int bigger than ptr and signed int", .{});
25612566 }
2562 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
2567 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
25632568 },
25642569 .Bool => {
25652570 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };
......@@ -2629,9 +2634,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
26292634 return self.genTypedValue(.{ .ty = error_type, .val = sub_val });
26302635 }
26312636
2632 return self.fail("TODO implement error union const of type '{}'", .{typed_value.ty});
2637 return self.fail("TODO implement error union const of type '{}'", .{typed_value.ty.fmtDebug()});
26332638 },
2634 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),
2639 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}),
26352640 }
26362641}
26372642
src/arch/wasm/CodeGen.zig+21-14
......@@ -1021,7 +1021,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {
10211021 }
10221022
10231023 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {
1024 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ ty, ty.abiSize(self.target) });
1024 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1025 ty.fmt(self.target), ty.abiSize(self.target),
1026 });
10251027 };
10261028 const abi_align = ty.abiAlignment(self.target);
10271029
......@@ -1053,7 +1055,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {
10531055
10541056 const abi_alignment = ptr_ty.ptrAlignment(self.target);
10551057 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {
1056 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{ pointee_ty, pointee_ty.abiSize(self.target) });
1058 return self.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1059 pointee_ty.fmt(self.target), pointee_ty.abiSize(self.target),
1060 });
10571061 };
10581062 if (abi_alignment > self.stack_alignment) {
10591063 self.stack_alignment = abi_alignment;
......@@ -1750,7 +1754,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
17501754 const operand_ty = self.air.typeOfIndex(inst);
17511755
17521756 if (isByRef(operand_ty, self.target)) {
1753 return self.fail("TODO: Implement binary operation for type: {}", .{operand_ty});
1757 return self.fail("TODO: Implement binary operation for type: {}", .{operand_ty.fmtDebug()});
17541758 }
17551759
17561760 try self.emitWValue(lhs);
......@@ -1918,6 +1922,8 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
19181922 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);
19191923 }
19201924
1925 const target = self.target;
1926
19211927 switch (ty.zigTypeTag()) {
19221928 .Int => {
19231929 const int_info = ty.intInfo(self.target);
......@@ -1929,13 +1935,13 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
19291935 else => unreachable,
19301936 },
19311937 .unsigned => switch (int_info.bits) {
1932 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },
1933 33...64 => return WValue{ .imm64 = val.toUnsignedInt() },
1938 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1939 33...64 => return WValue{ .imm64 = val.toUnsignedInt(target) },
19341940 else => unreachable,
19351941 },
19361942 }
19371943 },
1938 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },
1944 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
19391945 .Float => switch (ty.floatBits(self.target)) {
19401946 0...32 => return WValue{ .float32 = val.toFloat(f32) },
19411947 33...64 => return WValue{ .float64 = val.toFloat(f64) },
......@@ -1945,7 +1951,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
19451951 .field_ptr, .elem_ptr => {
19461952 return self.lowerParentPtr(val, ty.childType());
19471953 },
1948 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },
1954 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
19491955 .zero, .null_value => return WValue{ .imm32 = 0 },
19501956 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),
19511957 },
......@@ -2044,6 +2050,7 @@ fn emitUndefined(self: *Self, ty: Type) InnerError!WValue {
20442050/// It's illegal to provide a value with a type that cannot be represented
20452051/// as an integer value.
20462052fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
2053 const target = self.target;
20472054 switch (ty.zigTypeTag()) {
20482055 .Enum => {
20492056 if (val.castTag(.enum_field_index)) |field_index| {
......@@ -2071,7 +2078,7 @@ fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
20712078 },
20722079 .Int => switch (ty.intInfo(self.target).signedness) {
20732080 .signed => return @truncate(i32, val.toSignedInt()),
2074 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt())),
2081 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(target))),
20752082 },
20762083 .ErrorSet => {
20772084 const kv = self.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
......@@ -2296,7 +2303,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
22962303 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();
22972304 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {
22982305 return self.fail("Field type '{}' too big to fit into stack frame", .{
2299 struct_ty.structFieldType(extra.data.field_index),
2306 struct_ty.structFieldType(extra.data.field_index).fmt(self.target),
23002307 });
23012308 };
23022309 return self.structFieldPtr(struct_ptr, offset);
......@@ -2309,7 +2316,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr
23092316 const field_ty = struct_ty.structFieldType(index);
23102317 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {
23112318 return self.fail("Field type '{}' too big to fit into stack frame", .{
2312 field_ty,
2319 field_ty.fmt(self.target),
23132320 });
23142321 };
23152322 return self.structFieldPtr(struct_ptr, offset);
......@@ -2335,7 +2342,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
23352342 const field_ty = struct_ty.structFieldType(field_index);
23362343 if (!field_ty.hasRuntimeBits()) return WValue{ .none = {} };
23372344 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {
2338 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty});
2345 return self.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(self.target)});
23392346 };
23402347
23412348 if (isByRef(field_ty, self.target)) {
......@@ -2716,7 +2723,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
27162723 var buf: Type.Payload.ElemType = undefined;
27172724 const payload_ty = opt_ty.optionalChild(&buf);
27182725 if (!payload_ty.hasRuntimeBits()) {
2719 return self.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty});
2726 return self.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()});
27202727 }
27212728
27222729 if (opt_ty.isPtrLikeOptional()) {
......@@ -2724,7 +2731,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
27242731 }
27252732
27262733 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2727 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty});
2734 return self.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(self.target)});
27282735 };
27292736
27302737 try self.emitWValue(operand);
......@@ -2753,7 +2760,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
27532760 return operand;
27542761 }
27552762 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {
2756 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty});
2763 return self.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(self.target)});
27572764 };
27582765
27592766 // Create optional type, set the non-null bit, and store the operand inside the optional type
src/arch/x86_64/CodeGen.zig+12-8
......@@ -892,8 +892,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
892892 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));
893893 }
894894
895 const target = self.target.*;
895896 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
896 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
897 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
897898 };
898899 // TODO swap this for inst.ty.ptrAlign
899900 const abi_align = ptr_ty.ptrAlignment(self.target.*);
......@@ -902,8 +903,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
902903
903904fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
904905 const elem_ty = self.air.typeOfIndex(inst);
906 const target = self.target.*;
905907 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {
906 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty});
908 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(target)});
907909 };
908910 const abi_align = elem_ty.abiAlignment(self.target.*);
909911 if (abi_align > self.stack_align)
......@@ -1142,7 +1144,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void {
11421144
11431145 const ty = self.air.typeOfIndex(inst);
11441146 if (ty.zigTypeTag() != .Int) {
1145 return self.fail("TODO implement min for type {}", .{ty});
1147 return self.fail("TODO implement min for type {}", .{ty.fmtDebug()});
11461148 }
11471149 const signedness = ty.intInfo(self.target.*).signedness;
11481150 const result: MCValue = result: {
......@@ -1676,13 +1678,13 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void {
16761678 const ty = self.air.typeOfIndex(inst);
16771679 const tag = self.air.instructions.items(.tag)[inst];
16781680 switch (tag) {
1679 .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty }),
1681 .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty.fmtDebug() }),
16801682 .shl => {},
16811683 else => unreachable,
16821684 }
16831685
16841686 if (ty.zigTypeTag() != .Int) {
1685 return self.fail("TODO implement .shl for type {}", .{ty});
1687 return self.fail("TODO implement .shl for type {}", .{ty.fmtDebug()});
16861688 }
16871689 if (ty.abiSize(self.target.*) > 8) {
16881690 return self.fail("TODO implement .shl for integers larger than 8 bytes", .{});
......@@ -5820,7 +5822,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
58205822}
58215823
58225824fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
5823 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val.fmtDebug() });
5825 log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });
58245826 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
58255827 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
58265828 };
......@@ -5850,13 +5852,15 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
58505852 return self.lowerDeclRef(typed_value, payload.data.decl);
58515853 }
58525854
5855 const target = self.target.*;
5856
58535857 switch (typed_value.ty.zigTypeTag()) {
58545858 .Pointer => switch (typed_value.ty.ptrSize()) {
58555859 .Slice => {},
58565860 else => {
58575861 switch (typed_value.val.tag()) {
58585862 .int_u64 => {
5859 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
5863 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
58605864 },
58615865 else => {},
58625866 }
......@@ -5868,7 +5872,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
58685872 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
58695873 }
58705874 if (!(info.bits > ptr_bits or info.signedness == .signed)) {
5871 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
5875 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
58725876 }
58735877 },
58745878 .Bool => {
src/arch/x86_64/Emit.zig+3-1
......@@ -1118,7 +1118,9 @@ fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {
11181118 const index = dbg_out.dbg_info.items.len;
11191119 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
11201120
1121 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(emit.bin_file.allocator, ty);
1121 const gop = try dbg_out.dbg_info_type_relocs.getOrPutContext(emit.bin_file.allocator, ty, .{
1122 .target = emit.target.*,
1123 });
11221124 if (!gop.found_existing) {
11231125 gop.value_ptr.* = .{
11241126 .off = undefined,
src/codegen.zig+19-16
......@@ -165,7 +165,10 @@ pub fn generateSymbol(
165165 const target = bin_file.options.target;
166166 const endian = target.cpu.arch.endian();
167167
168 log.debug("generateSymbol: ty = {}, val = {}", .{ typed_value.ty, typed_value.val.fmtDebug() });
168 log.debug("generateSymbol: ty = {}, val = {}", .{
169 typed_value.ty.fmtDebug(),
170 typed_value.val.fmtDebug(),
171 });
169172
170173 if (typed_value.val.isUndefDeep()) {
171174 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));
......@@ -295,11 +298,11 @@ pub fn generateSymbol(
295298 .zero, .one, .int_u64, .int_big_positive => {
296299 switch (target.cpu.arch.ptrBitWidth()) {
297300 32 => {
298 const x = typed_value.val.toUnsignedInt();
301 const x = typed_value.val.toUnsignedInt(target);
299302 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
300303 },
301304 64 => {
302 const x = typed_value.val.toUnsignedInt();
305 const x = typed_value.val.toUnsignedInt(target);
303306 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
304307 },
305308 else => unreachable,
......@@ -433,7 +436,7 @@ pub fn generateSymbol(
433436 // TODO populate .debug_info for the integer
434437 const info = typed_value.ty.intInfo(bin_file.options.target);
435438 if (info.bits <= 8) {
436 const x = @intCast(u8, typed_value.val.toUnsignedInt());
439 const x = @intCast(u8, typed_value.val.toUnsignedInt(target));
437440 try code.append(x);
438441 return Result{ .appended = {} };
439442 }
......@@ -443,20 +446,20 @@ pub fn generateSymbol(
443446 bin_file.allocator,
444447 src_loc,
445448 "TODO implement generateSymbol for big ints ('{}')",
446 .{typed_value.ty},
449 .{typed_value.ty.fmtDebug()},
447450 ),
448451 };
449452 }
450453 switch (info.signedness) {
451454 .unsigned => {
452455 if (info.bits <= 16) {
453 const x = @intCast(u16, typed_value.val.toUnsignedInt());
456 const x = @intCast(u16, typed_value.val.toUnsignedInt(target));
454457 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
455458 } else if (info.bits <= 32) {
456 const x = @intCast(u32, typed_value.val.toUnsignedInt());
459 const x = @intCast(u32, typed_value.val.toUnsignedInt(target));
457460 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
458461 } else {
459 const x = typed_value.val.toUnsignedInt();
462 const x = typed_value.val.toUnsignedInt(target);
460463 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
461464 }
462465 },
......@@ -482,7 +485,7 @@ pub fn generateSymbol(
482485
483486 const info = typed_value.ty.intInfo(target);
484487 if (info.bits <= 8) {
485 const x = @intCast(u8, int_val.toUnsignedInt());
488 const x = @intCast(u8, int_val.toUnsignedInt(target));
486489 try code.append(x);
487490 return Result{ .appended = {} };
488491 }
......@@ -492,20 +495,20 @@ pub fn generateSymbol(
492495 bin_file.allocator,
493496 src_loc,
494497 "TODO implement generateSymbol for big int enums ('{}')",
495 .{typed_value.ty},
498 .{typed_value.ty.fmtDebug()},
496499 ),
497500 };
498501 }
499502 switch (info.signedness) {
500503 .unsigned => {
501504 if (info.bits <= 16) {
502 const x = @intCast(u16, int_val.toUnsignedInt());
505 const x = @intCast(u16, int_val.toUnsignedInt(target));
503506 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
504507 } else if (info.bits <= 32) {
505 const x = @intCast(u32, int_val.toUnsignedInt());
508 const x = @intCast(u32, int_val.toUnsignedInt(target));
506509 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
507510 } else {
508 const x = int_val.toUnsignedInt();
511 const x = int_val.toUnsignedInt(target);
509512 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
510513 }
511514 },
......@@ -597,7 +600,7 @@ pub fn generateSymbol(
597600 }
598601
599602 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;
600 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;
603 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
601604 assert(union_ty.haveFieldTypes());
602605 const field_ty = union_ty.fields.values()[field_index].ty;
603606 if (!field_ty.hasRuntimeBits()) {
......@@ -787,6 +790,7 @@ fn lowerDeclRef(
787790 debug_output: DebugInfoOutput,
788791 reloc_info: RelocInfo,
789792) GenerateSymbolError!Result {
793 const target = bin_file.options.target;
790794 if (typed_value.ty.isSlice()) {
791795 // generate ptr
792796 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
......@@ -805,7 +809,7 @@ fn lowerDeclRef(
805809 // generate length
806810 var slice_len: Value.Payload.U64 = .{
807811 .base = .{ .tag = .int_u64 },
808 .data = typed_value.val.sliceLen(),
812 .data = typed_value.val.sliceLen(target),
809813 };
810814 switch (try generateSymbol(bin_file, src_loc, .{
811815 .ty = Type.usize,
......@@ -821,7 +825,6 @@ fn lowerDeclRef(
821825 return Result{ .appended = {} };
822826 }
823827
824 const target = bin_file.options.target;
825828 const ptr_width = target.cpu.arch.ptrBitWidth();
826829 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
827830 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
src/codegen/c.zig+36-21
......@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(
5656 true,
5757);
5858
59const FormatTypeAsCIdentContext = struct {
60 ty: Type,
61 target: std.Target,
62};
63
64/// TODO make this not cut off at 128 bytes
5965fn formatTypeAsCIdentifier(
60 data: Type,
66 data: FormatTypeAsCIdentContext,
6167 comptime fmt: []const u8,
6268 options: std.fmt.FormatOptions,
6369 writer: anytype,
......@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(
6571 _ = fmt;
6672 _ = options;
6773 var buffer = [1]u8{0} ** 128;
68 // We don't care if it gets cut off, it's still more unique than a number
69 var buf = std.fmt.bufPrint(&buffer, "{}", .{data}) catch &buffer;
74 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer;
7075 return formatIdent(buf, "", .{}, writer);
7176}
7277
73pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) {
74 return .{ .data = t };
78pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) {
79 return .{ .data = .{
80 .ty = ty,
81 .target = target,
82 } };
7583}
7684
7785const reserved_idents = std.ComptimeStringMap(void, .{
......@@ -369,6 +377,8 @@ pub const DeclGen = struct {
369377 ) error{ OutOfMemory, AnalysisFail }!void {
370378 decl.markAlive();
371379
380 const target = dg.module.getTarget();
381
372382 if (ty.isSlice()) {
373383 try writer.writeByte('(');
374384 try dg.renderTypecast(writer, ty);
......@@ -376,7 +386,7 @@ pub const DeclGen = struct {
376386 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
377387 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());
378388 try writer.writeAll(", ");
379 try writer.print("{d}", .{val.sliceLen()});
389 try writer.print("{d}", .{val.sliceLen(target)});
380390 try writer.writeAll("}");
381391 return;
382392 }
......@@ -388,7 +398,7 @@ pub const DeclGen = struct {
388398 // somewhere and we should let the C compiler tell us about it.
389399 if (ty.castPtrToFn() == null) {
390400 // Determine if we must pointer cast.
391 if (ty.eql(decl.ty)) {
401 if (ty.eql(decl.ty, target)) {
392402 try writer.writeByte('&');
393403 try dg.renderDeclName(writer, decl);
394404 return;
......@@ -508,6 +518,7 @@ pub const DeclGen = struct {
508518 ty: Type,
509519 val: Value,
510520 ) error{ OutOfMemory, AnalysisFail }!void {
521 const target = dg.module.getTarget();
511522 if (val.isUndefDeep()) {
512523 switch (ty.zigTypeTag()) {
513524 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
......@@ -551,7 +562,7 @@ pub const DeclGen = struct {
551562 else => {
552563 if (ty.isSignedInt())
553564 return writer.print("{d}", .{val.toSignedInt()});
554 return writer.print("{d}u", .{val.toUnsignedInt()});
565 return writer.print("{d}u", .{val.toUnsignedInt(target)});
555566 },
556567 },
557568 .Float => {
......@@ -609,7 +620,7 @@ pub const DeclGen = struct {
609620 .int_u64, .one => {
610621 try writer.writeAll("((");
611622 try dg.renderTypecast(writer, ty);
612 try writer.print(")0x{x}u)", .{val.toUnsignedInt()});
623 try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)});
613624 },
614625 else => unreachable,
615626 },
......@@ -653,7 +664,6 @@ pub const DeclGen = struct {
653664 if (ty.isPtrLikeOptional()) {
654665 return dg.renderValue(writer, payload_type, val);
655666 }
656 const target = dg.module.getTarget();
657667 if (payload_type.abiSize(target) == 0) {
658668 const is_null = val.castTag(.opt_payload) == null;
659669 return writer.print("{}", .{is_null});
......@@ -773,7 +783,6 @@ pub const DeclGen = struct {
773783 .Union => {
774784 const union_obj = val.castTag(.@"union").?.data;
775785 const union_ty = ty.cast(Type.Payload.Union).?.data;
776 const target = dg.module.getTarget();
777786 const layout = ty.unionGetLayout(target);
778787
779788 try writer.writeAll("(");
......@@ -789,7 +798,7 @@ pub const DeclGen = struct {
789798 try writer.writeAll(".payload = {");
790799 }
791800
792 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;
801 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
793802 const field_ty = ty.unionFields().values()[index].ty;
794803 const field_name = ty.unionFields().keys()[index];
795804 if (field_ty.hasRuntimeBits()) {
......@@ -879,8 +888,8 @@ pub const DeclGen = struct {
879888 try bw.writeAll(" (*");
880889
881890 const name_start = buffer.items.len;
882 // TODO: typeToCIdentifier truncates to 128 bytes, we probably don't want to do this
883 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t)});
891 const target = dg.module.getTarget();
892 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)});
884893 const name_end = buffer.items.len - 2;
885894
886895 const param_len = fn_info.param_types.len;
......@@ -934,10 +943,11 @@ pub const DeclGen = struct {
934943
935944 try bw.writeAll("; size_t len; } ");
936945 const name_index = buffer.items.len;
946 const target = dg.module.getTarget();
937947 if (t.isConstPtr()) {
938 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)});
948 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)});
939949 } else {
940 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)});
950 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)});
941951 }
942952 if (ptr_sentinel) |s| {
943953 try bw.writeAll("_s_");
......@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {
10231033 try buffer.appendSlice("} ");
10241034
10251035 const name_start = buffer.items.len;
1026 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t)});
1036 const target = dg.module.getTarget();
1037 try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, target)});
10271038
10281039 const rendered = buffer.toOwnedSlice();
10291040 errdefer dg.typedefs.allocator.free(rendered);
......@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {
11071118 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
11081119 try bw.writeAll("; uint16_t error; } ");
11091120 const name_index = buffer.items.len;
1121 const target = dg.module.getTarget();
11101122 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {
11111123 const func = inf_err_set_payload.data.func;
11121124 try bw.writeAll("zig_E_");
......@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {
11141126 try bw.writeAll(";\n");
11151127 } else {
11161128 try bw.print("zig_E_{s}_{s};\n", .{
1117 typeToCIdentifier(err_set_type), typeToCIdentifier(child_type),
1129 typeToCIdentifier(err_set_type, target), typeToCIdentifier(child_type, target),
11181130 });
11191131 }
11201132
......@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {
11441156 try dg.renderType(bw, elem_type);
11451157
11461158 const name_start = buffer.items.len + 1;
1147 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type), c_len });
1159 const target = dg.module.getTarget();
1160 try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, target), c_len });
11481161 const name_end = buffer.items.len;
11491162
11501163 try bw.print("[{d}];\n", .{c_len});
......@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {
11721185 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
11731186 try bw.writeAll("; bool is_null; } ");
11741187 const name_index = buffer.items.len;
1175 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type)});
1188 const target = dg.module.getTarget();
1189 try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, target)});
11761190
11771191 const rendered = buffer.toOwnedSlice();
11781192 errdefer dg.typedefs.allocator.free(rendered);
......@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
21772191 if (src_val_is_undefined)
21782192 return try airStoreUndefined(f, dest_ptr);
21792193
2194 const target = f.object.dg.module.getTarget();
21802195 const writer = f.object.writer();
21812196 if (lhs_child_type.zigTypeTag() == .Array) {
21822197 // For this memcpy to safely work we need the rhs to have the same
21832198 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
21842199 const rhs_type = f.air.typeOf(bin_op.rhs);
2185 assert(rhs_type.eql(lhs_child_type));
2200 assert(rhs_type.eql(lhs_child_type, target));
21862201
21872202 // If the source is a constant, writeCValue will emit a brace initialization
21882203 // so work around this by initializing into new local.
src/codegen/llvm.zig+54-52
......@@ -812,7 +812,7 @@ pub const Object = struct {
812812 const gpa = o.gpa;
813813 // Be careful not to reference this `gop` variable after any recursive calls
814814 // to `lowerDebugType`.
815 const gop = try o.di_type_map.getOrPut(gpa, ty);
815 const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .target = o.target });
816816 if (gop.found_existing) {
817817 const annotated = gop.value_ptr.*;
818818 const di_type = annotated.toDIType();
......@@ -825,7 +825,7 @@ pub const Object = struct {
825825 };
826826 return o.lowerDebugTypeImpl(entry, resolve, di_type);
827827 }
828 errdefer assert(o.di_type_map.orderedRemove(ty));
828 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target }));
829829 // The Type memory is ephemeral; since we want to store a longer-lived
830830 // reference, we need to copy it here.
831831 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
......@@ -856,7 +856,7 @@ pub const Object = struct {
856856 .Int => {
857857 const info = ty.intInfo(target);
858858 assert(info.bits != 0);
859 const name = try ty.nameAlloc(gpa);
859 const name = try ty.nameAlloc(gpa, target);
860860 defer gpa.free(name);
861861 const dwarf_encoding: c_uint = switch (info.signedness) {
862862 .signed => DW.ATE.signed,
......@@ -873,7 +873,7 @@ pub const Object = struct {
873873 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);
874874 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
875875 // means we can't use `gop` anymore.
876 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));
876 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
877877 return enum_di_ty;
878878 }
879879
......@@ -903,7 +903,7 @@ pub const Object = struct {
903903 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
904904 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
905905
906 const name = try ty.nameAlloc(gpa);
906 const name = try ty.nameAlloc(gpa, target);
907907 defer gpa.free(name);
908908 var buffer: Type.Payload.Bits = undefined;
909909 const int_ty = ty.intTagType(&buffer);
......@@ -921,12 +921,12 @@ pub const Object = struct {
921921 "",
922922 );
923923 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
924 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty));
924 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .target = o.target });
925925 return enum_di_ty;
926926 },
927927 .Float => {
928928 const bits = ty.floatBits(target);
929 const name = try ty.nameAlloc(gpa);
929 const name = try ty.nameAlloc(gpa, target);
930930 defer gpa.free(name);
931931 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
932932 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
......@@ -974,7 +974,7 @@ pub const Object = struct {
974974 const bland_ptr_ty = Type.initPayload(&payload.base);
975975 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
976976 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
977 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve));
977 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .target = o.target });
978978 return ptr_di_ty;
979979 }
980980
......@@ -983,7 +983,7 @@ pub const Object = struct {
983983 const ptr_ty = ty.slicePtrFieldType(&buf);
984984 const len_ty = Type.usize;
985985
986 const name = try ty.nameAlloc(gpa);
986 const name = try ty.nameAlloc(gpa, target);
987987 defer gpa.free(name);
988988 const di_file: ?*llvm.DIFile = null;
989989 const line = 0;
......@@ -1054,12 +1054,12 @@ pub const Object = struct {
10541054 );
10551055 dib.replaceTemporary(fwd_decl, full_di_ty);
10561056 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1057 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
1057 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
10581058 return full_di_ty;
10591059 }
10601060
10611061 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);
1062 const name = try ty.nameAlloc(gpa);
1062 const name = try ty.nameAlloc(gpa, target);
10631063 defer gpa.free(name);
10641064 const ptr_di_ty = dib.createPointerType(
10651065 elem_di_ty,
......@@ -1068,7 +1068,7 @@ pub const Object = struct {
10681068 name,
10691069 );
10701070 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1071 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));
1071 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
10721072 return ptr_di_ty;
10731073 },
10741074 .Opaque => {
......@@ -1077,7 +1077,7 @@ pub const Object = struct {
10771077 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
10781078 return di_ty;
10791079 }
1080 const name = try ty.nameAlloc(gpa);
1080 const name = try ty.nameAlloc(gpa, target);
10811081 defer gpa.free(name);
10821082 const owner_decl = ty.getOwnerDecl();
10831083 const opaque_di_ty = dib.createForwardDeclType(
......@@ -1089,7 +1089,7 @@ pub const Object = struct {
10891089 );
10901090 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
10911091 // means we can't use `gop` anymore.
1092 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty));
1092 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .target = o.target });
10931093 return opaque_di_ty;
10941094 },
10951095 .Array => {
......@@ -1100,7 +1100,7 @@ pub const Object = struct {
11001100 @intCast(c_int, ty.arrayLen()),
11011101 );
11021102 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1103 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty));
1103 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .target = o.target });
11041104 return array_di_ty;
11051105 },
11061106 .Vector => {
......@@ -1111,11 +1111,11 @@ pub const Object = struct {
11111111 ty.vectorLen(),
11121112 );
11131113 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1114 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty));
1114 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .target = o.target });
11151115 return vector_di_ty;
11161116 },
11171117 .Optional => {
1118 const name = try ty.nameAlloc(gpa);
1118 const name = try ty.nameAlloc(gpa, target);
11191119 defer gpa.free(name);
11201120 var buf: Type.Payload.ElemType = undefined;
11211121 const child_ty = ty.optionalChild(&buf);
......@@ -1127,7 +1127,7 @@ pub const Object = struct {
11271127 if (ty.isPtrLikeOptional()) {
11281128 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
11291129 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1130 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty));
1130 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .target = o.target });
11311131 return ptr_di_ty;
11321132 }
11331133
......@@ -1200,7 +1200,7 @@ pub const Object = struct {
12001200 );
12011201 dib.replaceTemporary(fwd_decl, full_di_ty);
12021202 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1203 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
1203 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
12041204 return full_di_ty;
12051205 },
12061206 .ErrorUnion => {
......@@ -1209,10 +1209,10 @@ pub const Object = struct {
12091209 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
12101210 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);
12111211 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1212 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty));
1212 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .target = o.target });
12131213 return err_set_di_ty;
12141214 }
1215 const name = try ty.nameAlloc(gpa);
1215 const name = try ty.nameAlloc(gpa, target);
12161216 defer gpa.free(name);
12171217 const di_file: ?*llvm.DIFile = null;
12181218 const line = 0;
......@@ -1282,7 +1282,7 @@ pub const Object = struct {
12821282 );
12831283 dib.replaceTemporary(fwd_decl, full_di_ty);
12841284 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1285 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
1285 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
12861286 return full_di_ty;
12871287 },
12881288 .ErrorSet => {
......@@ -1294,7 +1294,7 @@ pub const Object = struct {
12941294 },
12951295 .Struct => {
12961296 const compile_unit_scope = o.di_compile_unit.?.toScope();
1297 const name = try ty.nameAlloc(gpa);
1297 const name = try ty.nameAlloc(gpa, target);
12981298 defer gpa.free(name);
12991299
13001300 if (ty.castTag(.@"struct")) |payload| {
......@@ -1381,7 +1381,7 @@ pub const Object = struct {
13811381 );
13821382 dib.replaceTemporary(fwd_decl, full_di_ty);
13831383 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1384 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
1384 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
13851385 return full_di_ty;
13861386 }
13871387
......@@ -1395,7 +1395,7 @@ pub const Object = struct {
13951395 dib.replaceTemporary(fwd_decl, struct_di_ty);
13961396 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
13971397 // means we can't use `gop` anymore.
1398 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));
1398 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
13991399 return struct_di_ty;
14001400 }
14011401 }
......@@ -1406,7 +1406,7 @@ pub const Object = struct {
14061406 dib.replaceTemporary(fwd_decl, struct_di_ty);
14071407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
14081408 // means we can't use `gop` anymore.
1409 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty));
1409 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .target = o.target });
14101410 return struct_di_ty;
14111411 }
14121412
......@@ -1461,13 +1461,13 @@ pub const Object = struct {
14611461 );
14621462 dib.replaceTemporary(fwd_decl, full_di_ty);
14631463 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1464 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty));
1464 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .target = o.target });
14651465 return full_di_ty;
14661466 },
14671467 .Union => {
14681468 const owner_decl = ty.getOwnerDecl();
14691469
1470 const name = try ty.nameAlloc(gpa);
1470 const name = try ty.nameAlloc(gpa, target);
14711471 defer gpa.free(name);
14721472
14731473 const fwd_decl = opt_fwd_decl orelse blk: {
......@@ -1489,7 +1489,7 @@ pub const Object = struct {
14891489 dib.replaceTemporary(fwd_decl, union_di_ty);
14901490 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
14911491 // means we can't use `gop` anymore.
1492 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty));
1492 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .target = o.target });
14931493 return union_di_ty;
14941494 }
14951495
......@@ -1603,7 +1603,7 @@ pub const Object = struct {
16031603 0,
16041604 );
16051605 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1606 try o.di_type_map.put(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty));
1606 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .target = o.target });
16071607 return fn_di_ty;
16081608 },
16091609 .ComptimeInt => unreachable,
......@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {
16761676 const decl = dg.decl;
16771677 assert(decl.has_tv);
16781678
1679 log.debug("gen: {s} type: {}, value: {}", .{ decl.name, decl.ty, decl.val.fmtDebug() });
1679 log.debug("gen: {s} type: {}, value: {}", .{
1680 decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
1681 });
16801682
16811683 if (decl.val.castTag(.function)) |func_payload| {
16821684 _ = func_payload;
......@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {
19901992 },
19911993 .Opaque => switch (t.tag()) {
19921994 .@"opaque" => {
1993 const gop = try dg.object.type_map.getOrPut(gpa, t);
1995 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
19941996 if (gop.found_existing) return gop.value_ptr.*;
19951997
19961998 // The Type memory is ephemeral; since we want to store a longer-lived
......@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {
20512053 return dg.context.intType(16);
20522054 },
20532055 .Struct => {
2054 const gop = try dg.object.type_map.getOrPut(gpa, t);
2056 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
20552057 if (gop.found_existing) return gop.value_ptr.*;
20562058
20572059 // The Type memory is ephemeral; since we want to store a longer-lived
......@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {
21742176 return llvm_struct_ty;
21752177 },
21762178 .Union => {
2177 const gop = try dg.object.type_map.getOrPut(gpa, t);
2179 const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .target = target });
21782180 if (gop.found_existing) return gop.value_ptr.*;
21792181
21802182 // The Type memory is ephemeral; since we want to store a longer-lived
......@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {
22892291 const llvm_type = try dg.llvmType(tv.ty);
22902292 return llvm_type.getUndef();
22912293 }
2294 const target = dg.module.getTarget();
22922295
22932296 switch (tv.ty.zigTypeTag()) {
22942297 .Bool => {
......@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {
23022305 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
23032306 else => {
23042307 var bigint_space: Value.BigIntSpace = undefined;
2305 const bigint = tv.val.toBigInt(&bigint_space);
2306 const target = dg.module.getTarget();
2308 const bigint = tv.val.toBigInt(&bigint_space, target);
23072309 const int_info = tv.ty.intInfo(target);
23082310 assert(int_info.bits != 0);
23092311 const llvm_type = dg.context.intType(int_info.bits);
......@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {
23312333 const int_val = tv.enumToInt(&int_buffer);
23322334
23332335 var bigint_space: Value.BigIntSpace = undefined;
2334 const bigint = int_val.toBigInt(&bigint_space);
2336 const bigint = int_val.toBigInt(&bigint_space, target);
23352337
2336 const target = dg.module.getTarget();
23372338 const int_info = tv.ty.intInfo(target);
23382339 const llvm_type = dg.context.intType(int_info.bits);
23392340
......@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {
23562357 },
23572358 .Float => {
23582359 const llvm_ty = try dg.llvmType(tv.ty);
2359 const target = dg.module.getTarget();
23602360 switch (tv.ty.floatBits(target)) {
23612361 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),
23622362 80 => {
......@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {
24142414 },
24152415 .int_u64, .one, .int_big_positive => {
24162416 const llvm_usize = try dg.llvmType(Type.usize);
2417 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(), .False);
2417 const llvm_int = llvm_usize.constInt(tv.val.toUnsignedInt(target), .False);
24182418 return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));
24192419 },
24202420 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
......@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {
24242424 const llvm_type = try dg.llvmType(tv.ty);
24252425 return llvm_type.constNull();
24262426 },
2427 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ tv.ty, tag }),
2427 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
2428 tv.ty.fmtDebug(), tag,
2429 }),
24282430 },
24292431 .Array => switch (tv.val.tag()) {
24302432 .bytes => {
......@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {
25922594 const llvm_struct_ty = try dg.llvmType(tv.ty);
25932595 const field_vals = tv.val.castTag(.aggregate).?.data;
25942596 const gpa = dg.gpa;
2595 const target = dg.module.getTarget();
25962597
25972598 if (tv.ty.isTupleOrAnonStruct()) {
25982599 const tuple = tv.ty.tupleFields();
......@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {
27532754 const llvm_union_ty = try dg.llvmType(tv.ty);
27542755 const tag_and_val = tv.val.castTag(.@"union").?.data;
27552756
2756 const target = dg.module.getTarget();
27572757 const layout = tv.ty.unionGetLayout(target);
27582758
27592759 if (layout.payload_size == 0) {
......@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {
27632763 });
27642764 }
27652765 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
2766 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag).?;
2766 const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, target).?;
27672767 assert(union_obj.haveFieldTypes());
27682768 const field_ty = union_obj.fields.values()[field_index].ty;
27692769 const payload = p: {
......@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {
28922892
28932893 .Frame,
28942894 .AnyFrame,
2895 => return dg.todo("implement const of type '{}'", .{tv.ty}),
2895 => return dg.todo("implement const of type '{}'", .{tv.ty.fmtDebug()}),
28962896 }
28972897 }
28982898
......@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {
29102910 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
29112911 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);
29122912
2913 if (ptr_child_ty.eql(decl.ty)) {
2913 const target = dg.module.getTarget();
2914 if (ptr_child_ty.eql(decl.ty, target)) {
29142915 return llvm_ptr;
29152916 } else {
29162917 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));
......@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {
29182919 }
29192920
29202921 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {
2922 const target = dg.module.getTarget();
29212923 var bitcast_needed: bool = undefined;
29222924 const llvm_ptr = switch (ptr_val.tag()) {
29232925 .decl_ref_mut => {
......@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {
29512953
29522954 const field_index = @intCast(u32, field_ptr.field_index);
29532955 const llvm_u32 = dg.context.intType(32);
2954 const target = dg.module.getTarget();
29552956 switch (parent_ty.zigTypeTag()) {
29562957 .Union => {
29572958 bitcast_needed = true;
......@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {
29742975 },
29752976 .Struct => {
29762977 const field_ty = parent_ty.structFieldType(field_index);
2977 bitcast_needed = !field_ty.eql(ptr_child_ty);
2978 bitcast_needed = !field_ty.eql(ptr_child_ty, target);
29782979
29792980 var ty_buf: Type.Payload.Pointer = undefined;
29802981 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;
......@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {
29902991 .elem_ptr => blk: {
29912992 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
29922993 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);
2993 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty);
2994 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, target);
29942995
29952996 const llvm_usize = try dg.llvmType(Type.usize);
29962997 const indices: [1]*const llvm.Value = .{
......@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {
30043005 var buf: Type.Payload.ElemType = undefined;
30053006
30063007 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
3007 bitcast_needed = !payload_ty.eql(ptr_child_ty);
3008 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
30083009
30093010 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {
30103011 // In this case, we represent pointer to optional the same as pointer
......@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {
30243025 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
30253026
30263027 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
3027 bitcast_needed = !payload_ty.eql(ptr_child_ty);
3028 bitcast_needed = !payload_ty.eql(ptr_child_ty, target);
30283029
30293030 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
30303031 // In this case, we represent pointer to error union the same as pointer
......@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {
30533054 tv: TypedValue,
30543055 decl: *Module.Decl,
30553056 ) Error!*const llvm.Value {
3057 const target = self.module.getTarget();
30563058 if (tv.ty.isSlice()) {
30573059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
30583060 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
30593061 var slice_len: Value.Payload.U64 = .{
30603062 .base = .{ .tag = .int_u64 },
3061 .data = tv.val.sliceLen(),
3063 .data = tv.val.sliceLen(target),
30623064 };
30633065 const fields: [2]*const llvm.Value = .{
30643066 try self.genTypedValue(.{
src/codegen/spirv.zig+10-8
......@@ -313,7 +313,7 @@ pub const DeclGen = struct {
313313 // As of yet, there is no vector support in the self-hosted compiler.
314314 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
315315 // TODO: For which types is this the case?
316 else => self.todo("implement arithmeticTypeInfo for {}", .{ty}),
316 else => self.todo("implement arithmeticTypeInfo for {}", .{ty.fmtDebug()}),
317317 };
318318 }
319319
......@@ -335,7 +335,7 @@ pub const DeclGen = struct {
335335 const int_info = ty.intInfo(target);
336336 const backing_bits = self.backingIntBits(int_info.bits) orelse {
337337 // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.
338 return self.todo("implement composite int constants for {}", .{ty});
338 return self.todo("implement composite int constants for {}", .{ty.fmtDebug()});
339339 };
340340
341341 // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any
......@@ -345,7 +345,7 @@ pub const DeclGen = struct {
345345
346346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.
347347 // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal
348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt();
348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(target);
349349
350350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {
351351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },
......@@ -388,7 +388,7 @@ pub const DeclGen = struct {
388388 });
389389 },
390390 .Void => unreachable,
391 else => return self.todo("constant generation of type {}", .{ty}),
391 else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}),
392392 }
393393
394394 return result_id.toRef();
......@@ -414,7 +414,7 @@ pub const DeclGen = struct {
414414 const backing_bits = self.backingIntBits(int_info.bits) orelse {
415415 // TODO: Integers too big for any native type are represented as "composite integers":
416416 // An array of largestSupportedIntBits.
417 return self.todo("Implement composite int type {}", .{ty});
417 return self.todo("Implement composite int type {}", .{ty.fmtDebug()});
418418 };
419419
420420 const payload = try self.spv.arena.create(SpvType.Payload.Int);
......@@ -644,8 +644,10 @@ pub const DeclGen = struct {
644644 const result_id = self.spv.allocId();
645645 const result_type_id = try self.resolveTypeId(ty);
646646
647 assert(self.air.typeOf(bin_op.lhs).eql(ty));
648 assert(self.air.typeOf(bin_op.rhs).eql(ty));
647 const target = self.getTarget();
648
649 assert(self.air.typeOf(bin_op.lhs).eql(ty, target));
650 assert(self.air.typeOf(bin_op.rhs).eql(ty, target));
649651
650652 // Binary operations are generally applicable to both scalar and vector operations
651653 // in SPIR-V, but int and float versions of operations require different opcodes.
......@@ -692,7 +694,7 @@ pub const DeclGen = struct {
692694 const result_id = self.spv.allocId();
693695 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
694696 const op_ty = self.air.typeOf(bin_op.lhs);
695 assert(op_ty.eql(self.air.typeOf(bin_op.rhs)));
697 assert(op_ty.eql(self.air.typeOf(bin_op.rhs), self.getTarget()));
696698
697699 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,
698700 // but int and float versions of operations require different opcodes.
src/link.zig+2-2
......@@ -457,7 +457,7 @@ pub const File = struct {
457457 /// May be called before or after updateDeclExports but must be called
458458 /// after allocateDeclIndexes for any given Decl.
459459 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {
460 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty });
460 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmtDebug() });
461461 assert(decl.has_tv);
462462 switch (base.tag) {
463463 // zig fmt: off
......@@ -477,7 +477,7 @@ pub const File = struct {
477477 /// after allocateDeclIndexes for any given Decl.
478478 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {
479479 log.debug("updateFunc {*} ({s}), type={}", .{
480 func.owner_decl, func.owner_decl.name, func.owner_decl.ty,
480 func.owner_decl, func.owner_decl.name, func.owner_decl.ty.fmtDebug(),
481481 });
482482 switch (base.tag) {
483483 // zig fmt: off
src/link/C.zig+5-3
......@@ -127,7 +127,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
127127 .error_msg = null,
128128 .decl = decl,
129129 .fwd_decl = fwd_decl.toManaged(module.gpa),
130 .typedefs = typedefs.promote(module.gpa),
130 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
131131 .typedefs_arena = self.arena.allocator(),
132132 },
133133 .code = code.toManaged(module.gpa),
......@@ -192,7 +192,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
192192 .error_msg = null,
193193 .decl = decl,
194194 .fwd_decl = fwd_decl.toManaged(module.gpa),
195 .typedefs = typedefs.promote(module.gpa),
195 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
196196 .typedefs_arena = self.arena.allocator(),
197197 },
198198 .code = code.toManaged(module.gpa),
......@@ -366,7 +366,9 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void
366366 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));
367367 var it = decl_block.typedefs.iterator();
368368 while (it.next()) |new| {
369 const gop = f.typedefs.getOrPutAssumeCapacity(new.key_ptr.*);
369 const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{
370 .target = self.base.options.target,
371 });
370372 if (!gop.found_existing) {
371373 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
372374 }
src/link/Dwarf.zig+15-9
......@@ -200,7 +200,9 @@ pub fn initDeclDebugInfo(self: *Dwarf, decl: *Module.Decl) !DeclDebugBuffers {
200200 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
201201 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
202202 if (fn_ret_has_bits) {
203 const gop = try dbg_info_type_relocs.getOrPut(gpa, fn_ret_type);
203 const gop = try dbg_info_type_relocs.getOrPutContext(gpa, fn_ret_type, .{
204 .target = self.target,
205 });
204206 if (!gop.found_existing) {
205207 gop.value_ptr.* = .{
206208 .off = undefined,
......@@ -455,7 +457,9 @@ pub fn commitDeclDebugInfo(
455457 var it: usize = 0;
456458 while (it < dbg_info_type_relocs.count()) : (it += 1) {
457459 const ty = dbg_info_type_relocs.keys()[it];
458 const value_ptr = dbg_info_type_relocs.getPtr(ty).?;
460 const value_ptr = dbg_info_type_relocs.getPtrContext(ty, .{
461 .target = self.target,
462 }).?;
459463 value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);
460464 try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs);
461465 }
......@@ -774,7 +778,7 @@ fn addDbgInfoType(
774778 // DW.AT.byte_size, DW.FORM.data1
775779 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
776780 // DW.AT.name, DW.FORM.string
777 try dbg_info_buffer.writer().print("{}\x00", .{ty});
781 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
778782 },
779783 .Optional => {
780784 if (ty.isPtrLikeOptional()) {
......@@ -785,7 +789,7 @@ fn addDbgInfoType(
785789 // DW.AT.byte_size, DW.FORM.data1
786790 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
787791 // DW.AT.name, DW.FORM.string
788 try dbg_info_buffer.writer().print("{}\x00", .{ty});
792 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
789793 } else {
790794 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
791795 var buf = try arena.create(Type.Payload.ElemType);
......@@ -796,7 +800,7 @@ fn addDbgInfoType(
796800 const abi_size = ty.abiSize(target);
797801 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
798802 // DW.AT.name, DW.FORM.string
799 try dbg_info_buffer.writer().print("{}\x00", .{ty});
803 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
800804 // DW.AT.member
801805 try dbg_info_buffer.ensureUnusedCapacity(7);
802806 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
......@@ -835,7 +839,7 @@ fn addDbgInfoType(
835839 // DW.AT.byte_size, DW.FORM.sdata
836840 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
837841 // DW.AT.name, DW.FORM.string
838 try dbg_info_buffer.writer().print("{}\x00", .{ty});
842 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
839843 // DW.AT.member
840844 try dbg_info_buffer.ensureUnusedCapacity(5);
841845 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
......@@ -882,7 +886,7 @@ fn addDbgInfoType(
882886 const abi_size = ty.abiSize(target);
883887 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
884888 // DW.AT.name, DW.FORM.string
885 const struct_name = try ty.nameAllocArena(arena);
889 const struct_name = try ty.nameAllocArena(arena, target);
886890 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
887891 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
888892 dbg_info_buffer.appendAssumeCapacity(0);
......@@ -915,13 +919,15 @@ fn addDbgInfoType(
915919 try dbg_info_buffer.append(0);
916920 },
917921 else => {
918 log.debug("TODO implement .debug_info for type '{}'", .{ty});
922 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
919923 try dbg_info_buffer.append(abbrev_pad1);
920924 },
921925 }
922926
923927 for (relocs.items) |rel| {
924 const gop = try dbg_info_type_relocs.getOrPut(self.allocator, rel.ty);
928 const gop = try dbg_info_type_relocs.getOrPutContext(self.allocator, rel.ty, .{
929 .target = self.target,
930 });
925931 if (!gop.found_existing) {
926932 gop.value_ptr.* = .{
927933 .off = undefined,
src/link/MachO.zig+10-9
......@@ -3874,7 +3874,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38743874
38753875/// Checks if the value, or any of its embedded values stores a pointer, and thus requires
38763876/// a rebase opcode for the dynamic linker.
3877fn needsPointerRebase(ty: Type, val: Value) bool {
3877fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
38783878 if (ty.zigTypeTag() == .Fn) {
38793879 return false;
38803880 }
......@@ -3890,7 +3890,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
38903890 const elem_ty = ty.childType();
38913891 var elem_value_buf: Value.ElemValueBuffer = undefined;
38923892 const elem_val = val.elemValueBuffer(0, &elem_value_buf);
3893 return needsPointerRebase(elem_ty, elem_val);
3893 return needsPointerRebase(elem_ty, elem_val, target);
38943894 },
38953895 .Struct => {
38963896 const fields = ty.structFields().values();
......@@ -3898,7 +3898,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
38983898 if (val.castTag(.aggregate)) |payload| {
38993899 const field_values = payload.data;
39003900 for (field_values) |field_val, i| {
3901 if (needsPointerRebase(fields[i].ty, field_val)) return true;
3901 if (needsPointerRebase(fields[i].ty, field_val, target)) return true;
39023902 } else return false;
39033903 } else return false;
39043904 },
......@@ -3907,18 +3907,18 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
39073907 const sub_val = payload.data;
39083908 var buffer: Type.Payload.ElemType = undefined;
39093909 const sub_ty = ty.optionalChild(&buffer);
3910 return needsPointerRebase(sub_ty, sub_val);
3910 return needsPointerRebase(sub_ty, sub_val, target);
39113911 } else return false;
39123912 },
39133913 .Union => {
39143914 const union_obj = val.cast(Value.Payload.Union).?.data;
3915 const active_field_ty = ty.unionFieldType(union_obj.tag);
3916 return needsPointerRebase(active_field_ty, union_obj.val);
3915 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
3916 return needsPointerRebase(active_field_ty, union_obj.val, target);
39173917 },
39183918 .ErrorUnion => {
39193919 if (val.castTag(.eu_payload)) |payload| {
39203920 const payload_ty = ty.errorUnionPayload();
3921 return needsPointerRebase(payload_ty, payload.data);
3921 return needsPointerRebase(payload_ty, payload.data, target);
39223922 } else return false;
39233923 },
39243924 else => return false,
......@@ -3927,7 +3927,8 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
39273927
39283928fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {
39293929 const code = atom.code.items;
3930 const alignment = ty.abiAlignment(self.base.options.target);
3930 const target = self.base.options.target;
3931 const alignment = ty.abiAlignment(target);
39313932 const align_log_2 = math.log2(alignment);
39323933 const zig_ty = ty.zigTypeTag();
39333934 const mode = self.base.options.optimize_mode;
......@@ -3954,7 +3955,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,
39543955 };
39553956 }
39563957
3957 if (needsPointerRebase(ty, val)) {
3958 if (needsPointerRebase(ty, val, target)) {
39583959 break :blk (try self.getMatchingSection(.{
39593960 .segname = makeStaticString("__DATA_CONST"),
39603961 .sectname = makeStaticString("__const"),
src/print_air.zig+6-6
......@@ -299,12 +299,12 @@ const Writer = struct {
299299
300300 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
301301 const ty = w.air.instructions.items(.data)[inst].ty;
302 try s.print("{}", .{ty});
302 try s.print("{}", .{ty.fmtDebug()});
303303 }
304304
305305 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
306306 const ty_op = w.air.instructions.items(.data)[inst].ty_op;
307 try s.print("{}, ", .{w.air.getRefType(ty_op.ty)});
307 try s.print("{}, ", .{w.air.getRefType(ty_op.ty).fmtDebug()});
308308 try w.writeOperand(s, inst, 0, ty_op.operand);
309309 }
310310
......@@ -313,7 +313,7 @@ const Writer = struct {
313313 const extra = w.air.extraData(Air.Block, ty_pl.payload);
314314 const body = w.air.extra[extra.end..][0..extra.data.body_len];
315315
316 try s.print("{}, {{\n", .{w.air.getRefType(ty_pl.ty)});
316 try s.print("{}, {{\n", .{w.air.getRefType(ty_pl.ty).fmtDebug()});
317317 const old_indent = w.indent;
318318 w.indent += 2;
319319 try w.writeBody(s, body);
......@@ -328,7 +328,7 @@ const Writer = struct {
328328 const len = @intCast(usize, vector_ty.arrayLen());
329329 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);
330330
331 try s.print("{}, [", .{vector_ty});
331 try s.print("{}, [", .{vector_ty.fmtDebug()});
332332 for (elements) |elem, i| {
333333 if (i != 0) try s.writeAll(", ");
334334 try w.writeOperand(s, inst, i, elem);
......@@ -502,7 +502,7 @@ const Writer = struct {
502502 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
503503 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
504504 const val = w.air.values[ty_pl.payload];
505 try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty), val.fmtDebug() });
505 try s.print("{}, {}", .{ w.air.getRefType(ty_pl.ty).fmtDebug(), val.fmtDebug() });
506506 }
507507
508508 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
......@@ -514,7 +514,7 @@ const Writer = struct {
514514 var op_index: usize = 0;
515515
516516 const ret_ty = w.air.typeOfIndex(inst);
517 try s.print("{}", .{ret_ty});
517 try s.print("{}", .{ret_ty.fmtDebug()});
518518
519519 if (is_volatile) {
520520 try s.writeAll(", volatile");
src/type.zig+544-269
......@@ -6,6 +6,7 @@ const Target = std.Target;
66const Module = @import("Module.zig");
77const log = std.log.scoped(.Type);
88const target_util = @import("target.zig");
9const TypedValue = @import("TypedValue.zig");
910
1011const file_struct = @This();
1112
......@@ -520,7 +521,7 @@ pub const Type = extern union {
520521 }
521522 }
522523
523 pub fn eql(a: Type, b: Type) bool {
524 pub fn eql(a: Type, b: Type, target: Target) bool {
524525 // As a shortcut, if the small tags / addresses match, we're done.
525526 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;
526527
......@@ -636,7 +637,7 @@ pub const Type = extern union {
636637 const a_info = a.fnInfo();
637638 const b_info = b.fnInfo();
638639
639 if (!eql(a_info.return_type, b_info.return_type))
640 if (!eql(a_info.return_type, b_info.return_type, target))
640641 return false;
641642
642643 if (a_info.cc != b_info.cc)
......@@ -662,7 +663,7 @@ pub const Type = extern union {
662663 if (a_param_ty.tag() == .generic_poison) continue;
663664 if (b_param_ty.tag() == .generic_poison) continue;
664665
665 if (!eql(a_param_ty, b_param_ty))
666 if (!eql(a_param_ty, b_param_ty, target))
666667 return false;
667668 }
668669
......@@ -680,13 +681,13 @@ pub const Type = extern union {
680681 if (a.arrayLen() != b.arrayLen())
681682 return false;
682683 const elem_ty = a.elemType();
683 if (!elem_ty.eql(b.elemType()))
684 if (!elem_ty.eql(b.elemType(), target))
684685 return false;
685686 const sentinel_a = a.sentinel();
686687 const sentinel_b = b.sentinel();
687688 if (sentinel_a) |sa| {
688689 if (sentinel_b) |sb| {
689 return sa.eql(sb, elem_ty);
690 return sa.eql(sb, elem_ty, target);
690691 } else {
691692 return false;
692693 }
......@@ -717,7 +718,7 @@ pub const Type = extern union {
717718
718719 const info_a = a.ptrInfo().data;
719720 const info_b = b.ptrInfo().data;
720 if (!info_a.pointee_type.eql(info_b.pointee_type))
721 if (!info_a.pointee_type.eql(info_b.pointee_type, target))
721722 return false;
722723 if (info_a.@"align" != info_b.@"align")
723724 return false;
......@@ -740,7 +741,7 @@ pub const Type = extern union {
740741 const sentinel_b = info_b.sentinel;
741742 if (sentinel_a) |sa| {
742743 if (sentinel_b) |sb| {
743 if (!sa.eql(sb, info_a.pointee_type))
744 if (!sa.eql(sb, info_a.pointee_type, target))
744745 return false;
745746 } else {
746747 return false;
......@@ -761,7 +762,7 @@ pub const Type = extern union {
761762
762763 var buf_a: Payload.ElemType = undefined;
763764 var buf_b: Payload.ElemType = undefined;
764 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b));
765 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b), target);
765766 },
766767
767768 .anyerror_void_error_union, .error_union => {
......@@ -769,18 +770,18 @@ pub const Type = extern union {
769770
770771 const a_set = a.errorUnionSet();
771772 const b_set = b.errorUnionSet();
772 if (!a_set.eql(b_set)) return false;
773 if (!a_set.eql(b_set, target)) return false;
773774
774775 const a_payload = a.errorUnionPayload();
775776 const b_payload = b.errorUnionPayload();
776 if (!a_payload.eql(b_payload)) return false;
777 if (!a_payload.eql(b_payload, target)) return false;
777778
778779 return true;
779780 },
780781
781782 .anyframe_T => {
782783 if (b.zigTypeTag() != .AnyFrame) return false;
783 return a.childType().eql(b.childType());
784 return a.childType().eql(b.childType(), target);
784785 },
785786
786787 .empty_struct => {
......@@ -803,7 +804,7 @@ pub const Type = extern union {
803804
804805 for (a_tuple.types) |a_ty, i| {
805806 const b_ty = b_tuple.types[i];
806 if (!eql(a_ty, b_ty)) return false;
807 if (!eql(a_ty, b_ty, target)) return false;
807808 }
808809
809810 for (a_tuple.values) |a_val, i| {
......@@ -819,7 +820,7 @@ pub const Type = extern union {
819820 if (b_val.tag() == .unreachable_value) {
820821 return false;
821822 } else {
822 if (!Value.eql(a_val, b_val, ty)) return false;
823 if (!Value.eql(a_val, b_val, ty, target)) return false;
823824 }
824825 }
825826 }
......@@ -839,7 +840,7 @@ pub const Type = extern union {
839840
840841 for (a_struct_obj.types) |a_ty, i| {
841842 const b_ty = b_struct_obj.types[i];
842 if (!eql(a_ty, b_ty)) return false;
843 if (!eql(a_ty, b_ty, target)) return false;
843844 }
844845
845846 for (a_struct_obj.values) |a_val, i| {
......@@ -855,7 +856,7 @@ pub const Type = extern union {
855856 if (b_val.tag() == .unreachable_value) {
856857 return false;
857858 } else {
858 if (!Value.eql(a_val, b_val, ty)) return false;
859 if (!Value.eql(a_val, b_val, ty, target)) return false;
859860 }
860861 }
861862 }
......@@ -910,13 +911,13 @@ pub const Type = extern union {
910911 }
911912 }
912913
913 pub fn hash(self: Type) u64 {
914 pub fn hash(self: Type, target: Target) u64 {
914915 var hasher = std.hash.Wyhash.init(0);
915 self.hashWithHasher(&hasher);
916 self.hashWithHasher(&hasher, target);
916917 return hasher.final();
917918 }
918919
919 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash) void {
920 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
920921 switch (ty.tag()) {
921922 .generic_poison => unreachable,
922923
......@@ -1035,7 +1036,7 @@ pub const Type = extern union {
10351036 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10361037
10371038 const fn_info = ty.fnInfo();
1038 hashWithHasher(fn_info.return_type, hasher);
1039 hashWithHasher(fn_info.return_type, hasher, target);
10391040 std.hash.autoHash(hasher, fn_info.alignment);
10401041 std.hash.autoHash(hasher, fn_info.cc);
10411042 std.hash.autoHash(hasher, fn_info.is_var_args);
......@@ -1045,7 +1046,7 @@ pub const Type = extern union {
10451046 for (fn_info.param_types) |param_ty, i| {
10461047 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));
10471048 if (param_ty.tag() == .generic_poison) continue;
1048 hashWithHasher(param_ty, hasher);
1049 hashWithHasher(param_ty, hasher, target);
10491050 }
10501051 },
10511052
......@@ -1058,8 +1059,8 @@ pub const Type = extern union {
10581059
10591060 const elem_ty = ty.elemType();
10601061 std.hash.autoHash(hasher, ty.arrayLen());
1061 hashWithHasher(elem_ty, hasher);
1062 hashSentinel(ty.sentinel(), elem_ty, hasher);
1062 hashWithHasher(elem_ty, hasher, target);
1063 hashSentinel(ty.sentinel(), elem_ty, hasher, target);
10631064 },
10641065
10651066 .vector => {
......@@ -1067,7 +1068,7 @@ pub const Type = extern union {
10671068
10681069 const elem_ty = ty.elemType();
10691070 std.hash.autoHash(hasher, ty.vectorLen());
1070 hashWithHasher(elem_ty, hasher);
1071 hashWithHasher(elem_ty, hasher, target);
10711072 },
10721073
10731074 .single_const_pointer_to_comptime_int,
......@@ -1091,8 +1092,8 @@ pub const Type = extern union {
10911092 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);
10921093
10931094 const info = ty.ptrInfo().data;
1094 hashWithHasher(info.pointee_type, hasher);
1095 hashSentinel(info.sentinel, info.pointee_type, hasher);
1095 hashWithHasher(info.pointee_type, hasher, target);
1096 hashSentinel(info.sentinel, info.pointee_type, hasher, target);
10961097 std.hash.autoHash(hasher, info.@"align");
10971098 std.hash.autoHash(hasher, info.@"addrspace");
10981099 std.hash.autoHash(hasher, info.bit_offset);
......@@ -1110,22 +1111,22 @@ pub const Type = extern union {
11101111 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
11111112
11121113 var buf: Payload.ElemType = undefined;
1113 hashWithHasher(ty.optionalChild(&buf), hasher);
1114 hashWithHasher(ty.optionalChild(&buf), hasher, target);
11141115 },
11151116
11161117 .anyerror_void_error_union, .error_union => {
11171118 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
11181119
11191120 const set_ty = ty.errorUnionSet();
1120 hashWithHasher(set_ty, hasher);
1121 hashWithHasher(set_ty, hasher, target);
11211122
11221123 const payload_ty = ty.errorUnionPayload();
1123 hashWithHasher(payload_ty, hasher);
1124 hashWithHasher(payload_ty, hasher, target);
11241125 },
11251126
11261127 .anyframe_T => {
11271128 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);
1128 hashWithHasher(ty.childType(), hasher);
1129 hashWithHasher(ty.childType(), hasher, target);
11291130 },
11301131
11311132 .empty_struct => {
......@@ -1144,10 +1145,10 @@ pub const Type = extern union {
11441145 std.hash.autoHash(hasher, tuple.types.len);
11451146
11461147 for (tuple.types) |field_ty, i| {
1147 hashWithHasher(field_ty, hasher);
1148 hashWithHasher(field_ty, hasher, target);
11481149 const field_val = tuple.values[i];
11491150 if (field_val.tag() == .unreachable_value) continue;
1150 field_val.hash(field_ty, hasher);
1151 field_val.hash(field_ty, hasher, target);
11511152 }
11521153 },
11531154 .anon_struct => {
......@@ -1159,9 +1160,9 @@ pub const Type = extern union {
11591160 const field_name = struct_obj.names[i];
11601161 const field_val = struct_obj.values[i];
11611162 hasher.update(field_name);
1162 hashWithHasher(field_ty, hasher);
1163 hashWithHasher(field_ty, hasher, target);
11631164 if (field_val.tag() == .unreachable_value) continue;
1164 field_val.hash(field_ty, hasher);
1165 field_val.hash(field_ty, hasher, target);
11651166 }
11661167 },
11671168
......@@ -1209,35 +1210,35 @@ pub const Type = extern union {
12091210 }
12101211 }
12111212
1212 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash) void {
1213 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
12131214 if (opt_val) |s| {
12141215 std.hash.autoHash(hasher, true);
1215 s.hash(ty, hasher);
1216 s.hash(ty, hasher, target);
12161217 } else {
12171218 std.hash.autoHash(hasher, false);
12181219 }
12191220 }
12201221
12211222 pub const HashContext64 = struct {
1223 target: Target,
1224
12221225 pub fn hash(self: @This(), t: Type) u64 {
1223 _ = self;
1224 return t.hash();
1226 return t.hash(self.target);
12251227 }
12261228 pub fn eql(self: @This(), a: Type, b: Type) bool {
1227 _ = self;
1228 return a.eql(b);
1229 return a.eql(b, self.target);
12291230 }
12301231 };
12311232
12321233 pub const HashContext32 = struct {
1234 target: Target,
1235
12331236 pub fn hash(self: @This(), t: Type) u32 {
1234 _ = self;
1235 return @truncate(u32, t.hash());
1237 return @truncate(u32, t.hash(self.target));
12361238 }
12371239 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {
1238 _ = self;
12391240 _ = b_index;
1240 return a.eql(b);
1241 return a.eql(b, self.target);
12411242 }
12421243 };
12431244
......@@ -1404,8 +1405,8 @@ pub const Type = extern union {
14041405 .function => {
14051406 const payload = self.castTag(.function).?.data;
14061407 const param_types = try allocator.alloc(Type, payload.param_types.len);
1407 for (payload.param_types) |param_type, i| {
1408 param_types[i] = try param_type.copy(allocator);
1408 for (payload.param_types) |param_ty, i| {
1409 param_types[i] = try param_ty.copy(allocator);
14091410 }
14101411 const other_comptime_params = payload.comptime_params[0..payload.param_types.len];
14111412 const comptime_params = try allocator.dupe(bool, other_comptime_params);
......@@ -1474,14 +1475,51 @@ pub const Type = extern union {
14741475 return Type{ .ptr_otherwise = &new_payload.base };
14751476 }
14761477
1477 pub fn format(
1478 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
1479 _ = ty;
1480 _ = unused_fmt_string;
1481 _ = options;
1482 _ = writer;
1483 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
1484 }
1485
1486 pub fn fmt(ty: Type, target: Target) std.fmt.Formatter(format2) {
1487 return .{ .data = .{
1488 .ty = ty,
1489 .target = target,
1490 } };
1491 }
1492
1493 const FormatContext = struct {
1494 ty: Type,
1495 target: Target,
1496 };
1497
1498 fn format2(
1499 ctx: FormatContext,
1500 comptime unused_format_string: []const u8,
1501 options: std.fmt.FormatOptions,
1502 writer: anytype,
1503 ) !void {
1504 comptime assert(unused_format_string.len == 0);
1505 _ = options;
1506 return print(ctx.ty, writer, ctx.target);
1507 }
1508
1509 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
1510 return .{ .data = ty };
1511 }
1512
1513 /// This is a debug function. In order to print types in a meaningful way
1514 /// we also need access to the target.
1515 pub fn dump(
14781516 start_type: Type,
1479 comptime fmt: []const u8,
1517 comptime unused_format_string: []const u8,
14801518 options: std.fmt.FormatOptions,
14811519 writer: anytype,
14821520 ) @TypeOf(writer).Error!void {
14831521 _ = options;
1484 comptime assert(fmt.len == 0);
1522 comptime assert(unused_format_string.len == 0);
14851523 var ty = start_type;
14861524 while (true) {
14871525 const t = ty.tag();
......@@ -1584,7 +1622,7 @@ pub const Type = extern union {
15841622 try writer.writeAll("fn(");
15851623 for (payload.param_types) |param_type, i| {
15861624 if (i != 0) try writer.writeAll(", ");
1587 try param_type.format("", .{}, writer);
1625 try param_type.dump("", .{}, writer);
15881626 }
15891627 if (payload.is_var_args) {
15901628 if (payload.param_types.len != 0) {
......@@ -1622,7 +1660,7 @@ pub const Type = extern union {
16221660 .vector => {
16231661 const payload = ty.castTag(.vector).?.data;
16241662 try writer.print("@Vector({d}, ", .{payload.len});
1625 try payload.elem_type.format("", .{}, writer);
1663 try payload.elem_type.dump("", .{}, writer);
16261664 return writer.writeAll(")");
16271665 },
16281666 .array => {
......@@ -1633,7 +1671,10 @@ pub const Type = extern union {
16331671 },
16341672 .array_sentinel => {
16351673 const payload = ty.castTag(.array_sentinel).?.data;
1636 try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel.fmtValue(payload.elem_type) });
1674 try writer.print("[{d}:{}]", .{
1675 payload.len,
1676 payload.sentinel.fmtDebug(),
1677 });
16371678 ty = payload.elem_type;
16381679 continue;
16391680 },
......@@ -1646,9 +1687,9 @@ pub const Type = extern union {
16461687 if (val.tag() != .unreachable_value) {
16471688 try writer.writeAll("comptime ");
16481689 }
1649 try field_ty.format("", .{}, writer);
1690 try field_ty.dump("", .{}, writer);
16501691 if (val.tag() != .unreachable_value) {
1651 try writer.print(" = {}", .{val.fmtValue(field_ty)});
1692 try writer.print(" = {}", .{val.fmtDebug()});
16521693 }
16531694 }
16541695 try writer.writeAll("}");
......@@ -1665,9 +1706,9 @@ pub const Type = extern union {
16651706 }
16661707 try writer.writeAll(anon_struct.names[i]);
16671708 try writer.writeAll(": ");
1668 try field_ty.format("", .{}, writer);
1709 try field_ty.dump("", .{}, writer);
16691710 if (val.tag() != .unreachable_value) {
1670 try writer.print(" = {}", .{val.fmtValue(field_ty)});
1711 try writer.print(" = {}", .{val.fmtDebug()});
16711712 }
16721713 }
16731714 try writer.writeAll("}");
......@@ -1752,8 +1793,8 @@ pub const Type = extern union {
17521793 const payload = ty.castTag(.pointer).?.data;
17531794 if (payload.sentinel) |some| switch (payload.size) {
17541795 .One, .C => unreachable,
1755 .Many => try writer.print("[*:{}]", .{some.fmtValue(payload.pointee_type)}),
1756 .Slice => try writer.print("[:{}]", .{some.fmtValue(payload.pointee_type)}),
1796 .Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
1797 .Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
17571798 } else switch (payload.size) {
17581799 .One => try writer.writeAll("*"),
17591800 .Many => try writer.writeAll("[*]"),
......@@ -1780,7 +1821,7 @@ pub const Type = extern union {
17801821 },
17811822 .error_union => {
17821823 const payload = ty.castTag(.error_union).?.data;
1783 try payload.error_set.format("", .{}, writer);
1824 try payload.error_set.dump("", .{}, writer);
17841825 try writer.writeAll("!");
17851826 ty = payload.payload;
17861827 continue;
......@@ -1821,20 +1862,17 @@ pub const Type = extern union {
18211862 }
18221863 }
18231864
1824 pub fn nameAllocArena(ty: Type, arena: Allocator) Allocator.Error![:0]const u8 {
1825 return nameAllocAdvanced(ty, arena, true);
1826 }
1865 pub const nameAllocArena = nameAlloc;
18271866
1828 pub fn nameAlloc(ty: Type, gpa: Allocator) Allocator.Error![:0]const u8 {
1829 return nameAllocAdvanced(ty, gpa, false);
1867 pub fn nameAlloc(ty: Type, ally: Allocator, target: Target) Allocator.Error![:0]const u8 {
1868 var buffer = std.ArrayList(u8).init(ally);
1869 defer buffer.deinit();
1870 try ty.print(buffer.writer(), target);
1871 return buffer.toOwnedSliceSentinel(0);
18301872 }
18311873
1832 /// Returns a name suitable for `@typeName`.
1833 pub fn nameAllocAdvanced(
1834 ty: Type,
1835 ally: Allocator,
1836 is_arena: bool,
1837 ) Allocator.Error![:0]const u8 {
1874 /// Prints a name suitable for `@typeName`.
1875 pub fn print(ty: Type, writer: anytype, target: Target) @TypeOf(writer).Error!void {
18381876 const t = ty.tag();
18391877 switch (t) {
18401878 .inferred_alloc_const => unreachable,
......@@ -1892,141 +1930,251 @@ pub const Type = extern union {
18921930 .comptime_int,
18931931 .comptime_float,
18941932 .noreturn,
1895 => return maybeDupe(@tagName(t), ally, is_arena),
1933 => try writer.writeAll(@tagName(t)),
18961934
1897 .enum_literal => return maybeDupe("@TypeOf(.enum_literal)", ally, is_arena),
1898 .@"null" => return maybeDupe("@TypeOf(null)", ally, is_arena),
1899 .@"undefined" => return maybeDupe("@TypeOf(undefined)", ally, is_arena),
1900 .empty_struct_literal => return maybeDupe("@TypeOf(.{})", ally, is_arena),
1935 .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"),
1936 .@"null" => try writer.writeAll("@TypeOf(null)"),
1937 .@"undefined" => try writer.writeAll("@TypeOf(undefined)"),
1938 .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"),
19011939
19021940 .empty_struct => {
19031941 const namespace = ty.castTag(.empty_struct).?.data;
1904 var buffer = std.ArrayList(u8).init(ally);
1905 defer buffer.deinit();
1906 try namespace.renderFullyQualifiedName("", buffer.writer());
1907 return buffer.toOwnedSliceSentinel(0);
1942 try namespace.renderFullyQualifiedName("", writer);
19081943 },
19091944
19101945 .@"struct" => {
19111946 const struct_obj = ty.castTag(.@"struct").?.data;
1912 return try struct_obj.owner_decl.getFullyQualifiedName(ally);
1947 try struct_obj.owner_decl.renderFullyQualifiedName(writer);
19131948 },
19141949 .@"union", .union_tagged => {
19151950 const union_obj = ty.cast(Payload.Union).?.data;
1916 return try union_obj.owner_decl.getFullyQualifiedName(ally);
1951 try union_obj.owner_decl.renderFullyQualifiedName(writer);
19171952 },
19181953 .enum_full, .enum_nonexhaustive => {
19191954 const enum_full = ty.cast(Payload.EnumFull).?.data;
1920 return try enum_full.owner_decl.getFullyQualifiedName(ally);
1955 try enum_full.owner_decl.renderFullyQualifiedName(writer);
19211956 },
19221957 .enum_simple => {
19231958 const enum_simple = ty.castTag(.enum_simple).?.data;
1924 return try enum_simple.owner_decl.getFullyQualifiedName(ally);
1959 try enum_simple.owner_decl.renderFullyQualifiedName(writer);
19251960 },
19261961 .enum_numbered => {
19271962 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1928 return try enum_numbered.owner_decl.getFullyQualifiedName(ally);
1963 try enum_numbered.owner_decl.renderFullyQualifiedName(writer);
19291964 },
19301965 .@"opaque" => {
19311966 const opaque_obj = ty.cast(Payload.Opaque).?.data;
1932 return try opaque_obj.owner_decl.getFullyQualifiedName(ally);
1967 try opaque_obj.owner_decl.renderFullyQualifiedName(writer);
19331968 },
19341969
1935 .anyerror_void_error_union => return maybeDupe("anyerror!void", ally, is_arena),
1936 .const_slice_u8 => return maybeDupe("[]const u8", ally, is_arena),
1937 .const_slice_u8_sentinel_0 => return maybeDupe("[:0]const u8", ally, is_arena),
1938 .fn_noreturn_no_args => return maybeDupe("fn() noreturn", ally, is_arena),
1939 .fn_void_no_args => return maybeDupe("fn() void", ally, is_arena),
1940 .fn_naked_noreturn_no_args => return maybeDupe("fn() callconv(.Naked) noreturn", ally, is_arena),
1941 .fn_ccc_void_no_args => return maybeDupe("fn() callconv(.C) void", ally, is_arena),
1942 .single_const_pointer_to_comptime_int => return maybeDupe("*const comptime_int", ally, is_arena),
1943 .manyptr_u8 => return maybeDupe("[*]u8", ally, is_arena),
1944 .manyptr_const_u8 => return maybeDupe("[*]const u8", ally, is_arena),
1945 .manyptr_const_u8_sentinel_0 => return maybeDupe("[*:0]const u8", ally, is_arena),
1970 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
1971 .const_slice_u8 => try writer.writeAll("[]const u8"),
1972 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),
1973 .fn_noreturn_no_args => try writer.writeAll("fn() noreturn"),
1974 .fn_void_no_args => try writer.writeAll("fn() void"),
1975 .fn_naked_noreturn_no_args => try writer.writeAll("fn() callconv(.Naked) noreturn"),
1976 .fn_ccc_void_no_args => try writer.writeAll("fn() callconv(.C) void"),
1977 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
1978 .manyptr_u8 => try writer.writeAll("[*]u8"),
1979 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
1980 .manyptr_const_u8_sentinel_0 => try writer.writeAll("[*:0]const u8"),
19461981
19471982 .error_set_inferred => {
19481983 const func = ty.castTag(.error_set_inferred).?.data.func;
19491984
1950 var buf = std.ArrayList(u8).init(ally);
1951 defer buf.deinit();
1952 try buf.appendSlice("@typeInfo(@typeInfo(@TypeOf(");
1953 try func.owner_decl.renderFullyQualifiedName(buf.writer());
1954 try buf.appendSlice(")).Fn.return_type.?).ErrorUnion.error_set");
1955 return try buf.toOwnedSliceSentinel(0);
1985 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
1986 try func.owner_decl.renderFullyQualifiedName(writer);
1987 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
19561988 },
19571989
19581990 .function => {
19591991 const fn_info = ty.fnInfo();
1960 var buf = std.ArrayList(u8).init(ally);
1961 defer buf.deinit();
1962 try buf.appendSlice("fn(");
1963 for (fn_info.param_types) |param_type, i| {
1964 if (i != 0) try buf.appendSlice(", ");
1965 const param_name = try param_type.nameAllocAdvanced(ally, is_arena);
1966 defer if (!is_arena) ally.free(param_name);
1967 try buf.appendSlice(param_name);
1992 try writer.writeAll("fn(");
1993 for (fn_info.param_types) |param_ty, i| {
1994 if (i != 0) try writer.writeAll(", ");
1995 try print(param_ty, writer, target);
19681996 }
19691997 if (fn_info.is_var_args) {
19701998 if (fn_info.param_types.len != 0) {
1971 try buf.appendSlice(", ");
1999 try writer.writeAll(", ");
19722000 }
1973 try buf.appendSlice("...");
2001 try writer.writeAll("...");
19742002 }
1975 try buf.appendSlice(") ");
2003 try writer.writeAll(") ");
19762004 if (fn_info.cc != .Unspecified) {
1977 try buf.appendSlice("callconv(.");
1978 try buf.appendSlice(@tagName(fn_info.cc));
1979 try buf.appendSlice(") ");
2005 try writer.writeAll("callconv(.");
2006 try writer.writeAll(@tagName(fn_info.cc));
2007 try writer.writeAll(") ");
19802008 }
19812009 if (fn_info.alignment != 0) {
1982 try buf.writer().print("align({d}) ", .{fn_info.alignment});
2010 try writer.print("align({d}) ", .{fn_info.alignment});
19832011 }
1984 {
1985 const ret_ty_name = try fn_info.return_type.nameAllocAdvanced(ally, is_arena);
1986 defer if (!is_arena) ally.free(ret_ty_name);
1987 try buf.appendSlice(ret_ty_name);
1988 }
1989 return try buf.toOwnedSliceSentinel(0);
2012 try print(fn_info.return_type, writer, target);
19902013 },
19912014
19922015 .error_union => {
19932016 const error_union = ty.castTag(.error_union).?.data;
2017 try print(error_union.error_set, writer, target);
2018 try writer.writeAll("!");
2019 try print(error_union.payload, writer, target);
2020 },
19942021
1995 var buf = std.ArrayList(u8).init(ally);
1996 defer buf.deinit();
2022 .array_u8 => {
2023 const len = ty.castTag(.array_u8).?.data;
2024 try writer.print("[{d}]u8", .{len});
2025 },
2026 .array_u8_sentinel_0 => {
2027 const len = ty.castTag(.array_u8_sentinel_0).?.data;
2028 try writer.print("[{d}:0]u8", .{len});
2029 },
2030 .vector => {
2031 const payload = ty.castTag(.vector).?.data;
2032 try writer.print("@Vector({d}, ", .{payload.len});
2033 try print(payload.elem_type, writer, target);
2034 try writer.writeAll(")");
2035 },
2036 .array => {
2037 const payload = ty.castTag(.array).?.data;
2038 try writer.print("[{d}]", .{payload.len});
2039 try print(payload.elem_type, writer, target);
2040 },
2041 .array_sentinel => {
2042 const payload = ty.castTag(.array_sentinel).?.data;
2043 try writer.print("[{d}:{}]", .{
2044 payload.len,
2045 payload.sentinel.fmtValue(payload.elem_type, target),
2046 });
2047 try print(payload.elem_type, writer, target);
2048 },
2049 .tuple => {
2050 const tuple = ty.castTag(.tuple).?.data;
19972051
1998 {
1999 const err_set_ty_name = try error_union.error_set.nameAllocAdvanced(ally, is_arena);
2000 defer if (!is_arena) ally.free(err_set_ty_name);
2001 try buf.appendSlice(err_set_ty_name);
2052 try writer.writeAll("tuple{");
2053 for (tuple.types) |field_ty, i| {
2054 if (i != 0) try writer.writeAll(", ");
2055 const val = tuple.values[i];
2056 if (val.tag() != .unreachable_value) {
2057 try writer.writeAll("comptime ");
2058 }
2059 try print(field_ty, writer, target);
2060 if (val.tag() != .unreachable_value) {
2061 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2062 }
2063 }
2064 try writer.writeAll("}");
2065 },
2066 .anon_struct => {
2067 const anon_struct = ty.castTag(.anon_struct).?.data;
2068
2069 try writer.writeAll("struct{");
2070 for (anon_struct.types) |field_ty, i| {
2071 if (i != 0) try writer.writeAll(", ");
2072 const val = anon_struct.values[i];
2073 if (val.tag() != .unreachable_value) {
2074 try writer.writeAll("comptime ");
2075 }
2076 try writer.writeAll(anon_struct.names[i]);
2077 try writer.writeAll(": ");
2078
2079 try print(field_ty, writer, target);
2080
2081 if (val.tag() != .unreachable_value) {
2082 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2083 }
20022084 }
2085 try writer.writeAll("}");
2086 },
20032087
2004 try buf.appendSlice("!");
2088 .pointer,
2089 .single_const_pointer,
2090 .single_mut_pointer,
2091 .many_const_pointer,
2092 .many_mut_pointer,
2093 .c_const_pointer,
2094 .c_mut_pointer,
2095 .const_slice,
2096 .mut_slice,
2097 => {
2098 const info = ty.ptrInfo().data;
20052099
2006 {
2007 const payload_ty_name = try error_union.payload.nameAllocAdvanced(ally, is_arena);
2008 defer if (!is_arena) ally.free(payload_ty_name);
2009 try buf.appendSlice(payload_ty_name);
2100 if (info.sentinel) |s| switch (info.size) {
2101 .One, .C => unreachable,
2102 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, target)}),
2103 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, target)}),
2104 } else switch (info.size) {
2105 .One => try writer.writeAll("*"),
2106 .Many => try writer.writeAll("[*]"),
2107 .C => try writer.writeAll("[*c]"),
2108 .Slice => try writer.writeAll("[]"),
20102109 }
2110 if (info.@"align" != 0 or info.host_size != 0) {
2111 try writer.print("align({d}", .{info.@"align"});
20112112
2012 return try buf.toOwnedSliceSentinel(0);
2013 },
2113 if (info.bit_offset != 0) {
2114 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
2115 }
2116 try writer.writeAll(") ");
2117 }
2118 if (info.@"addrspace" != .generic) {
2119 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
2120 }
2121 if (!info.mutable) try writer.writeAll("const ");
2122 if (info.@"volatile") try writer.writeAll("volatile ");
2123 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
20142124
2015 else => {
2016 // TODO this is wasteful and also an incorrect implementation of `@typeName`
2017 var buf = std.ArrayList(u8).init(ally);
2018 defer buf.deinit();
2019 try buf.writer().print("{}", .{ty});
2020 return try buf.toOwnedSliceSentinel(0);
2125 try print(info.pointee_type, writer, target);
20212126 },
2022 }
2023 }
20242127
2025 fn maybeDupe(s: [:0]const u8, ally: Allocator, is_arena: bool) Allocator.Error![:0]const u8 {
2026 if (is_arena) {
2027 return s;
2028 } else {
2029 return try ally.dupeZ(u8, s);
2128 .int_signed => {
2129 const bits = ty.castTag(.int_signed).?.data;
2130 return writer.print("i{d}", .{bits});
2131 },
2132 .int_unsigned => {
2133 const bits = ty.castTag(.int_unsigned).?.data;
2134 return writer.print("u{d}", .{bits});
2135 },
2136 .optional => {
2137 const child_type = ty.castTag(.optional).?.data;
2138 try writer.writeByte('?');
2139 try print(child_type, writer, target);
2140 },
2141 .optional_single_mut_pointer => {
2142 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
2143 try writer.writeAll("?*");
2144 try print(pointee_type, writer, target);
2145 },
2146 .optional_single_const_pointer => {
2147 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
2148 try writer.writeAll("?*const ");
2149 try print(pointee_type, writer, target);
2150 },
2151 .anyframe_T => {
2152 const return_type = ty.castTag(.anyframe_T).?.data;
2153 try writer.print("anyframe->", .{});
2154 try print(return_type, writer, target);
2155 },
2156 .error_set => {
2157 const names = ty.castTag(.error_set).?.data.names.keys();
2158 try writer.writeAll("error{");
2159 for (names) |name, i| {
2160 if (i != 0) try writer.writeByte(',');
2161 try writer.writeAll(name);
2162 }
2163 try writer.writeAll("}");
2164 },
2165 .error_set_single => {
2166 const name = ty.castTag(.error_set_single).?.data;
2167 return writer.print("error{{{s}}}", .{name});
2168 },
2169 .error_set_merged => {
2170 const names = ty.castTag(.error_set_merged).?.data.keys();
2171 try writer.writeAll("error{");
2172 for (names) |name, i| {
2173 if (i != 0) try writer.writeByte(',');
2174 try writer.writeAll(name);
2175 }
2176 try writer.writeAll("}");
2177 },
20302178 }
20312179 }
20322180
......@@ -2102,8 +2250,12 @@ pub const Type = extern union {
21022250 /// * the type has only one possible value, making its ABI size 0.
21032251 /// When `ignore_comptime_only` is true, then types that are comptime only
21042252 /// may return false positives.
2105 pub fn hasRuntimeBitsAdvanced(ty: Type, ignore_comptime_only: bool) bool {
2106 return switch (ty.tag()) {
2253 pub fn hasRuntimeBitsAdvanced(
2254 ty: Type,
2255 ignore_comptime_only: bool,
2256 sema_kit: ?Module.WipAnalysis,
2257 ) Module.CompileError!bool {
2258 switch (ty.tag()) {
21072259 .u1,
21082260 .u8,
21092261 .i8,
......@@ -2157,7 +2309,7 @@ pub const Type = extern union {
21572309 .@"anyframe",
21582310 .anyopaque,
21592311 .@"opaque",
2160 => true,
2312 => return true,
21612313
21622314 // These are false because they are comptime-only types.
21632315 .single_const_pointer_to_comptime_int,
......@@ -2181,7 +2333,7 @@ pub const Type = extern union {
21812333 .fn_void_no_args,
21822334 .fn_naked_noreturn_no_args,
21832335 .fn_ccc_void_no_args,
2184 => false,
2336 => return false,
21852337
21862338 // These types have more than one possible value, so the result is the same as
21872339 // asking whether they are comptime-only types.
......@@ -2198,20 +2350,34 @@ pub const Type = extern union {
21982350 .const_slice,
21992351 .mut_slice,
22002352 .pointer,
2201 => if (ignore_comptime_only) true else !comptimeOnly(ty),
2353 => {
2354 if (ignore_comptime_only) {
2355 return true;
2356 } else if (sema_kit) |sk| {
2357 return !(try sk.sema.typeRequiresComptime(sk.block, sk.src, ty));
2358 } else {
2359 return !comptimeOnly(ty);
2360 }
2361 },
22022362
22032363 .@"struct" => {
22042364 const struct_obj = ty.castTag(.@"struct").?.data;
2365 if (sema_kit) |sk| {
2366 _ = try sk.sema.typeRequiresComptime(sk.block, sk.src, ty);
2367 }
22052368 switch (struct_obj.requires_comptime) {
22062369 .wip => unreachable,
22072370 .yes => return false,
22082371 .no => if (struct_obj.known_non_opv) return true,
22092372 .unknown => {},
22102373 }
2374 if (sema_kit) |sk| {
2375 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2376 }
22112377 assert(struct_obj.haveFieldTypes());
22122378 for (struct_obj.fields.values()) |value| {
22132379 if (value.is_comptime) continue;
2214 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))
2380 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
22152381 return true;
22162382 } else {
22172383 return false;
......@@ -2229,14 +2395,17 @@ pub const Type = extern union {
22292395 .enum_numbered, .enum_nonexhaustive => {
22302396 var buffer: Payload.Bits = undefined;
22312397 const int_tag_ty = ty.intTagType(&buffer);
2232 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only);
2398 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit);
22332399 },
22342400
22352401 .@"union" => {
22362402 const union_obj = ty.castTag(.@"union").?.data;
2403 if (sema_kit) |sk| {
2404 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2405 }
22372406 assert(union_obj.haveFieldTypes());
22382407 for (union_obj.fields.values()) |value| {
2239 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))
2408 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
22402409 return true;
22412410 } else {
22422411 return false;
......@@ -2244,29 +2413,32 @@ pub const Type = extern union {
22442413 },
22452414 .union_tagged => {
22462415 const union_obj = ty.castTag(.union_tagged).?.data;
2247 if (union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only)) {
2416 if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) {
22482417 return true;
22492418 }
2419 if (sema_kit) |sk| {
2420 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2421 }
22502422 assert(union_obj.haveFieldTypes());
22512423 for (union_obj.fields.values()) |value| {
2252 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))
2424 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
22532425 return true;
22542426 } else {
22552427 return false;
22562428 }
22572429 },
22582430
2259 .array, .vector => ty.arrayLen() != 0 and
2260 ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only),
2261 .array_u8 => ty.arrayLen() != 0,
2262 .array_sentinel => ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only),
2431 .array, .vector => return ty.arrayLen() != 0 and
2432 try ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
2433 .array_u8 => return ty.arrayLen() != 0,
2434 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
22632435
2264 .int_signed, .int_unsigned => ty.cast(Payload.Bits).?.data != 0,
2436 .int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data != 0,
22652437
22662438 .error_union => {
22672439 const payload = ty.castTag(.error_union).?.data;
2268 return payload.error_set.hasRuntimeBitsAdvanced(ignore_comptime_only) or
2269 payload.payload.hasRuntimeBitsAdvanced(ignore_comptime_only);
2440 return (try payload.error_set.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) or
2441 (try payload.payload.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit));
22702442 },
22712443
22722444 .tuple, .anon_struct => {
......@@ -2274,7 +2446,7 @@ pub const Type = extern union {
22742446 for (tuple.types) |field_ty, i| {
22752447 const val = tuple.values[i];
22762448 if (val.tag() != .unreachable_value) continue; // comptime field
2277 if (field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only)) return true;
2449 if (try field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) return true;
22782450 }
22792451 return false;
22802452 },
......@@ -2283,7 +2455,7 @@ pub const Type = extern union {
22832455 .inferred_alloc_mut => unreachable,
22842456 .var_args_param => unreachable,
22852457 .generic_poison => unreachable,
2286 };
2458 }
22872459 }
22882460
22892461 /// true if and only if the type has a well-defined memory layout
......@@ -2409,11 +2581,11 @@ pub const Type = extern union {
24092581 }
24102582
24112583 pub fn hasRuntimeBits(ty: Type) bool {
2412 return hasRuntimeBitsAdvanced(ty, false);
2584 return hasRuntimeBitsAdvanced(ty, false, null) catch unreachable;
24132585 }
24142586
24152587 pub fn hasRuntimeBitsIgnoreComptime(ty: Type) bool {
2416 return hasRuntimeBitsAdvanced(ty, true);
2588 return hasRuntimeBitsAdvanced(ty, true, null) catch unreachable;
24172589 }
24182590
24192591 pub fn isFnOrHasRuntimeBits(ty: Type) bool {
......@@ -2518,8 +2690,33 @@ pub const Type = extern union {
25182690 }
25192691
25202692 /// Returns 0 for 0-bit types.
2521 pub fn abiAlignment(self: Type, target: Target) u32 {
2522 return switch (self.tag()) {
2693 pub fn abiAlignment(ty: Type, target: Target) u32 {
2694 return ty.abiAlignmentAdvanced(target, .eager).scalar;
2695 }
2696
2697 /// May capture a reference to `ty`.
2698 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {
2699 switch (ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {
2700 .val => |val| return try val,
2701 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
2702 }
2703 }
2704
2705 /// If you pass `eager` you will get back `scalar` and assert the type is resolved.
2706 /// If you pass `lazy` you may get back `scalar` or `val`.
2707 /// If `val` is returned, a reference to `ty` has been captured.
2708 fn abiAlignmentAdvanced(
2709 ty: Type,
2710 target: Target,
2711 strat: union(enum) {
2712 eager,
2713 lazy: Allocator,
2714 },
2715 ) union(enum) {
2716 scalar: u32,
2717 val: Allocator.Error!Value,
2718 } {
2719 return switch (ty.tag()) {
25232720 .u1,
25242721 .u8,
25252722 .i8,
......@@ -2538,25 +2735,25 @@ pub const Type = extern union {
25382735 .extern_options,
25392736 .@"opaque",
25402737 .anyopaque,
2541 => return 1,
2738 => return .{ .scalar = 1 },
25422739
25432740 .fn_noreturn_no_args, // represents machine code; not a pointer
25442741 .fn_void_no_args, // represents machine code; not a pointer
25452742 .fn_naked_noreturn_no_args, // represents machine code; not a pointer
25462743 .fn_ccc_void_no_args, // represents machine code; not a pointer
2547 => return target_util.defaultFunctionAlignment(target),
2744 => return .{ .scalar = target_util.defaultFunctionAlignment(target) },
25482745
25492746 // represents machine code; not a pointer
25502747 .function => {
2551 const alignment = self.castTag(.function).?.data.alignment;
2552 if (alignment != 0) return alignment;
2553 return target_util.defaultFunctionAlignment(target);
2748 const alignment = ty.castTag(.function).?.data.alignment;
2749 if (alignment != 0) return .{ .scalar = alignment };
2750 return .{ .scalar = target_util.defaultFunctionAlignment(target) };
25542751 },
25552752
2556 .i16, .u16 => return 2,
2557 .i32, .u32 => return 4,
2558 .i64, .u64 => return 8,
2559 .u128, .i128 => return 16,
2753 .i16, .u16 => return .{ .scalar = 2 },
2754 .i32, .u32 => return .{ .scalar = 4 },
2755 .i64, .u64 => return .{ .scalar = 8 },
2756 .u128, .i128 => return .{ .scalar = 16 },
25602757
25612758 .isize,
25622759 .usize,
......@@ -2579,40 +2776,40 @@ pub const Type = extern union {
25792776 .manyptr_const_u8_sentinel_0,
25802777 .@"anyframe",
25812778 .anyframe_T,
2582 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
2583
2584 .c_short => return @divExact(CType.short.sizeInBits(target), 8),
2585 .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),
2586 .c_int => return @divExact(CType.int.sizeInBits(target), 8),
2587 .c_uint => return @divExact(CType.uint.sizeInBits(target), 8),
2588 .c_long => return @divExact(CType.long.sizeInBits(target), 8),
2589 .c_ulong => return @divExact(CType.ulong.sizeInBits(target), 8),
2590 .c_longlong => return @divExact(CType.longlong.sizeInBits(target), 8),
2591 .c_ulonglong => return @divExact(CType.ulonglong.sizeInBits(target), 8),
2592
2593 .f16 => return 2,
2594 .f32 => return 4,
2595 .f64 => return 8,
2596 .f128 => return 16,
2779 => return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
2780
2781 .c_short => return .{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
2782 .c_ushort => return .{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
2783 .c_int => return .{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
2784 .c_uint => return .{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
2785 .c_long => return .{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
2786 .c_ulong => return .{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2787 .c_longlong => return .{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2788 .c_ulonglong => return .{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
2789
2790 .f16 => return .{ .scalar = 2 },
2791 .f32 => return .{ .scalar = 4 },
2792 .f64 => return .{ .scalar = 8 },
2793 .f128 => return .{ .scalar = 16 },
25972794
25982795 .f80 => switch (target.cpu.arch) {
2599 .i386 => return 4,
2600 .x86_64 => return 16,
2796 .i386 => return .{ .scalar = 4 },
2797 .x86_64 => return .{ .scalar = 16 },
26012798 else => {
26022799 var payload: Payload.Bits = .{
26032800 .base = .{ .tag = .int_unsigned },
26042801 .data = 80,
26052802 };
26062803 const u80_ty = initPayload(&payload.base);
2607 return abiAlignment(u80_ty, target);
2804 return .{ .scalar = abiAlignment(u80_ty, target) };
26082805 },
26092806 },
26102807 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
2611 16 => return abiAlignment(Type.f16, target),
2612 32 => return abiAlignment(Type.f32, target),
2613 64 => return abiAlignment(Type.f64, target),
2614 80 => return abiAlignment(Type.f80, target),
2615 128 => return abiAlignment(Type.f128, target),
2808 16 => return .{ .scalar = abiAlignment(Type.f16, target) },
2809 32 => return .{ .scalar = abiAlignment(Type.f32, target) },
2810 64 => return .{ .scalar = abiAlignment(Type.f64, target) },
2811 80 => return .{ .scalar = abiAlignment(Type.f80, target) },
2812 128 => return .{ .scalar = abiAlignment(Type.f128, target) },
26162813 else => unreachable,
26172814 },
26182815
......@@ -2622,60 +2819,93 @@ pub const Type = extern union {
26222819 .anyerror,
26232820 .error_set_inferred,
26242821 .error_set_merged,
2625 => return 2, // TODO revisit this when we have the concept of the error tag type
2822 => return .{ .scalar = 2 }, // TODO revisit this when we have the concept of the error tag type
26262823
2627 .array, .array_sentinel => return self.elemType().abiAlignment(target),
2824 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
26282825
26292826 // TODO audit this - is there any more complicated logic to determine
26302827 // ABI alignment of vectors?
2631 .vector => return 16,
2828 .vector => return .{ .scalar = 16 },
26322829
26332830 .int_signed, .int_unsigned => {
2634 const bits: u16 = self.cast(Payload.Bits).?.data;
2635 if (bits == 0) return 0;
2636 if (bits <= 8) return 1;
2637 if (bits <= 16) return 2;
2638 if (bits <= 32) return 4;
2639 if (bits <= 64) return 8;
2640 return 16;
2831 const bits: u16 = ty.cast(Payload.Bits).?.data;
2832 if (bits == 0) return .{ .scalar = 0 };
2833 if (bits <= 8) return .{ .scalar = 1 };
2834 if (bits <= 16) return .{ .scalar = 2 };
2835 if (bits <= 32) return .{ .scalar = 4 };
2836 if (bits <= 64) return .{ .scalar = 8 };
2837 return .{ .scalar = 16 };
26412838 },
26422839
26432840 .optional => {
26442841 var buf: Payload.ElemType = undefined;
2645 const child_type = self.optionalChild(&buf);
2646 if (!child_type.hasRuntimeBits()) return 1;
2842 const child_type = ty.optionalChild(&buf);
26472843
2648 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr())
2649 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
2844 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) {
2845 return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
2846 }
26502847
2651 return child_type.abiAlignment(target);
2848 switch (strat) {
2849 .eager => {
2850 if (!child_type.hasRuntimeBits()) return .{ .scalar = 1 };
2851 return .{ .scalar = child_type.abiAlignment(target) };
2852 },
2853 .lazy => |arena| switch (child_type.abiAlignmentAdvanced(target, strat)) {
2854 .scalar => |x| return .{ .scalar = @maximum(x, 1) },
2855 .val => return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2856 },
2857 }
26522858 },
26532859
26542860 .error_union => {
2655 const data = self.castTag(.error_union).?.data;
2656 if (!data.error_set.hasRuntimeBits()) {
2657 return data.payload.abiAlignment(target);
2658 } else if (!data.payload.hasRuntimeBits()) {
2659 return data.error_set.abiAlignment(target);
2861 const data = ty.castTag(.error_union).?.data;
2862 switch (strat) {
2863 .eager => {
2864 if (!data.error_set.hasRuntimeBits()) {
2865 return .{ .scalar = data.payload.abiAlignment(target) };
2866 } else if (!data.payload.hasRuntimeBits()) {
2867 return .{ .scalar = data.error_set.abiAlignment(target) };
2868 }
2869 return .{ .scalar = @maximum(
2870 data.payload.abiAlignment(target),
2871 data.error_set.abiAlignment(target),
2872 ) };
2873 },
2874 .lazy => |arena| {
2875 switch (data.payload.abiAlignmentAdvanced(target, strat)) {
2876 .scalar => |payload_align| {
2877 if (payload_align == 0) {
2878 return data.error_set.abiAlignmentAdvanced(target, strat);
2879 }
2880 switch (data.error_set.abiAlignmentAdvanced(target, strat)) {
2881 .scalar => |err_set_align| {
2882 return .{ .scalar = @maximum(payload_align, err_set_align) };
2883 },
2884 .val => {},
2885 }
2886 },
2887 .val => {},
2888 }
2889 return .{ .val = Value.Tag.lazy_align.create(arena, ty) };
2890 },
26602891 }
2661 return @maximum(
2662 data.payload.abiAlignment(target),
2663 data.error_set.abiAlignment(target),
2664 );
26652892 },
26662893
26672894 .@"struct" => {
2668 const fields = self.structFields();
2669 if (self.castTag(.@"struct")) |payload| {
2895 if (ty.castTag(.@"struct")) |payload| {
26702896 const struct_obj = payload.data;
2671 assert(struct_obj.haveLayout());
2897 if (!struct_obj.haveLayout()) switch (strat) {
2898 .eager => unreachable, // struct layout not resolved
2899 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2900 };
26722901 if (struct_obj.layout == .Packed) {
26732902 var buf: Type.Payload.Bits = undefined;
26742903 const int_ty = struct_obj.packedIntegerType(target, &buf);
2675 return int_ty.abiAlignment(target);
2904 return .{ .scalar = int_ty.abiAlignment(target) };
26762905 }
26772906 }
26782907
2908 const fields = ty.structFields();
26792909 var big_align: u32 = 0;
26802910 for (fields.values()) |field| {
26812911 if (!field.ty.hasRuntimeBits()) continue;
......@@ -2683,31 +2913,45 @@ pub const Type = extern union {
26832913 const field_align = field.normalAlignment(target);
26842914 big_align = @maximum(big_align, field_align);
26852915 }
2686 return big_align;
2916 return .{ .scalar = big_align };
26872917 },
26882918
26892919 .tuple, .anon_struct => {
2690 const tuple = self.tupleFields();
2920 const tuple = ty.tupleFields();
26912921 var big_align: u32 = 0;
26922922 for (tuple.types) |field_ty, i| {
26932923 const val = tuple.values[i];
26942924 if (val.tag() != .unreachable_value) continue; // comptime field
2695 if (!field_ty.hasRuntimeBits()) continue;
26962925
2697 const field_align = field_ty.abiAlignment(target);
2698 big_align = @maximum(big_align, field_align);
2926 switch (field_ty.abiAlignmentAdvanced(target, strat)) {
2927 .scalar => |field_align| big_align = @maximum(big_align, field_align),
2928 .val => switch (strat) {
2929 .eager => unreachable, // field type alignment not resolved
2930 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2931 },
2932 }
26992933 }
2700 return big_align;
2934 return .{ .scalar = big_align };
27012935 },
27022936
27032937 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
27042938 var buffer: Payload.Bits = undefined;
2705 const int_tag_ty = self.intTagType(&buffer);
2706 return int_tag_ty.abiAlignment(target);
2939 const int_tag_ty = ty.intTagType(&buffer);
2940 return .{ .scalar = int_tag_ty.abiAlignment(target) };
2941 },
2942 .@"union" => switch (strat) {
2943 .eager => {
2944 // TODO pass `true` for have_tag when unions have a safety tag
2945 return .{ .scalar = ty.castTag(.@"union").?.data.abiAlignment(target, false) };
2946 },
2947 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2948 },
2949 .union_tagged => switch (strat) {
2950 .eager => {
2951 return .{ .scalar = ty.castTag(.union_tagged).?.data.abiAlignment(target, true) };
2952 },
2953 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
27072954 },
2708 // TODO pass `true` for have_tag when unions have a safety tag
2709 .@"union" => return self.castTag(.@"union").?.data.abiAlignment(target, false),
2710 .union_tagged => return self.castTag(.union_tagged).?.data.abiAlignment(target, true),
27112955
27122956 .empty_struct,
27132957 .void,
......@@ -2719,7 +2963,7 @@ pub const Type = extern union {
27192963 .@"undefined",
27202964 .enum_literal,
27212965 .type_info,
2722 => return 0,
2966 => return .{ .scalar = 0 },
27232967
27242968 .noreturn,
27252969 .inferred_alloc_const,
......@@ -3392,10 +3636,7 @@ pub const Type = extern union {
33923636
33933637 .optional => {
33943638 const child_ty = self.castTag(.optional).?.data;
3395 // optionals of zero sized types behave like bools, not pointers
3396 if (!child_ty.hasRuntimeBits()) return false;
33973639 if (child_ty.zigTypeTag() != .Pointer) return false;
3398
33993640 const info = child_ty.ptrInfo().data;
34003641 switch (info.size) {
34013642 .Slice, .C => return false,
......@@ -3663,9 +3904,9 @@ pub const Type = extern union {
36633904 return union_obj.fields;
36643905 }
36653906
3666 pub fn unionFieldType(ty: Type, enum_tag: Value) Type {
3907 pub fn unionFieldType(ty: Type, enum_tag: Value, target: Target) Type {
36673908 const union_obj = ty.cast(Payload.Union).?.data;
3668 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag).?;
3909 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, target).?;
36693910 assert(union_obj.haveFieldTypes());
36703911 return union_obj.fields.values()[index].ty;
36713912 }
......@@ -4330,6 +4571,8 @@ pub const Type = extern union {
43304571
43314572 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which
43324573 /// resolves field types rather than asserting they are already resolved.
4574 /// TODO merge these implementations together with the "advanced" pattern seen
4575 /// elsewhere in this file.
43334576 pub fn comptimeOnly(ty: Type) bool {
43344577 return switch (ty.tag()) {
43354578 .u1,
......@@ -4679,20 +4922,20 @@ pub const Type = extern union {
46794922 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
46804923 /// an integer which represents the enum value. Returns the field index in
46814924 /// declaration order, or `null` if `enum_tag` does not match any field.
4682 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value) ?usize {
4925 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, target: Target) ?usize {
46834926 if (enum_tag.castTag(.enum_field_index)) |payload| {
46844927 return @as(usize, payload.data);
46854928 }
46864929 const S = struct {
4687 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize) ?usize {
4930 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, tg: Target) ?usize {
46884931 if (int_val.compareWithZero(.lt)) return null;
46894932 var end_payload: Value.Payload.U64 = .{
46904933 .base = .{ .tag = .int_u64 },
46914934 .data = end,
46924935 };
46934936 const end_val = Value.initPayload(&end_payload.base);
4694 if (int_val.compare(.gte, end_val, int_ty)) return null;
4695 return @intCast(usize, int_val.toUnsignedInt());
4937 if (int_val.compare(.gte, end_val, int_ty, tg)) return null;
4938 return @intCast(usize, int_val.toUnsignedInt(tg));
46964939 }
46974940 };
46984941 switch (ty.tag()) {
......@@ -4700,18 +4943,24 @@ pub const Type = extern union {
47004943 const enum_full = ty.cast(Payload.EnumFull).?.data;
47014944 const tag_ty = enum_full.tag_ty;
47024945 if (enum_full.values.count() == 0) {
4703 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count());
4946 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), target);
47044947 } else {
4705 return enum_full.values.getIndexContext(enum_tag, .{ .ty = tag_ty });
4948 return enum_full.values.getIndexContext(enum_tag, .{
4949 .ty = tag_ty,
4950 .target = target,
4951 });
47064952 }
47074953 },
47084954 .enum_numbered => {
47094955 const enum_obj = ty.castTag(.enum_numbered).?.data;
47104956 const tag_ty = enum_obj.tag_ty;
47114957 if (enum_obj.values.count() == 0) {
4712 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count());
4958 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), target);
47134959 } else {
4714 return enum_obj.values.getIndexContext(enum_tag, .{ .ty = tag_ty });
4960 return enum_obj.values.getIndexContext(enum_tag, .{
4961 .ty = tag_ty,
4962 .target = target,
4963 });
47154964 }
47164965 },
47174966 .enum_simple => {
......@@ -4723,7 +4972,7 @@ pub const Type = extern union {
47234972 .data = bits,
47244973 };
47254974 const tag_ty = Type.initPayload(&buffer.base);
4726 return S.fieldWithRange(tag_ty, enum_tag, fields_len);
4975 return S.fieldWithRange(tag_ty, enum_tag, fields_len, target);
47274976 },
47284977 .atomic_order,
47294978 .atomic_rmw_op,
......@@ -5018,14 +5267,14 @@ pub const Type = extern union {
50185267 /// Asserts the type is an enum.
50195268 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {
50205269 const S = struct {
5021 fn intInRange(tag_ty: Type, int_val: Value, end: usize) bool {
5270 fn intInRange(tag_ty: Type, int_val: Value, end: usize, tg: Target) bool {
50225271 if (int_val.compareWithZero(.lt)) return false;
50235272 var end_payload: Value.Payload.U64 = .{
50245273 .base = .{ .tag = .int_u64 },
50255274 .data = end,
50265275 };
50275276 const end_val = Value.initPayload(&end_payload.base);
5028 if (int_val.compare(.gte, end_val, tag_ty)) return false;
5277 if (int_val.compare(.gte, end_val, tag_ty, tg)) return false;
50295278 return true;
50305279 }
50315280 };
......@@ -5035,18 +5284,24 @@ pub const Type = extern union {
50355284 const enum_full = ty.castTag(.enum_full).?.data;
50365285 const tag_ty = enum_full.tag_ty;
50375286 if (enum_full.values.count() == 0) {
5038 return S.intInRange(tag_ty, int, enum_full.fields.count());
5287 return S.intInRange(tag_ty, int, enum_full.fields.count(), target);
50395288 } else {
5040 return enum_full.values.containsContext(int, .{ .ty = tag_ty });
5289 return enum_full.values.containsContext(int, .{
5290 .ty = tag_ty,
5291 .target = target,
5292 });
50415293 }
50425294 },
50435295 .enum_numbered => {
50445296 const enum_obj = ty.castTag(.enum_numbered).?.data;
50455297 const tag_ty = enum_obj.tag_ty;
50465298 if (enum_obj.values.count() == 0) {
5047 return S.intInRange(tag_ty, int, enum_obj.fields.count());
5299 return S.intInRange(tag_ty, int, enum_obj.fields.count(), target);
50485300 } else {
5049 return enum_obj.values.containsContext(int, .{ .ty = tag_ty });
5301 return enum_obj.values.containsContext(int, .{
5302 .ty = tag_ty,
5303 .target = target,
5304 });
50505305 }
50515306 },
50525307 .enum_simple => {
......@@ -5058,7 +5313,7 @@ pub const Type = extern union {
50585313 .data = bits,
50595314 };
50605315 const tag_ty = Type.initPayload(&buffer.base);
5061 return S.intInRange(tag_ty, int, fields_len);
5316 return S.intInRange(tag_ty, int, fields_len, target);
50625317 },
50635318 .atomic_order,
50645319 .atomic_rmw_op,
......@@ -5070,7 +5325,7 @@ pub const Type = extern union {
50705325 .prefetch_options,
50715326 .export_options,
50725327 .extern_options,
5073 => @panic("TODO resolve std.builtin types"),
5328 => unreachable,
50745329
50755330 else => unreachable,
50765331 }
......@@ -5620,7 +5875,7 @@ pub const Type = extern union {
56205875 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")
56215876 {
56225877 if (d.sentinel) |sent| {
5623 if (!d.mutable and d.pointee_type.eql(Type.u8)) {
5878 if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
56245879 switch (d.size) {
56255880 .Slice => {
56265881 if (sent.compareWithZero(.eq)) {
......@@ -5635,7 +5890,7 @@ pub const Type = extern union {
56355890 else => {},
56365891 }
56375892 }
5638 } else if (!d.mutable and d.pointee_type.eql(Type.u8)) {
5893 } else if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
56395894 switch (d.size) {
56405895 .Slice => return Type.initTag(.const_slice_u8),
56415896 .Many => return Type.initTag(.manyptr_const_u8),
......@@ -5669,10 +5924,11 @@ pub const Type = extern union {
56695924 len: u64,
56705925 sent: ?Value,
56715926 elem_type: Type,
5927 target: Target,
56725928 ) Allocator.Error!Type {
5673 if (elem_type.eql(Type.u8)) {
5929 if (elem_type.eql(Type.u8, target)) {
56745930 if (sent) |some| {
5675 if (some.eql(Value.zero, elem_type)) {
5931 if (some.eql(Value.zero, elem_type, target)) {
56765932 return Tag.array_u8_sentinel_0.create(arena, len);
56775933 }
56785934 } else {
......@@ -5715,6 +5971,25 @@ pub const Type = extern union {
57155971 }
57165972 }
57175973
5974 pub fn errorUnion(
5975 arena: Allocator,
5976 error_set: Type,
5977 payload: Type,
5978 target: Target,
5979 ) Allocator.Error!Type {
5980 assert(error_set.zigTypeTag() == .ErrorSet);
5981 if (error_set.eql(Type.@"anyerror", target) and
5982 payload.eql(Type.void, target))
5983 {
5984 return Type.initTag(.anyerror_void_error_union);
5985 }
5986
5987 return Type.Tag.error_union.create(arena, .{
5988 .error_set = error_set,
5989 .payload = payload,
5990 });
5991 }
5992
57185993 pub fn smallestUnsignedBits(max: u64) u16 {
57195994 if (max == 0) return 0;
57205995 const base = std.math.log2(max);
src/value.zig+307-208
......@@ -8,6 +8,8 @@ const Target = std.Target;
88const Allocator = std.mem.Allocator;
99const Module = @import("Module.zig");
1010const Air = @import("Air.zig");
11const TypedValue = @import("TypedValue.zig");
12const Sema = @import("Sema.zig");
1113
1214/// This is the raw data, with no bookkeeping, no memory awareness,
1315/// no de-duplication, and no type system awareness.
......@@ -175,6 +177,8 @@ pub const Value = extern union {
175177 /// and refers directly to the air. It will never be referenced by the air itself.
176178 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.
177179 bound_fn,
180 /// The ABI alignment of the payload type.
181 lazy_align,
178182
179183 pub const last_no_payload_tag = Tag.empty_array;
180184 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -283,7 +287,10 @@ pub const Value = extern union {
283287
284288 .enum_field_index => Payload.U32,
285289
286 .ty => Payload.Ty,
290 .ty,
291 .lazy_align,
292 => Payload.Ty,
293
287294 .int_type => Payload.IntType,
288295 .int_u64 => Payload.U64,
289296 .int_i64 => Payload.I64,
......@@ -453,7 +460,7 @@ pub const Value = extern union {
453460 .bound_fn,
454461 => unreachable,
455462
456 .ty => {
463 .ty, .lazy_align => {
457464 const payload = self.castTag(.ty).?;
458465 const new_payload = try arena.create(Payload.Ty);
459466 new_payload.* = .{
......@@ -608,7 +615,7 @@ pub const Value = extern union {
608615 @compileError("do not use format values directly; use either fmtDebug or fmtValue");
609616 }
610617
611 /// TODO this should become a debug dump() function. In order to print values in a meaningful way
618 /// This is a debug function. In order to print values in a meaningful way
612619 /// we also need access to the type.
613620 pub fn dump(
614621 start_val: Value,
......@@ -699,7 +706,12 @@ pub const Value = extern union {
699706 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
700707 .bool_true => return out_stream.writeAll("true"),
701708 .bool_false => return out_stream.writeAll("false"),
702 .ty => return val.castTag(.ty).?.data.format("", options, out_stream),
709 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
710 .lazy_align => {
711 try out_stream.writeAll("@alignOf(");
712 try val.castTag(.lazy_align).?.data.dump("", options, out_stream);
713 try out_stream.writeAll(")");
714 },
703715 .int_type => {
704716 const int_type = val.castTag(.int_type).?.data;
705717 return out_stream.print("{s}{d}", .{
......@@ -778,15 +790,16 @@ pub const Value = extern union {
778790 return .{ .data = val };
779791 }
780792
781 const TypedValue = @import("TypedValue.zig");
782
783 pub fn fmtValue(val: Value, ty: Type) std.fmt.Formatter(TypedValue.format) {
784 return .{ .data = .{ .ty = ty, .val = val } };
793 pub fn fmtValue(val: Value, ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {
794 return .{ .data = .{
795 .tv = .{ .ty = ty, .val = val },
796 .target = target,
797 } };
785798 }
786799
787800 /// Asserts that the value is representable as an array of bytes.
788801 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
789 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator) ![]u8 {
802 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, target: Target) ![]u8 {
790803 switch (val.tag()) {
791804 .bytes => {
792805 const bytes = val.castTag(.bytes).?.data;
......@@ -796,7 +809,7 @@ pub const Value = extern union {
796809 },
797810 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
798811 .repeated => {
799 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt());
812 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));
800813 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
801814 std.mem.set(u8, result, byte);
802815 return result;
......@@ -804,23 +817,23 @@ pub const Value = extern union {
804817 .decl_ref => {
805818 const decl = val.castTag(.decl_ref).?.data;
806819 const decl_val = try decl.value();
807 return decl_val.toAllocatedBytes(decl.ty, allocator);
820 return decl_val.toAllocatedBytes(decl.ty, allocator, target);
808821 },
809822 .the_only_possible_value => return &[_]u8{},
810823 .slice => {
811824 const slice = val.castTag(.slice).?.data;
812 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(), allocator);
825 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, target);
813826 },
814 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator),
827 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, target),
815828 }
816829 }
817830
818 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator) ![]u8 {
831 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, target: Target) ![]u8 {
819832 const result = try allocator.alloc(u8, @intCast(usize, len));
820833 var elem_value_buf: ElemValueBuffer = undefined;
821834 for (result) |*elem, i| {
822835 const elem_val = val.elemValueBuffer(i, &elem_value_buf);
823 elem.* = @intCast(u8, elem_val.toUnsignedInt());
836 elem.* = @intCast(u8, elem_val.toUnsignedInt(target));
824837 }
825838 return result;
826839 }
......@@ -977,8 +990,18 @@ pub const Value = extern union {
977990 }
978991
979992 /// Asserts the value is an integer.
980 pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {
981 switch (self.tag()) {
993 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {
994 return val.toBigIntAdvanced(space, target, null) catch unreachable;
995 }
996
997 /// Asserts the value is an integer.
998 pub fn toBigIntAdvanced(
999 val: Value,
1000 space: *BigIntSpace,
1001 target: Target,
1002 sema_kit: ?Module.WipAnalysis,
1003 ) !BigIntConst {
1004 switch (val.tag()) {
9821005 .zero,
9831006 .bool_false,
9841007 .the_only_possible_value, // i0, u0
......@@ -988,19 +1011,35 @@ pub const Value = extern union {
9881011 .bool_true,
9891012 => return BigIntMutable.init(&space.limbs, 1).toConst(),
9901013
991 .int_u64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_u64).?.data).toConst(),
992 .int_i64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_i64).?.data).toConst(),
993 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt(),
994 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt(),
1014 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
1015 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
1016 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
1017 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
9951018
9961019 .undef => unreachable,
1020
1021 .lazy_align => {
1022 const ty = val.castTag(.lazy_align).?.data;
1023 if (sema_kit) |sk| {
1024 try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
1025 }
1026 const x = ty.abiAlignment(target);
1027 return BigIntMutable.init(&space.limbs, x).toConst();
1028 },
1029
9971030 else => unreachable,
9981031 }
9991032 }
10001033
10011034 /// If the value fits in a u64, return it, otherwise null.
10021035 /// Asserts not undefined.
1003 pub fn getUnsignedInt(val: Value) ?u64 {
1036 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {
1037 return getUnsignedIntAdvanced(val, target, null) catch unreachable;
1038 }
1039
1040 /// If the value fits in a u64, return it, otherwise null.
1041 /// Asserts not undefined.
1042 pub fn getUnsignedIntAdvanced(val: Value, target: Target, sema_kit: ?Module.WipAnalysis) !?u64 {
10041043 switch (val.tag()) {
10051044 .zero,
10061045 .bool_false,
......@@ -1017,13 +1056,22 @@ pub const Value = extern union {
10171056 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
10181057
10191058 .undef => unreachable,
1059
1060 .lazy_align => {
1061 const ty = val.castTag(.lazy_align).?.data;
1062 if (sema_kit) |sk| {
1063 try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
1064 }
1065 return ty.abiAlignment(target);
1066 },
1067
10201068 else => return null,
10211069 }
10221070 }
10231071
10241072 /// Asserts the value is an integer and it fits in a u64
1025 pub fn toUnsignedInt(val: Value) u64 {
1026 return getUnsignedInt(val).?;
1073 pub fn toUnsignedInt(val: Value, target: Target) u64 {
1074 return getUnsignedInt(val, target).?;
10271075 }
10281076
10291077 /// Asserts the value is an integer and it fits in a i64
......@@ -1066,7 +1114,7 @@ pub const Value = extern union {
10661114 switch (ty.zigTypeTag()) {
10671115 .Int => {
10681116 var bigint_buffer: BigIntSpace = undefined;
1069 const bigint = val.toBigInt(&bigint_buffer);
1117 const bigint = val.toBigInt(&bigint_buffer, target);
10701118 const bits = ty.intInfo(target).bits;
10711119 const abi_size = @intCast(usize, ty.abiSize(target));
10721120 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
......@@ -1075,7 +1123,7 @@ pub const Value = extern union {
10751123 var enum_buffer: Payload.U64 = undefined;
10761124 const int_val = val.enumToInt(ty, &enum_buffer);
10771125 var bigint_buffer: BigIntSpace = undefined;
1078 const bigint = int_val.toBigInt(&bigint_buffer);
1126 const bigint = int_val.toBigInt(&bigint_buffer, target);
10791127 const bits = ty.intInfo(target).bits;
10801128 const abi_size = @intCast(usize, ty.abiSize(target));
10811129 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
......@@ -1151,7 +1199,7 @@ pub const Value = extern union {
11511199 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),
11521200 else => unreachable,
11531201 },
1154 .Int, .Bool => field_val.toBigInt(&field_space),
1202 .Int, .Bool => field_val.toBigInt(&field_space, target),
11551203 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),
11561204 else => unreachable,
11571205 };
......@@ -1511,7 +1559,7 @@ pub const Value = extern union {
15111559 const info = ty.intInfo(target);
15121560
15131561 var buffer: Value.BigIntSpace = undefined;
1514 const operand_bigint = val.toBigInt(&buffer);
1562 const operand_bigint = val.toBigInt(&buffer, target);
15151563
15161564 var limbs_buffer: [4]std.math.big.Limb = undefined;
15171565 var result_bigint = BigIntMutable{
......@@ -1532,7 +1580,7 @@ pub const Value = extern union {
15321580 const info = ty.intInfo(target);
15331581
15341582 var buffer: Value.BigIntSpace = undefined;
1535 const operand_bigint = val.toBigInt(&buffer);
1583 const operand_bigint = val.toBigInt(&buffer, target);
15361584
15371585 const limbs = try arena.alloc(
15381586 std.math.big.Limb,
......@@ -1553,7 +1601,7 @@ pub const Value = extern union {
15531601 assert(info.bits % 8 == 0);
15541602
15551603 var buffer: Value.BigIntSpace = undefined;
1556 const operand_bigint = val.toBigInt(&buffer);
1604 const operand_bigint = val.toBigInt(&buffer, target);
15571605
15581606 const limbs = try arena.alloc(
15591607 std.math.big.Limb,
......@@ -1597,7 +1645,7 @@ pub const Value = extern union {
15971645
15981646 else => {
15991647 var buffer: BigIntSpace = undefined;
1600 return self.toBigInt(&buffer).bitCountTwosComp();
1648 return self.toBigInt(&buffer, target).bitCountTwosComp();
16011649 },
16021650 }
16031651 }
......@@ -1624,6 +1672,17 @@ pub const Value = extern union {
16241672 else => unreachable,
16251673 },
16261674
1675 .lazy_align => {
1676 const info = ty.intInfo(target);
1677 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
1678 // If it is u16 or bigger we know the alignment fits without resolving it.
1679 if (info.bits >= max_needed_bits) return true;
1680 const x = self.castTag(.lazy_align).?.data.abiAlignment(target);
1681 if (x == 0) return true;
1682 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
1683 return info.bits >= actual_needed_bits;
1684 },
1685
16271686 .int_u64 => switch (ty.zigTypeTag()) {
16281687 .Int => {
16291688 const x = self.castTag(.int_u64).?.data;
......@@ -1643,7 +1702,7 @@ pub const Value = extern union {
16431702 if (info.signedness == .unsigned and x < 0)
16441703 return false;
16451704 var buffer: BigIntSpace = undefined;
1646 return self.toBigInt(&buffer).fitsInTwosComp(info.signedness, info.bits);
1705 return self.toBigInt(&buffer, target).fitsInTwosComp(info.signedness, info.bits);
16471706 },
16481707 .ComptimeInt => return true,
16491708 else => unreachable,
......@@ -1745,6 +1804,10 @@ pub const Value = extern union {
17451804 }
17461805
17471806 pub fn orderAgainstZero(lhs: Value) std.math.Order {
1807 return orderAgainstZeroAdvanced(lhs, null) catch unreachable;
1808 }
1809
1810 pub fn orderAgainstZeroAdvanced(lhs: Value, sema_kit: ?Module.WipAnalysis) !std.math.Order {
17481811 return switch (lhs.tag()) {
17491812 .zero,
17501813 .bool_false,
......@@ -1765,6 +1828,15 @@ pub const Value = extern union {
17651828 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
17661829 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
17671830
1831 .lazy_align => {
1832 const ty = lhs.castTag(.lazy_align).?.data;
1833 if (try ty.hasRuntimeBitsAdvanced(false, sema_kit)) {
1834 return .gt;
1835 } else {
1836 return .eq;
1837 }
1838 },
1839
17681840 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
17691841 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
17701842 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
......@@ -1776,11 +1848,17 @@ pub const Value = extern union {
17761848 }
17771849
17781850 /// Asserts the value is comparable.
1779 pub fn order(lhs: Value, rhs: Value) std.math.Order {
1851 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {
1852 return orderAdvanced(lhs, rhs, target, null) catch unreachable;
1853 }
1854
1855 /// Asserts the value is comparable.
1856 /// If sema_kit is null then this function asserts things are resolved and cannot fail.
1857 pub fn orderAdvanced(lhs: Value, rhs: Value, target: Target, sema_kit: ?Module.WipAnalysis) !std.math.Order {
17801858 const lhs_tag = lhs.tag();
17811859 const rhs_tag = rhs.tag();
1782 const lhs_against_zero = lhs.orderAgainstZero();
1783 const rhs_against_zero = rhs.orderAgainstZero();
1860 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(sema_kit);
1861 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(sema_kit);
17841862 switch (lhs_against_zero) {
17851863 .lt => if (rhs_against_zero != .lt) return .lt,
17861864 .eq => return rhs_against_zero.invert(),
......@@ -1814,14 +1892,24 @@ pub const Value = extern union {
18141892
18151893 var lhs_bigint_space: BigIntSpace = undefined;
18161894 var rhs_bigint_space: BigIntSpace = undefined;
1817 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space);
1818 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space);
1895 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, sema_kit);
1896 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, sema_kit);
18191897 return lhs_bigint.order(rhs_bigint);
18201898 }
18211899
18221900 /// Asserts the value is comparable. Does not take a type parameter because it supports
18231901 /// comparisons between heterogeneous types.
1824 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value) bool {
1902 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {
1903 return compareHeteroAdvanced(lhs, op, rhs, target, null) catch unreachable;
1904 }
1905
1906 pub fn compareHeteroAdvanced(
1907 lhs: Value,
1908 op: std.math.CompareOperator,
1909 rhs: Value,
1910 target: Target,
1911 sema_kit: ?Module.WipAnalysis,
1912 ) !bool {
18251913 if (lhs.pointerDecl()) |lhs_decl| {
18261914 if (rhs.pointerDecl()) |rhs_decl| {
18271915 switch (op) {
......@@ -1843,39 +1931,39 @@ pub const Value = extern union {
18431931 else => {},
18441932 }
18451933 }
1846 return order(lhs, rhs).compare(op);
1934 return (try orderAdvanced(lhs, rhs, target, sema_kit)).compare(op);
18471935 }
18481936
18491937 /// Asserts the values are comparable. Both operands have type `ty`.
18501938 /// Vector results will be reduced with AND.
1851 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {
1939 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
18521940 if (ty.zigTypeTag() == .Vector) {
18531941 var i: usize = 0;
18541942 while (i < ty.vectorLen()) : (i += 1) {
1855 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType())) {
1943 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target)) {
18561944 return false;
18571945 }
18581946 }
18591947 return true;
18601948 }
1861 return compareScalar(lhs, op, rhs, ty);
1949 return compareScalar(lhs, op, rhs, ty, target);
18621950 }
18631951
18641952 /// Asserts the values are comparable. Both operands have type `ty`.
1865 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {
1953 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
18661954 return switch (op) {
1867 .eq => lhs.eql(rhs, ty),
1868 .neq => !lhs.eql(rhs, ty),
1869 else => compareHetero(lhs, op, rhs),
1955 .eq => lhs.eql(rhs, ty, target),
1956 .neq => !lhs.eql(rhs, ty, target),
1957 else => compareHetero(lhs, op, rhs, target),
18701958 };
18711959 }
18721960
18731961 /// Asserts the values are comparable vectors of type `ty`.
1874 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator) !Value {
1962 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
18751963 assert(ty.zigTypeTag() == .Vector);
18761964 const result_data = try allocator.alloc(Value, ty.vectorLen());
18771965 for (result_data) |*scalar, i| {
1878 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType());
1966 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target);
18791967 scalar.* = if (res_bool) Value.@"true" else Value.@"false";
18801968 }
18811969 return Value.Tag.aggregate.create(allocator, result_data);
......@@ -1899,12 +1987,12 @@ pub const Value = extern union {
18991987
19001988 /// This function is used by hash maps and so treats floating-point NaNs as equal
19011989 /// to each other, and not equal to other floating-point values.
1902 pub fn eql(a: Value, b: Value, ty: Type) bool {
1990 /// Similarly, it treats `undef` as a distinct value from all other values.
1991 pub fn eql(a: Value, b: Value, ty: Type, target: Target) bool {
19031992 const a_tag = a.tag();
19041993 const b_tag = b.tag();
1905 assert(a_tag != .undef);
1906 assert(b_tag != .undef);
19071994 if (a_tag == b_tag) switch (a_tag) {
1995 .undef => return true,
19081996 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
19091997 .enum_literal => {
19101998 const a_name = a.castTag(.enum_literal).?.data;
......@@ -1920,31 +2008,31 @@ pub const Value = extern union {
19202008 const a_payload = a.castTag(.opt_payload).?.data;
19212009 const b_payload = b.castTag(.opt_payload).?.data;
19222010 var buffer: Type.Payload.ElemType = undefined;
1923 return eql(a_payload, b_payload, ty.optionalChild(&buffer));
2011 return eql(a_payload, b_payload, ty.optionalChild(&buffer), target);
19242012 },
19252013 .slice => {
19262014 const a_payload = a.castTag(.slice).?.data;
19272015 const b_payload = b.castTag(.slice).?.data;
1928 if (!eql(a_payload.len, b_payload.len, Type.usize)) return false;
2016 if (!eql(a_payload.len, b_payload.len, Type.usize, target)) return false;
19292017
19302018 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
19312019 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
19322020
1933 return eql(a_payload.ptr, b_payload.ptr, ptr_ty);
2021 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, target);
19342022 },
19352023 .elem_ptr => {
19362024 const a_payload = a.castTag(.elem_ptr).?.data;
19372025 const b_payload = b.castTag(.elem_ptr).?.data;
19382026 if (a_payload.index != b_payload.index) return false;
19392027
1940 return eql(a_payload.array_ptr, b_payload.array_ptr, ty);
2028 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, target);
19412029 },
19422030 .field_ptr => {
19432031 const a_payload = a.castTag(.field_ptr).?.data;
19442032 const b_payload = b.castTag(.field_ptr).?.data;
19452033 if (a_payload.field_index != b_payload.field_index) return false;
19462034
1947 return eql(a_payload.container_ptr, b_payload.container_ptr, ty);
2035 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, target);
19482036 },
19492037 .@"error" => {
19502038 const a_name = a.castTag(.@"error").?.data.name;
......@@ -1954,7 +2042,7 @@ pub const Value = extern union {
19542042 .eu_payload => {
19552043 const a_payload = a.castTag(.eu_payload).?.data;
19562044 const b_payload = b.castTag(.eu_payload).?.data;
1957 return eql(a_payload, b_payload, ty.errorUnionPayload());
2045 return eql(a_payload, b_payload, ty.errorUnionPayload(), target);
19582046 },
19592047 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
19602048 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
......@@ -1972,7 +2060,7 @@ pub const Value = extern union {
19722060 const types = ty.tupleFields().types;
19732061 assert(types.len == a_field_vals.len);
19742062 for (types) |field_ty, i| {
1975 if (!eql(a_field_vals[i], b_field_vals[i], field_ty)) return false;
2063 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, target)) return false;
19762064 }
19772065 return true;
19782066 }
......@@ -1981,7 +2069,7 @@ pub const Value = extern union {
19812069 const fields = ty.structFields().values();
19822070 assert(fields.len == a_field_vals.len);
19832071 for (fields) |field, i| {
1984 if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false;
2072 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, target)) return false;
19852073 }
19862074 return true;
19872075 }
......@@ -1990,7 +2078,7 @@ pub const Value = extern union {
19902078 for (a_field_vals) |a_elem, i| {
19912079 const b_elem = b_field_vals[i];
19922080
1993 if (!eql(a_elem, b_elem, elem_ty)) return false;
2081 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
19942082 }
19952083 return true;
19962084 },
......@@ -2005,17 +2093,19 @@ pub const Value = extern union {
20052093 },
20062094 .Auto => {
20072095 const tag_ty = ty.unionTagTypeHypothetical();
2008 if (!a_union.tag.eql(b_union.tag, tag_ty)) {
2096 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
20092097 return false;
20102098 }
2011 const active_field_ty = ty.unionFieldType(a_union.tag);
2012 return a_union.val.eql(b_union.val, active_field_ty);
2099 const active_field_ty = ty.unionFieldType(a_union.tag, target);
2100 return a_union.val.eql(b_union.val, active_field_ty, target);
20132101 },
20142102 }
20152103 },
20162104 else => {},
20172105 } else if (a_tag == .null_value or b_tag == .null_value) {
20182106 return false;
2107 } else if (a_tag == .undef or b_tag == .undef) {
2108 return false;
20192109 }
20202110
20212111 if (a.pointerDecl()) |a_decl| {
......@@ -2034,7 +2124,7 @@ pub const Value = extern union {
20342124 var buf_b: ToTypeBuffer = undefined;
20352125 const a_type = a.toType(&buf_a);
20362126 const b_type = b.toType(&buf_b);
2037 return a_type.eql(b_type);
2127 return a_type.eql(b_type, target);
20382128 },
20392129 .Enum => {
20402130 var buf_a: Payload.U64 = undefined;
......@@ -2043,7 +2133,7 @@ pub const Value = extern union {
20432133 const b_val = b.enumToInt(ty, &buf_b);
20442134 var buf_ty: Type.Payload.Bits = undefined;
20452135 const int_ty = ty.intTagType(&buf_ty);
2046 return eql(a_val, b_val, int_ty);
2136 return eql(a_val, b_val, int_ty, target);
20472137 },
20482138 .Array, .Vector => {
20492139 const len = ty.arrayLen();
......@@ -2054,7 +2144,7 @@ pub const Value = extern union {
20542144 while (i < len) : (i += 1) {
20552145 const a_elem = elemValueBuffer(a, i, &a_buf);
20562146 const b_elem = elemValueBuffer(b, i, &b_buf);
2057 if (!eql(a_elem, b_elem, elem_ty)) return false;
2147 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
20582148 }
20592149 return true;
20602150 },
......@@ -2070,15 +2160,15 @@ pub const Value = extern union {
20702160 if (a_nan or b_nan) {
20712161 return a_nan and b_nan;
20722162 }
2073 return order(a, b).compare(.eq);
2163 return order(a, b, target).compare(.eq);
20742164 },
2075 else => return order(a, b).compare(.eq),
2165 else => return order(a, b, target).compare(.eq),
20762166 }
20772167 }
20782168
20792169 /// This function is used by hash maps and so treats floating-point NaNs as equal
20802170 /// to each other, and not equal to other floating-point values.
2081 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash) void {
2171 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
20822172 const zig_ty_tag = ty.zigTypeTag();
20832173 std.hash.autoHash(hasher, zig_ty_tag);
20842174 if (val.isUndef()) return;
......@@ -2095,7 +2185,7 @@ pub const Value = extern union {
20952185
20962186 .Type => {
20972187 var buf: ToTypeBuffer = undefined;
2098 return val.toType(&buf).hashWithHasher(hasher);
2188 return val.toType(&buf).hashWithHasher(hasher, target);
20992189 },
21002190 .Float, .ComptimeFloat => {
21012191 // Normalize the float here because this hash must match eql semantics.
......@@ -2116,11 +2206,11 @@ pub const Value = extern union {
21162206 const slice = val.castTag(.slice).?.data;
21172207 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
21182208 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2119 hash(slice.ptr, ptr_ty, hasher);
2120 hash(slice.len, Type.usize, hasher);
2209 hash(slice.ptr, ptr_ty, hasher, target);
2210 hash(slice.len, Type.usize, hasher, target);
21212211 },
21222212
2123 else => return hashPtr(val, hasher),
2213 else => return hashPtr(val, hasher, target),
21242214 },
21252215 .Array, .Vector => {
21262216 const len = ty.arrayLen();
......@@ -2129,14 +2219,14 @@ pub const Value = extern union {
21292219 var elem_value_buf: ElemValueBuffer = undefined;
21302220 while (index < len) : (index += 1) {
21312221 const elem_val = val.elemValueBuffer(index, &elem_value_buf);
2132 elem_val.hash(elem_ty, hasher);
2222 elem_val.hash(elem_ty, hasher, target);
21332223 }
21342224 },
21352225 .Struct => {
21362226 if (ty.isTupleOrAnonStruct()) {
21372227 const fields = ty.tupleFields();
21382228 for (fields.values) |field_val, i| {
2139 field_val.hash(fields.types[i], hasher);
2229 field_val.hash(fields.types[i], hasher, target);
21402230 }
21412231 return;
21422232 }
......@@ -2145,13 +2235,13 @@ pub const Value = extern union {
21452235 switch (val.tag()) {
21462236 .empty_struct_value => {
21472237 for (fields) |field| {
2148 field.default_val.hash(field.ty, hasher);
2238 field.default_val.hash(field.ty, hasher, target);
21492239 }
21502240 },
21512241 .aggregate => {
21522242 const field_values = val.castTag(.aggregate).?.data;
21532243 for (field_values) |field_val, i| {
2154 field_val.hash(fields[i].ty, hasher);
2244 field_val.hash(fields[i].ty, hasher, target);
21552245 }
21562246 },
21572247 else => unreachable,
......@@ -2163,7 +2253,7 @@ pub const Value = extern union {
21632253 const sub_val = payload.data;
21642254 var buffer: Type.Payload.ElemType = undefined;
21652255 const sub_ty = ty.optionalChild(&buffer);
2166 sub_val.hash(sub_ty, hasher);
2256 sub_val.hash(sub_ty, hasher, target);
21672257 } else {
21682258 std.hash.autoHash(hasher, false); // non-null
21692259 }
......@@ -2172,14 +2262,14 @@ pub const Value = extern union {
21722262 if (val.tag() == .@"error") {
21732263 std.hash.autoHash(hasher, false); // error
21742264 const sub_ty = ty.errorUnionSet();
2175 val.hash(sub_ty, hasher);
2265 val.hash(sub_ty, hasher, target);
21762266 return;
21772267 }
21782268
21792269 if (val.castTag(.eu_payload)) |payload| {
21802270 std.hash.autoHash(hasher, true); // payload
21812271 const sub_ty = ty.errorUnionPayload();
2182 payload.data.hash(sub_ty, hasher);
2272 payload.data.hash(sub_ty, hasher, target);
21832273 return;
21842274 } else unreachable;
21852275 },
......@@ -2192,15 +2282,15 @@ pub const Value = extern union {
21922282 .Enum => {
21932283 var enum_space: Payload.U64 = undefined;
21942284 const int_val = val.enumToInt(ty, &enum_space);
2195 hashInt(int_val, hasher);
2285 hashInt(int_val, hasher, target);
21962286 },
21972287 .Union => {
21982288 const union_obj = val.cast(Payload.Union).?.data;
21992289 if (ty.unionTagType()) |tag_ty| {
2200 union_obj.tag.hash(tag_ty, hasher);
2290 union_obj.tag.hash(tag_ty, hasher, target);
22012291 }
2202 const active_field_ty = ty.unionFieldType(union_obj.tag);
2203 union_obj.val.hash(active_field_ty, hasher);
2292 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
2293 union_obj.val.hash(active_field_ty, hasher, target);
22042294 },
22052295 .Fn => {
22062296 const func: *Module.Fn = val.castTag(.function).?.data;
......@@ -2225,28 +2315,30 @@ pub const Value = extern union {
22252315
22262316 pub const ArrayHashContext = struct {
22272317 ty: Type,
2318 target: Target,
22282319
22292320 pub fn hash(self: @This(), val: Value) u32 {
2230 const other_context: HashContext = .{ .ty = self.ty };
2321 const other_context: HashContext = .{ .ty = self.ty, .target = self.target };
22312322 return @truncate(u32, other_context.hash(val));
22322323 }
22332324 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {
22342325 _ = b_index;
2235 return a.eql(b, self.ty);
2326 return a.eql(b, self.ty, self.target);
22362327 }
22372328 };
22382329
22392330 pub const HashContext = struct {
22402331 ty: Type,
2332 target: Target,
22412333
22422334 pub fn hash(self: @This(), val: Value) u64 {
22432335 var hasher = std.hash.Wyhash.init(0);
2244 val.hash(self.ty, &hasher);
2336 val.hash(self.ty, &hasher, self.target);
22452337 return hasher.final();
22462338 }
22472339
22482340 pub fn eql(self: @This(), a: Value, b: Value) bool {
2249 return a.eql(b, self.ty);
2341 return a.eql(b, self.ty, self.target);
22502342 }
22512343 };
22522344
......@@ -2296,16 +2388,16 @@ pub const Value = extern union {
22962388 };
22972389 }
22982390
2299 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash) void {
2391 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
23002392 var buffer: BigIntSpace = undefined;
2301 const big = int_val.toBigInt(&buffer);
2393 const big = int_val.toBigInt(&buffer, target);
23022394 std.hash.autoHash(hasher, big.positive);
23032395 for (big.limbs) |limb| {
23042396 std.hash.autoHash(hasher, limb);
23052397 }
23062398 }
23072399
2308 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash) void {
2400 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
23092401 switch (ptr_val.tag()) {
23102402 .decl_ref,
23112403 .decl_ref_mut,
......@@ -2319,25 +2411,25 @@ pub const Value = extern union {
23192411
23202412 .elem_ptr => {
23212413 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2322 hashPtr(elem_ptr.array_ptr, hasher);
2414 hashPtr(elem_ptr.array_ptr, hasher, target);
23232415 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
23242416 std.hash.autoHash(hasher, elem_ptr.index);
23252417 },
23262418 .field_ptr => {
23272419 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
23282420 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2329 hashPtr(field_ptr.container_ptr, hasher);
2421 hashPtr(field_ptr.container_ptr, hasher, target);
23302422 std.hash.autoHash(hasher, field_ptr.field_index);
23312423 },
23322424 .eu_payload_ptr => {
23332425 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
23342426 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2335 hashPtr(err_union_ptr.container_ptr, hasher);
2427 hashPtr(err_union_ptr.container_ptr, hasher, target);
23362428 },
23372429 .opt_payload_ptr => {
23382430 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
23392431 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2340 hashPtr(opt_ptr.container_ptr, hasher);
2432 hashPtr(opt_ptr.container_ptr, hasher, target);
23412433 },
23422434
23432435 .zero,
......@@ -2349,7 +2441,7 @@ pub const Value = extern union {
23492441 .bool_false,
23502442 .bool_true,
23512443 .the_only_possible_value,
2352 => return hashInt(ptr_val, hasher),
2444 => return hashInt(ptr_val, hasher, target),
23532445
23542446 else => unreachable,
23552447 }
......@@ -2411,9 +2503,9 @@ pub const Value = extern union {
24112503 };
24122504 }
24132505
2414 pub fn sliceLen(val: Value) u64 {
2506 pub fn sliceLen(val: Value, target: Target) u64 {
24152507 return switch (val.tag()) {
2416 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(),
2508 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(target),
24172509 .decl_ref => {
24182510 const decl = val.castTag(.decl_ref).?.data;
24192511 if (decl.ty.zigTypeTag() == .Array) {
......@@ -2561,7 +2653,7 @@ pub const Value = extern union {
25612653 }
25622654
25632655 /// Returns a pointer to the element value at the index.
2564 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {
2656 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize, target: Target) Allocator.Error!Value {
25652657 const elem_ty = ty.elemType2();
25662658 const ptr_val = switch (val.tag()) {
25672659 .slice => val.castTag(.slice).?.data.ptr,
......@@ -2570,7 +2662,7 @@ pub const Value = extern union {
25702662
25712663 if (ptr_val.tag() == .elem_ptr) {
25722664 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2573 if (elem_ptr.elem_ty.eql(elem_ty)) {
2665 if (elem_ptr.elem_ty.eql(elem_ty, target)) {
25742666 return Tag.elem_ptr.create(arena, .{
25752667 .array_ptr = elem_ptr.array_ptr,
25762668 .elem_ty = elem_ptr.elem_ty,
......@@ -2821,8 +2913,8 @@ pub const Value = extern union {
28212913
28222914 var lhs_space: Value.BigIntSpace = undefined;
28232915 var rhs_space: Value.BigIntSpace = undefined;
2824 const lhs_bigint = lhs.toBigInt(&lhs_space);
2825 const rhs_bigint = rhs.toBigInt(&rhs_space);
2916 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2917 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
28262918 const limbs = try arena.alloc(
28272919 std.math.big.Limb,
28282920 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2865,7 +2957,7 @@ pub const Value = extern union {
28652957 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
28662958
28672959 if (ty.zigTypeTag() == .ComptimeInt) {
2868 return intAdd(lhs, rhs, ty, arena);
2960 return intAdd(lhs, rhs, ty, arena, target);
28692961 }
28702962
28712963 if (ty.isAnyFloat()) {
......@@ -2925,8 +3017,8 @@ pub const Value = extern union {
29253017
29263018 var lhs_space: Value.BigIntSpace = undefined;
29273019 var rhs_space: Value.BigIntSpace = undefined;
2928 const lhs_bigint = lhs.toBigInt(&lhs_space);
2929 const rhs_bigint = rhs.toBigInt(&rhs_space);
3020 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3021 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
29303022 const limbs = try arena.alloc(
29313023 std.math.big.Limb,
29323024 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2947,8 +3039,8 @@ pub const Value = extern union {
29473039
29483040 var lhs_space: Value.BigIntSpace = undefined;
29493041 var rhs_space: Value.BigIntSpace = undefined;
2950 const lhs_bigint = lhs.toBigInt(&lhs_space);
2951 const rhs_bigint = rhs.toBigInt(&rhs_space);
3042 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3043 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
29523044 const limbs = try arena.alloc(
29533045 std.math.big.Limb,
29543046 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2991,7 +3083,7 @@ pub const Value = extern union {
29913083 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
29923084
29933085 if (ty.zigTypeTag() == .ComptimeInt) {
2994 return intSub(lhs, rhs, ty, arena);
3086 return intSub(lhs, rhs, ty, arena, target);
29953087 }
29963088
29973089 if (ty.isAnyFloat()) {
......@@ -3035,8 +3127,8 @@ pub const Value = extern union {
30353127
30363128 var lhs_space: Value.BigIntSpace = undefined;
30373129 var rhs_space: Value.BigIntSpace = undefined;
3038 const lhs_bigint = lhs.toBigInt(&lhs_space);
3039 const rhs_bigint = rhs.toBigInt(&rhs_space);
3130 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3131 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
30403132 const limbs = try arena.alloc(
30413133 std.math.big.Limb,
30423134 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3057,8 +3149,8 @@ pub const Value = extern union {
30573149
30583150 var lhs_space: Value.BigIntSpace = undefined;
30593151 var rhs_space: Value.BigIntSpace = undefined;
3060 const lhs_bigint = lhs.toBigInt(&lhs_space);
3061 const rhs_bigint = rhs.toBigInt(&rhs_space);
3152 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3153 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
30623154 const limbs = try arena.alloc(
30633155 std.math.big.Limb,
30643156 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -3110,7 +3202,7 @@ pub const Value = extern union {
31103202 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
31113203
31123204 if (ty.zigTypeTag() == .ComptimeInt) {
3113 return intMul(lhs, rhs, ty, arena);
3205 return intMul(lhs, rhs, ty, arena, target);
31143206 }
31153207
31163208 if (ty.isAnyFloat()) {
......@@ -3154,8 +3246,8 @@ pub const Value = extern union {
31543246
31553247 var lhs_space: Value.BigIntSpace = undefined;
31563248 var rhs_space: Value.BigIntSpace = undefined;
3157 const lhs_bigint = lhs.toBigInt(&lhs_space);
3158 const rhs_bigint = rhs.toBigInt(&rhs_space);
3249 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3250 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
31593251 const limbs = try arena.alloc(
31603252 std.math.big.Limb,
31613253 std.math.max(
......@@ -3175,24 +3267,24 @@ pub const Value = extern union {
31753267 }
31763268
31773269 /// Supports both floats and ints; handles undefined.
3178 pub fn numberMax(lhs: Value, rhs: Value) Value {
3270 pub fn numberMax(lhs: Value, rhs: Value, target: Target) Value {
31793271 if (lhs.isUndef() or rhs.isUndef()) return undef;
31803272 if (lhs.isNan()) return rhs;
31813273 if (rhs.isNan()) return lhs;
31823274
3183 return switch (order(lhs, rhs)) {
3275 return switch (order(lhs, rhs, target)) {
31843276 .lt => rhs,
31853277 .gt, .eq => lhs,
31863278 };
31873279 }
31883280
31893281 /// Supports both floats and ints; handles undefined.
3190 pub fn numberMin(lhs: Value, rhs: Value) Value {
3282 pub fn numberMin(lhs: Value, rhs: Value, target: Target) Value {
31913283 if (lhs.isUndef() or rhs.isUndef()) return undef;
31923284 if (lhs.isNan()) return rhs;
31933285 if (rhs.isNan()) return lhs;
31943286
3195 return switch (order(lhs, rhs)) {
3287 return switch (order(lhs, rhs, target)) {
31963288 .lt => lhs,
31973289 .gt, .eq => rhs,
31983290 };
......@@ -3224,7 +3316,7 @@ pub const Value = extern union {
32243316 // TODO is this a performance issue? maybe we should try the operation without
32253317 // resorting to BigInt first.
32263318 var val_space: Value.BigIntSpace = undefined;
3227 const val_bigint = val.toBigInt(&val_space);
3319 const val_bigint = val.toBigInt(&val_space, target);
32283320 const limbs = try arena.alloc(
32293321 std.math.big.Limb,
32303322 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3236,27 +3328,27 @@ pub const Value = extern union {
32363328 }
32373329
32383330 /// operands must be (vectors of) integers; handles undefined scalars.
3239 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3331 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
32403332 if (ty.zigTypeTag() == .Vector) {
32413333 const result_data = try allocator.alloc(Value, ty.vectorLen());
32423334 for (result_data) |*scalar, i| {
3243 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3335 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
32443336 }
32453337 return Value.Tag.aggregate.create(allocator, result_data);
32463338 }
3247 return bitwiseAndScalar(lhs, rhs, allocator);
3339 return bitwiseAndScalar(lhs, rhs, allocator, target);
32483340 }
32493341
32503342 /// operands must be integers; handles undefined.
3251 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3343 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
32523344 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32533345
32543346 // TODO is this a performance issue? maybe we should try the operation without
32553347 // resorting to BigInt first.
32563348 var lhs_space: Value.BigIntSpace = undefined;
32573349 var rhs_space: Value.BigIntSpace = undefined;
3258 const lhs_bigint = lhs.toBigInt(&lhs_space);
3259 const rhs_bigint = rhs.toBigInt(&rhs_space);
3350 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3351 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
32603352 const limbs = try arena.alloc(
32613353 std.math.big.Limb,
32623354 // + 1 for negatives
......@@ -3283,38 +3375,38 @@ pub const Value = extern union {
32833375 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {
32843376 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32853377
3286 const anded = try bitwiseAnd(lhs, rhs, ty, arena);
3378 const anded = try bitwiseAnd(lhs, rhs, ty, arena, target);
32873379
32883380 const all_ones = if (ty.isSignedInt())
32893381 try Value.Tag.int_i64.create(arena, -1)
32903382 else
32913383 try ty.maxInt(arena, target);
32923384
3293 return bitwiseXor(anded, all_ones, ty, arena);
3385 return bitwiseXor(anded, all_ones, ty, arena, target);
32943386 }
32953387
32963388 /// operands must be (vectors of) integers; handles undefined scalars.
3297 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3389 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
32983390 if (ty.zigTypeTag() == .Vector) {
32993391 const result_data = try allocator.alloc(Value, ty.vectorLen());
33003392 for (result_data) |*scalar, i| {
3301 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3393 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33023394 }
33033395 return Value.Tag.aggregate.create(allocator, result_data);
33043396 }
3305 return bitwiseOrScalar(lhs, rhs, allocator);
3397 return bitwiseOrScalar(lhs, rhs, allocator, target);
33063398 }
33073399
33083400 /// operands must be integers; handles undefined.
3309 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3401 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
33103402 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33113403
33123404 // TODO is this a performance issue? maybe we should try the operation without
33133405 // resorting to BigInt first.
33143406 var lhs_space: Value.BigIntSpace = undefined;
33153407 var rhs_space: Value.BigIntSpace = undefined;
3316 const lhs_bigint = lhs.toBigInt(&lhs_space);
3317 const rhs_bigint = rhs.toBigInt(&rhs_space);
3408 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3409 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33183410 const limbs = try arena.alloc(
33193411 std.math.big.Limb,
33203412 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
......@@ -3325,27 +3417,27 @@ pub const Value = extern union {
33253417 }
33263418
33273419 /// operands must be (vectors of) integers; handles undefined scalars.
3328 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3420 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33293421 if (ty.zigTypeTag() == .Vector) {
33303422 const result_data = try allocator.alloc(Value, ty.vectorLen());
33313423 for (result_data) |*scalar, i| {
3332 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3424 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33333425 }
33343426 return Value.Tag.aggregate.create(allocator, result_data);
33353427 }
3336 return bitwiseXorScalar(lhs, rhs, allocator);
3428 return bitwiseXorScalar(lhs, rhs, allocator, target);
33373429 }
33383430
33393431 /// operands must be integers; handles undefined.
3340 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3432 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
33413433 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33423434
33433435 // TODO is this a performance issue? maybe we should try the operation without
33443436 // resorting to BigInt first.
33453437 var lhs_space: Value.BigIntSpace = undefined;
33463438 var rhs_space: Value.BigIntSpace = undefined;
3347 const lhs_bigint = lhs.toBigInt(&lhs_space);
3348 const rhs_bigint = rhs.toBigInt(&rhs_space);
3439 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3440 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33493441 const limbs = try arena.alloc(
33503442 std.math.big.Limb,
33513443 // + 1 for negatives
......@@ -3356,24 +3448,24 @@ pub const Value = extern union {
33563448 return fromBigInt(arena, result_bigint.toConst());
33573449 }
33583450
3359 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3451 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33603452 if (ty.zigTypeTag() == .Vector) {
33613453 const result_data = try allocator.alloc(Value, ty.vectorLen());
33623454 for (result_data) |*scalar, i| {
3363 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3455 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33643456 }
33653457 return Value.Tag.aggregate.create(allocator, result_data);
33663458 }
3367 return intAddScalar(lhs, rhs, allocator);
3459 return intAddScalar(lhs, rhs, allocator, target);
33683460 }
33693461
3370 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3462 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
33713463 // TODO is this a performance issue? maybe we should try the operation without
33723464 // resorting to BigInt first.
33733465 var lhs_space: Value.BigIntSpace = undefined;
33743466 var rhs_space: Value.BigIntSpace = undefined;
3375 const lhs_bigint = lhs.toBigInt(&lhs_space);
3376 const rhs_bigint = rhs.toBigInt(&rhs_space);
3467 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3468 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33773469 const limbs = try allocator.alloc(
33783470 std.math.big.Limb,
33793471 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -3383,24 +3475,24 @@ pub const Value = extern union {
33833475 return fromBigInt(allocator, result_bigint.toConst());
33843476 }
33853477
3386 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3478 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33873479 if (ty.zigTypeTag() == .Vector) {
33883480 const result_data = try allocator.alloc(Value, ty.vectorLen());
33893481 for (result_data) |*scalar, i| {
3390 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3482 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33913483 }
33923484 return Value.Tag.aggregate.create(allocator, result_data);
33933485 }
3394 return intSubScalar(lhs, rhs, allocator);
3486 return intSubScalar(lhs, rhs, allocator, target);
33953487 }
33963488
3397 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3489 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
33983490 // TODO is this a performance issue? maybe we should try the operation without
33993491 // resorting to BigInt first.
34003492 var lhs_space: Value.BigIntSpace = undefined;
34013493 var rhs_space: Value.BigIntSpace = undefined;
3402 const lhs_bigint = lhs.toBigInt(&lhs_space);
3403 const rhs_bigint = rhs.toBigInt(&rhs_space);
3494 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3495 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34043496 const limbs = try allocator.alloc(
34053497 std.math.big.Limb,
34063498 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -3410,24 +3502,24 @@ pub const Value = extern union {
34103502 return fromBigInt(allocator, result_bigint.toConst());
34113503 }
34123504
3413 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3505 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34143506 if (ty.zigTypeTag() == .Vector) {
34153507 const result_data = try allocator.alloc(Value, ty.vectorLen());
34163508 for (result_data) |*scalar, i| {
3417 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3509 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34183510 }
34193511 return Value.Tag.aggregate.create(allocator, result_data);
34203512 }
3421 return intDivScalar(lhs, rhs, allocator);
3513 return intDivScalar(lhs, rhs, allocator, target);
34223514 }
34233515
3424 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3516 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34253517 // TODO is this a performance issue? maybe we should try the operation without
34263518 // resorting to BigInt first.
34273519 var lhs_space: Value.BigIntSpace = undefined;
34283520 var rhs_space: Value.BigIntSpace = undefined;
3429 const lhs_bigint = lhs.toBigInt(&lhs_space);
3430 const rhs_bigint = rhs.toBigInt(&rhs_space);
3521 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3522 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34313523 const limbs_q = try allocator.alloc(
34323524 std.math.big.Limb,
34333525 lhs_bigint.limbs.len,
......@@ -3446,24 +3538,24 @@ pub const Value = extern union {
34463538 return fromBigInt(allocator, result_q.toConst());
34473539 }
34483540
3449 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3541 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34503542 if (ty.zigTypeTag() == .Vector) {
34513543 const result_data = try allocator.alloc(Value, ty.vectorLen());
34523544 for (result_data) |*scalar, i| {
3453 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3545 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34543546 }
34553547 return Value.Tag.aggregate.create(allocator, result_data);
34563548 }
3457 return intDivFloorScalar(lhs, rhs, allocator);
3549 return intDivFloorScalar(lhs, rhs, allocator, target);
34583550 }
34593551
3460 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3552 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34613553 // TODO is this a performance issue? maybe we should try the operation without
34623554 // resorting to BigInt first.
34633555 var lhs_space: Value.BigIntSpace = undefined;
34643556 var rhs_space: Value.BigIntSpace = undefined;
3465 const lhs_bigint = lhs.toBigInt(&lhs_space);
3466 const rhs_bigint = rhs.toBigInt(&rhs_space);
3557 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3558 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34673559 const limbs_q = try allocator.alloc(
34683560 std.math.big.Limb,
34693561 lhs_bigint.limbs.len,
......@@ -3482,24 +3574,24 @@ pub const Value = extern union {
34823574 return fromBigInt(allocator, result_q.toConst());
34833575 }
34843576
3485 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3577 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34863578 if (ty.zigTypeTag() == .Vector) {
34873579 const result_data = try allocator.alloc(Value, ty.vectorLen());
34883580 for (result_data) |*scalar, i| {
3489 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3581 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34903582 }
34913583 return Value.Tag.aggregate.create(allocator, result_data);
34923584 }
3493 return intRemScalar(lhs, rhs, allocator);
3585 return intRemScalar(lhs, rhs, allocator, target);
34943586 }
34953587
3496 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3588 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34973589 // TODO is this a performance issue? maybe we should try the operation without
34983590 // resorting to BigInt first.
34993591 var lhs_space: Value.BigIntSpace = undefined;
35003592 var rhs_space: Value.BigIntSpace = undefined;
3501 const lhs_bigint = lhs.toBigInt(&lhs_space);
3502 const rhs_bigint = rhs.toBigInt(&rhs_space);
3593 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3594 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
35033595 const limbs_q = try allocator.alloc(
35043596 std.math.big.Limb,
35053597 lhs_bigint.limbs.len,
......@@ -3520,24 +3612,24 @@ pub const Value = extern union {
35203612 return fromBigInt(allocator, result_r.toConst());
35213613 }
35223614
3523 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3615 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
35243616 if (ty.zigTypeTag() == .Vector) {
35253617 const result_data = try allocator.alloc(Value, ty.vectorLen());
35263618 for (result_data) |*scalar, i| {
3527 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3619 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
35283620 }
35293621 return Value.Tag.aggregate.create(allocator, result_data);
35303622 }
3531 return intModScalar(lhs, rhs, allocator);
3623 return intModScalar(lhs, rhs, allocator, target);
35323624 }
35333625
3534 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3626 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
35353627 // TODO is this a performance issue? maybe we should try the operation without
35363628 // resorting to BigInt first.
35373629 var lhs_space: Value.BigIntSpace = undefined;
35383630 var rhs_space: Value.BigIntSpace = undefined;
3539 const lhs_bigint = lhs.toBigInt(&lhs_space);
3540 const rhs_bigint = rhs.toBigInt(&rhs_space);
3631 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3632 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
35413633 const limbs_q = try allocator.alloc(
35423634 std.math.big.Limb,
35433635 lhs_bigint.limbs.len,
......@@ -3658,24 +3750,24 @@ pub const Value = extern union {
36583750 }
36593751 }
36603752
3661 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3753 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
36623754 if (ty.zigTypeTag() == .Vector) {
36633755 const result_data = try allocator.alloc(Value, ty.vectorLen());
36643756 for (result_data) |*scalar, i| {
3665 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3757 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
36663758 }
36673759 return Value.Tag.aggregate.create(allocator, result_data);
36683760 }
3669 return intMulScalar(lhs, rhs, allocator);
3761 return intMulScalar(lhs, rhs, allocator, target);
36703762 }
36713763
3672 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3764 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
36733765 // TODO is this a performance issue? maybe we should try the operation without
36743766 // resorting to BigInt first.
36753767 var lhs_space: Value.BigIntSpace = undefined;
36763768 var rhs_space: Value.BigIntSpace = undefined;
3677 const lhs_bigint = lhs.toBigInt(&lhs_space);
3678 const rhs_bigint = rhs.toBigInt(&rhs_space);
3769 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3770 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
36793771 const limbs = try allocator.alloc(
36803772 std.math.big.Limb,
36813773 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -3690,34 +3782,41 @@ pub const Value = extern union {
36903782 return fromBigInt(allocator, result_bigint.toConst());
36913783 }
36923784
3693 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
3785 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
36943786 if (ty.zigTypeTag() == .Vector) {
36953787 const result_data = try allocator.alloc(Value, ty.vectorLen());
36963788 for (result_data) |*scalar, i| {
3697 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits);
3789 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits, target);
36983790 }
36993791 return Value.Tag.aggregate.create(allocator, result_data);
37003792 }
3701 return intTruncScalar(val, allocator, signedness, bits);
3793 return intTruncScalar(val, allocator, signedness, bits, target);
37023794 }
37033795
37043796 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
3705 pub fn intTruncBitsAsValue(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: Value) !Value {
3797 pub fn intTruncBitsAsValue(
3798 val: Value,
3799 ty: Type,
3800 allocator: Allocator,
3801 signedness: std.builtin.Signedness,
3802 bits: Value,
3803 target: Target,
3804 ) !Value {
37063805 if (ty.zigTypeTag() == .Vector) {
37073806 const result_data = try allocator.alloc(Value, ty.vectorLen());
37083807 for (result_data) |*scalar, i| {
3709 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt()));
3808 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt(target)), target);
37103809 }
37113810 return Value.Tag.aggregate.create(allocator, result_data);
37123811 }
3713 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt()));
3812 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);
37143813 }
37153814
3716 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
3815 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
37173816 if (bits == 0) return Value.zero;
37183817
37193818 var val_space: Value.BigIntSpace = undefined;
3720 const val_bigint = val.toBigInt(&val_space);
3819 const val_bigint = val.toBigInt(&val_space, target);
37213820
37223821 const limbs = try allocator.alloc(
37233822 std.math.big.Limb,
......@@ -3729,23 +3828,23 @@ pub const Value = extern union {
37293828 return fromBigInt(allocator, result_bigint.toConst());
37303829 }
37313830
3732 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3831 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
37333832 if (ty.zigTypeTag() == .Vector) {
37343833 const result_data = try allocator.alloc(Value, ty.vectorLen());
37353834 for (result_data) |*scalar, i| {
3736 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3835 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
37373836 }
37383837 return Value.Tag.aggregate.create(allocator, result_data);
37393838 }
3740 return shlScalar(lhs, rhs, allocator);
3839 return shlScalar(lhs, rhs, allocator, target);
37413840 }
37423841
3743 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3842 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
37443843 // TODO is this a performance issue? maybe we should try the operation without
37453844 // resorting to BigInt first.
37463845 var lhs_space: Value.BigIntSpace = undefined;
3747 const lhs_bigint = lhs.toBigInt(&lhs_space);
3748 const shift = @intCast(usize, rhs.toUnsignedInt());
3846 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3847 const shift = @intCast(usize, rhs.toUnsignedInt(target));
37493848 const limbs = try allocator.alloc(
37503849 std.math.big.Limb,
37513850 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -3768,8 +3867,8 @@ pub const Value = extern union {
37683867 ) !OverflowArithmeticResult {
37693868 const info = ty.intInfo(target);
37703869 var lhs_space: Value.BigIntSpace = undefined;
3771 const lhs_bigint = lhs.toBigInt(&lhs_space);
3772 const shift = @intCast(usize, rhs.toUnsignedInt());
3870 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3871 const shift = @intCast(usize, rhs.toUnsignedInt(target));
37733872 const limbs = try allocator.alloc(
37743873 std.math.big.Limb,
37753874 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -3819,8 +3918,8 @@ pub const Value = extern union {
38193918 const info = ty.intInfo(target);
38203919
38213920 var lhs_space: Value.BigIntSpace = undefined;
3822 const lhs_bigint = lhs.toBigInt(&lhs_space);
3823 const shift = @intCast(usize, rhs.toUnsignedInt());
3921 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3922 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38243923 const limbs = try arena.alloc(
38253924 std.math.big.Limb,
38263925 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3858,29 +3957,29 @@ pub const Value = extern union {
38583957 arena: Allocator,
38593958 target: Target,
38603959 ) !Value {
3861 const shifted = try lhs.shl(rhs, ty, arena);
3960 const shifted = try lhs.shl(rhs, ty, arena, target);
38623961 const int_info = ty.intInfo(target);
3863 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits);
3962 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, target);
38643963 return truncated;
38653964 }
38663965
3867 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3966 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
38683967 if (ty.zigTypeTag() == .Vector) {
38693968 const result_data = try allocator.alloc(Value, ty.vectorLen());
38703969 for (result_data) |*scalar, i| {
3871 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3970 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
38723971 }
38733972 return Value.Tag.aggregate.create(allocator, result_data);
38743973 }
3875 return shrScalar(lhs, rhs, allocator);
3974 return shrScalar(lhs, rhs, allocator, target);
38763975 }
38773976
3878 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3977 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
38793978 // TODO is this a performance issue? maybe we should try the operation without
38803979 // resorting to BigInt first.
38813980 var lhs_space: Value.BigIntSpace = undefined;
3882 const lhs_bigint = lhs.toBigInt(&lhs_space);
3883 const shift = @intCast(usize, rhs.toUnsignedInt());
3981 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3982 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38843983
38853984 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
38863985 if (result_limbs == 0) {
test/behavior.zig+1-1
......@@ -125,6 +125,7 @@ test {
125125 _ = @import("behavior/src.zig");
126126 _ = @import("behavior/struct.zig");
127127 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
128 _ = @import("behavior/struct_contains_slice_of_itself.zig");
128129 _ = @import("behavior/switch.zig");
129130 _ = @import("behavior/switch_prong_err_enum.zig");
130131 _ = @import("behavior/switch_prong_implicit_cast.zig");
......@@ -179,6 +180,5 @@ test {
179180 _ = @import("behavior/bugs/6781.zig");
180181 _ = @import("behavior/bugs/7027.zig");
181182 _ = @import("behavior/select.zig");
182 _ = @import("behavior/struct_contains_slice_of_itself.zig");
183183 }
184184}
test/behavior/struct_contains_slice_of_itself.zig+9
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const expect = @import("std").testing.expect;
23
34const Node = struct {
......@@ -11,6 +12,10 @@ const NodeAligned = struct {
1112};
1213
1314test "struct contains slice of itself" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18
1419 var other_nodes = [_]Node{
1520 Node{
1621 .payload = 31,
......@@ -48,6 +53,10 @@ test "struct contains slice of itself" {
4853}
4954
5055test "struct contains aligned slice of itself" {
56 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
59
5160 var other_nodes = [_]NodeAligned{
5261 NodeAligned{
5362 .payload = 31,
test/stage2/x86_64.zig+1-1
......@@ -1166,7 +1166,7 @@ pub fn addCases(ctx: *TestContext) !void {
11661166 \\ _ = x;
11671167 \\}
11681168 , &[_][]const u8{
1169 ":2:9: error: variable of type '@Type(.Null)' must be const or comptime",
1169 ":2:9: error: variable of type '@TypeOf(null)' must be const or comptime",
11701170 });
11711171 }
11721172