authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 00:23:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 15:45:58-07:00
log593130ce0a4b06185fcb4806f8330857a1da9f92
treeae30c61a06e6cecb97cc760dc6acd0cbfb83c162
parentb74f2924102fe06addb688dc5fd039dc2756f619

stage2: lazy `@alignOf`

Add a `target` parameter to every function that deals with Type and Value.

24 files changed, 1570 insertions(+), 1053 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+19-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
......@@ -184,6 +185,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
184185);
185186
186187pub const MemoizedCall = struct {
188 target: std.Target,
189
187190 pub const Key = struct {
188191 func: *Fn,
189192 args: []TypedValue,
......@@ -195,14 +198,12 @@ pub const MemoizedCall = struct {
195198 };
196199
197200 pub fn eql(ctx: @This(), a: Key, b: Key) bool {
198 _ = ctx;
199
200201 if (a.func != b.func) return false;
201202
202203 assert(a.args.len == b.args.len);
203204 for (a.args) |a_arg, arg_i| {
204205 const b_arg = b.args[arg_i];
205 if (!a_arg.eql(b_arg)) {
206 if (!a_arg.eql(b_arg, ctx.target)) {
206207 return false;
207208 }
208209 }
......@@ -212,8 +213,6 @@ pub const MemoizedCall = struct {
212213
213214 /// Must match `Sema.GenericCallAdapter.hash`.
214215 pub fn hash(ctx: @This(), key: Key) u64 {
215 _ = ctx;
216
217216 var hasher = std.hash.Wyhash.init(0);
218217
219218 // The generic function Decl is guaranteed to be the first dependency
......@@ -223,7 +222,7 @@ pub const MemoizedCall = struct {
223222 // This logic must be kept in sync with the logic in `analyzeCall` that
224223 // computes the hash.
225224 for (key.args) |arg| {
226 arg.hash(&hasher);
225 arg.hash(&hasher, ctx.target);
227226 }
228227
229228 return hasher.final();
......@@ -1230,7 +1229,7 @@ pub const Union = struct {
12301229 if (field.abi_align == 0) {
12311230 break :a field.ty.abiAlignment(target);
12321231 } else {
1233 break :a @intCast(u32, field.abi_align.toUnsignedInt());
1232 break :a field.abi_align;
12341233 }
12351234 };
12361235 if (field_align > most_alignment) {
......@@ -3877,6 +3876,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38773876 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);
38783877 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
38793878 };
3879 const target = sema.mod.getTarget();
38803880 const address_space = blk: {
38813881 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {
38823882 .function, .extern_fn => .function,
......@@ -3886,9 +3886,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38863886
38873887 break :blk switch (decl.zirAddrspaceRef()) {
38883888 .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),
3889 .function => target_util.defaultAddressSpace(target, .function),
3890 .variable => target_util.defaultAddressSpace(target, .global_mutable),
3891 .constant => target_util.defaultAddressSpace(target, .global_constant),
38923892 else => unreachable,
38933893 },
38943894 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
......@@ -3904,13 +3904,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39043904
39053905 if (decl.is_usingnamespace) {
39063906 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});
3907 if (!decl_tv.ty.eql(ty_ty, target)) {
3908 return sema.fail(&block_scope, src, "expected type, found {}", .{
3909 decl_tv.ty.fmt(target),
3910 });
39093911 }
39103912 var buffer: Value.ToTypeBuffer = undefined;
39113913 const ty = decl_tv.val.toType(&buffer);
39123914 if (ty.getNamespace() == null) {
3913 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty});
3915 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(target)});
39143916 }
39153917
39163918 decl.ty = ty_ty;
......@@ -3937,7 +3939,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39373939
39383940 if (decl.has_tv) {
39393941 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
3940 type_changed = !decl.ty.eql(decl_tv.ty);
3942 type_changed = !decl.ty.eql(decl_tv.ty, target);
39413943 if (decl.getFunction()) |prev_func| {
39423944 prev_is_inline = prev_func.state == .inline_only;
39433945 }
......@@ -3986,7 +3988,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39863988 }
39873989 var type_changed = true;
39883990 if (decl.has_tv) {
3989 type_changed = !decl.ty.eql(decl_tv.ty);
3991 type_changed = !decl.ty.eql(decl_tv.ty, target);
39903992 decl.clearValues(gpa);
39913993 }
39923994
......@@ -5054,22 +5056,6 @@ pub fn errNoteNonLazy(
50545056 };
50555057}
50565058
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
50735059pub fn getTarget(mod: Module) Target {
50745060 return mod.comp.bin_file.options.target;
50755061}
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+499-349
......@@ -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 val.toUnsignedInt(target);
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 (ptr_val.getUnsignedInt(target)) |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
......@@ -12414,6 +12491,7 @@ fn fieldType(
1241412491 ty_src: LazySrcLoc,
1241512492) CompileError!Air.Inst.Ref {
1241612493 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
12494 const target = sema.mod.getTarget();
1241712495 switch (resolved_ty.zigTypeTag()) {
1241812496 .Struct => {
1241912497 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
......@@ -12428,7 +12506,7 @@ fn fieldType(
1242812506 return sema.addType(field.ty);
1242912507 },
1243012508 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
12431 resolved_ty,
12509 resolved_ty.fmt(target),
1243212510 }),
1243312511 }
1243412512}
......@@ -12459,11 +12537,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1245912537 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1246012538 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1246112539 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);
1246412540 const target = sema.mod.getTarget();
12465 const abi_align = resolved_ty.abiAlignment(target);
12466 return sema.addIntUnsigned(Type.comptime_int, abi_align);
12541 return sema.addConstant(
12542 Type.comptime_int,
12543 try ty.lazyAbiAlignment(target, sema.arena),
12544 );
1246712545}
1246812546
1246912547fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -12509,6 +12587,7 @@ fn zirUnaryMath(
1250912587 const operand = sema.resolveInst(inst_data.operand);
1251012588 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1251112589 const operand_ty = sema.typeOf(operand);
12590 const target = sema.mod.getTarget();
1251212591
1251312592 switch (operand_ty.zigTypeTag()) {
1251412593 .ComptimeFloat, .Float => {},
......@@ -12516,13 +12595,12 @@ fn zirUnaryMath(
1251612595 const scalar_ty = operand_ty.scalarType();
1251712596 switch (scalar_ty.zigTypeTag()) {
1251812597 .ComptimeFloat, .Float => {},
12519 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty}),
12598 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(target)}),
1252012599 }
1252112600 },
12522 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty}),
12601 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(target)}),
1252312602 }
1252412603
12525 const target = sema.mod.getTarget();
1252612604 switch (operand_ty.zigTypeTag()) {
1252712605 .Vector => {
1252812606 const scalar_ty = operand_ty.scalarType();
......@@ -12568,6 +12646,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1256812646 const src = inst_data.src();
1256912647 const operand = sema.resolveInst(inst_data.operand);
1257012648 const operand_ty = sema.typeOf(operand);
12649 const target = sema.mod.getTarget();
1257112650
1257212651 try sema.resolveTypeLayout(block, operand_src, operand_ty);
1257312652 const enum_ty = switch (operand_ty.zigTypeTag()) {
......@@ -12590,13 +12669,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1259012669 return sema.failWithOwnedErrorMsg(block, msg);
1259112670 },
1259212671 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{
12593 operand_ty,
12672 operand_ty.fmt(target),
1259412673 }),
1259512674 };
1259612675 const enum_decl = enum_ty.getOwnerDecl();
1259712676 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
1259812677 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
12599 const field_index = enum_ty.enumTagFieldIndex(val) orelse {
12678 const field_index = enum_ty.enumTagFieldIndex(val, target) orelse {
1260012679 const msg = msg: {
1260112680 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{
1260212681 casted_operand, enum_decl.name,
......@@ -12626,8 +12705,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1262612705 const val = try sema.resolveConstValue(block, operand_src, type_info);
1262712706 const union_val = val.cast(Value.Payload.Union).?.data;
1262812707 const tag_ty = type_info_ty.unionTagType().?;
12629 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag).?;
1263012708 const target = sema.mod.getTarget();
12709 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, target).?;
1263112710 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1263212711 .Type => return Air.Inst.Ref.type_type,
1263312712 .Void => return Air.Inst.Ref.void_type,
......@@ -12646,7 +12725,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1264612725 const bits_val = struct_val[1];
1264712726
1264812727 const signedness = signedness_val.toEnum(std.builtin.Signedness);
12649 const bits = @intCast(u16, bits_val.toUnsignedInt());
12728 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
1265012729 const ty = switch (signedness) {
1265112730 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
1265212731 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
......@@ -12659,7 +12738,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1265912738 const len_val = struct_val[0];
1266012739 const child_val = struct_val[1];
1266112740
12662 const len = len_val.toUnsignedInt();
12741 const len = len_val.toUnsignedInt(target);
1266312742 var buffer: Value.ToTypeBuffer = undefined;
1266412743 const child_ty = child_val.toType(&buffer);
1266512744
......@@ -12672,7 +12751,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1267212751 // bits: comptime_int,
1267312752 const bits_val = struct_val[0];
1267412753
12675 const bits = @intCast(u16, bits_val.toUnsignedInt());
12754 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
1267612755 const ty = switch (bits) {
1267712756 16 => Type.@"f16",
1267812757 32 => Type.@"f32",
......@@ -12717,7 +12796,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1271712796 .size = ptr_size,
1271812797 .mutable = !is_const_val.toBool(),
1271912798 .@"volatile" = is_volatile_val.toBool(),
12720 .@"align" = @intCast(u16, alignment_val.toUnsignedInt()), // TODO: Validate this value.
12799 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
1272112800 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
1272212801 .pointee_type = try child_ty.copy(sema.arena),
1272312802 .@"allowzero" = is_allowzero_val.toBool(),
......@@ -12735,7 +12814,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1273512814 // sentinel: ?*const anyopaque,
1273612815 const sentinel_val = struct_val[2];
1273712816
12738 const len = len_val.toUnsignedInt();
12817 const len = len_val.toUnsignedInt(target);
1273912818 var buffer: Value.ToTypeBuffer = undefined;
1274012819 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
1274112820 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
......@@ -12746,7 +12825,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1274612825 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
1274712826 } else null;
1274812827
12749 const ty = try Type.array(sema.arena, len, sentinel, child_ty);
12828 const ty = try Type.array(sema.arena, len, sentinel, child_ty, target);
1275012829 return sema.addType(ty);
1275112830 },
1275212831 .Optional => {
......@@ -12796,7 +12875,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1279612875 const name_val = struct_val[0];
1279712876
1279812877 names.putAssumeCapacityNoClobber(
12799 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
12878 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
1280012879 {},
1280112880 );
1280212881 }
......@@ -12817,7 +12896,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1281712896 const is_tuple_val = struct_val[3];
1281812897
1281912898 // Decls
12820 if (decls_val.sliceLen() > 0) {
12899 if (decls_val.sliceLen(target) > 0) {
1282112900 return sema.fail(block, src, "reified structs must have no decls", .{});
1282212901 }
1282312902
......@@ -12847,7 +12926,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1284712926 }
1284812927
1284912928 // Decls
12850 if (decls_val.sliceLen() > 0) {
12929 if (decls_val.sliceLen(target) > 0) {
1285112930 return sema.fail(block, src, "reified enums must have no decls", .{});
1285212931 }
1285312932
......@@ -12898,11 +12977,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1289812977 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1289912978
1290012979 // Fields
12901 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
12980 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1290212981 if (fields_len > 0) {
1290312982 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1290412983 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
1290512984 .ty = enum_obj.tag_ty,
12985 .target = target,
1290612986 });
1290712987
1290812988 var i: usize = 0;
......@@ -12918,6 +12998,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1291812998 const field_name = try name_val.toAllocatedBytes(
1291912999 Type.initTag(.const_slice_u8),
1292013000 new_decl_arena_allocator,
13001 target,
1292113002 );
1292213003
1292313004 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -12929,6 +13010,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1292913010 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
1293013011 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
1293113012 .ty = enum_obj.tag_ty,
13013 .target = target,
1293213014 });
1293313015 }
1293413016 }
......@@ -12942,7 +13024,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1294213024 const decls_val = struct_val[0];
1294313025
1294413026 // Decls
12945 if (decls_val.sliceLen() > 0) {
13027 if (decls_val.sliceLen(target) > 0) {
1294613028 return sema.fail(block, src, "reified opaque must have no decls", .{});
1294713029 }
1294813030
......@@ -12993,7 +13075,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1299313075 const decls_val = struct_val[3];
1299413076
1299513077 // Decls
12996 if (decls_val.sliceLen() > 0) {
13078 if (decls_val.sliceLen(target) > 0) {
1299713079 return sema.fail(block, src, "reified unions must have no decls", .{});
1299813080 }
1299913081
......@@ -13033,7 +13115,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1303313115 };
1303413116
1303513117 // Tag type
13036 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13118 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1303713119 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
1303813120 var buffer: Value.ToTypeBuffer = undefined;
1303913121 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
......@@ -13058,6 +13140,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1305813140 const field_name = try name_val.toAllocatedBytes(
1305913141 Type.initTag(.const_slice_u8),
1306013142 new_decl_arena_allocator,
13143 target,
1306113144 );
1306213145
1306313146 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -13069,7 +13152,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
1306913152 var buffer: Value.ToTypeBuffer = undefined;
1307013153 gop.value_ptr.* = .{
1307113154 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13072 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),
13155 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
1307313156 };
1307413157 }
1307513158 }
......@@ -13089,7 +13172,9 @@ fn reifyTuple(
1308913172 src: LazySrcLoc,
1309013173 fields_val: Value,
1309113174) CompileError!Air.Inst.Ref {
13092 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13175 const target = sema.mod.getTarget();
13176
13177 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1309313178 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));
1309413179
1309513180 const types = try sema.arena.alloc(Type, fields_len);
......@@ -13114,6 +13199,7 @@ fn reifyTuple(
1311413199 const field_name = try name_val.toAllocatedBytes(
1311513200 Type.initTag(.const_slice_u8),
1311613201 sema.arena,
13202 target,
1311713203 );
1311813204
1311913205 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
......@@ -13197,8 +13283,10 @@ fn reifyStruct(
1319713283 },
1319813284 };
1319913285
13286 const target = sema.mod.getTarget();
13287
1320013288 // Fields
13201 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());
13289 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
1320213290 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
1320313291 var i: usize = 0;
1320413292 while (i < fields_len) : (i += 1) {
......@@ -13219,6 +13307,7 @@ fn reifyStruct(
1321913307 const field_name = try name_val.toAllocatedBytes(
1322013308 Type.initTag(.const_slice_u8),
1322113309 new_decl_arena_allocator,
13310 target,
1322213311 );
1322313312
1322413313 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
......@@ -13238,7 +13327,7 @@ fn reifyStruct(
1323813327 var buffer: Value.ToTypeBuffer = undefined;
1323913328 gop.value_ptr.* = .{
1324013329 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13241 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),
13330 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
1324213331 .default_val = default_val,
1324313332 .is_comptime = is_comptime_val.toBool(),
1324413333 .offset = undefined,
......@@ -13257,7 +13346,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1325713346 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
1325813347 defer anon_decl.deinit();
1325913348
13260 const bytes = try ty.nameAllocArena(anon_decl.arena());
13349 const target = sema.mod.getTarget();
13350 const bytes = try ty.nameAllocArena(anon_decl.arena(), target);
1326113351
1326213352 const new_decl = try anon_decl.finish(
1326313353 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
......@@ -13296,7 +13386,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1329613386 const target = sema.mod.getTarget();
1329713387 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {
1329813388 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 });
13389 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{
13390 std.math.floor(val.toFloat(f64)),
13391 dest_ty.fmt(target),
13392 });
1330013393 },
1330113394 else => |e| return e,
1330213395 };
......@@ -13344,13 +13437,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1334413437 try sema.checkPtrType(block, type_src, type_res);
1334513438 try sema.resolveTypeLayout(block, src, type_res.elemType2());
1334613439 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
13440 const target = sema.mod.getTarget();
1334713441
1334813442 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
13349 const addr = val.toUnsignedInt();
13443 const addr = val.toUnsignedInt(target);
1335013444 if (!type_res.isAllowzeroPtr() and addr == 0)
13351 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res});
13445 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(target)});
1335213446 if (addr != 0 and addr % ptr_align != 0)
13353 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res});
13447 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(target)});
1335413448
1335513449 const val_payload = try sema.arena.create(Value.Payload.U64);
1335613450 val_payload.* = .{
......@@ -13394,6 +13488,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1339413488 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
1339513489 const operand = sema.resolveInst(extra.rhs);
1339613490 const operand_ty = sema.typeOf(operand);
13491 const target = sema.mod.getTarget();
1339713492 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
1339813493 try sema.checkErrorSetType(block, operand_src, operand_ty);
1339913494
......@@ -13407,7 +13502,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1340713502 block,
1340813503 src,
1340913504 "error.{s} not a member of error set '{}'",
13410 .{ error_name, dest_ty },
13505 .{ error_name, dest_ty.fmt(target) },
1341113506 );
1341213507 }
1341313508 }
......@@ -13502,7 +13597,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1350213597
1350313598 if (operand_info.signedness != dest_info.signedness) {
1350413599 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
13505 @tagName(dest_info.signedness), operand_ty,
13600 @tagName(dest_info.signedness), operand_ty.fmt(target),
1350613601 });
1350713602 }
1350813603 if (operand_info.bits < dest_info.bits) {
......@@ -13511,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1351113606 block,
1351213607 src,
1351313608 "destination type '{}' has more bits than source type '{}'",
13514 .{ dest_ty, operand_ty },
13609 .{ dest_ty.fmt(target), operand_ty.fmt(target) },
1351513610 );
1351613611 errdefer msg.destroy(sema.gpa);
1351713612 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
......@@ -13531,14 +13626,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1353113626 if (!is_vector) {
1353213627 return sema.addConstant(
1353313628 dest_ty,
13534 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits),
13629 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, target),
1353513630 );
1353613631 }
1353713632 var elem_buf: Value.ElemValueBuffer = undefined;
1353813633 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
1353913634 for (elems) |*elem, i| {
1354013635 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);
13636 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);
1354213637 }
1354313638 return sema.addConstant(
1354413639 dest_ty,
......@@ -13653,7 +13748,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1365313748 block,
1365413749 ty_src,
1365513750 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
13656 .{ scalar_ty, bits },
13751 .{ scalar_ty.fmt(target), bits },
1365713752 );
1365813753 }
1365913754
......@@ -13765,6 +13860,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1376513860
1376613861 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
1376713862 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
13863 const target = sema.mod.getTarget();
1376813864
1376913865 try sema.resolveTypeLayout(block, lhs_src, ty);
1377013866 if (ty.tag() != .@"struct") {
......@@ -13772,7 +13868,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1377213868 block,
1377313869 lhs_src,
1377413870 "expected struct type, found '{}'",
13775 .{ty},
13871 .{ty.fmt(target)},
1377613872 );
1377713873 }
1377813874
......@@ -13782,11 +13878,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1378213878 block,
1378313879 rhs_src,
1378413880 "struct '{}' has no field '{s}'",
13785 .{ ty, field_name },
13881 .{ ty.fmt(target), field_name },
1378613882 );
1378713883 };
1378813884
13789 const target = sema.mod.getTarget();
1379013885 switch (ty.containerLayout()) {
1379113886 .Packed => {
1379213887 var bit_sum: u64 = 0;
......@@ -13809,18 +13904,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1380913904}
1381013905
1381113906fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
13907 const target = sema.mod.getTarget();
1381213908 switch (ty.zigTypeTag()) {
1381313909 .Struct, .Enum, .Union, .Opaque => return,
13814 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty}),
13910 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(target)}),
1381513911 }
1381613912}
1381713913
1381813914/// Returns `true` if the type was a comptime_int.
1381913915fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
13916 const target = sema.mod.getTarget();
1382013917 switch (try ty.zigTypeTagOrPoison()) {
1382113918 .ComptimeInt => return true,
1382213919 .Int => return false,
13823 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),
13920 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(target)}),
1382413921 }
1382513922}
1382613923
......@@ -13830,6 +13927,7 @@ fn checkPtrOperand(
1383013927 ty_src: LazySrcLoc,
1383113928 ty: Type,
1383213929) CompileError!void {
13930 const target = sema.mod.getTarget();
1383313931 switch (ty.zigTypeTag()) {
1383413932 .Pointer => return,
1383513933 .Fn => {
......@@ -13838,7 +13936,7 @@ fn checkPtrOperand(
1383813936 block,
1383913937 ty_src,
1384013938 "expected pointer, found {}",
13841 .{ty},
13939 .{ty.fmt(target)},
1384213940 );
1384313941 errdefer msg.destroy(sema.gpa);
1384413942
......@@ -13851,7 +13949,7 @@ fn checkPtrOperand(
1385113949 .Optional => if (ty.isPtrLikeOptional()) return,
1385213950 else => {},
1385313951 }
13854 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
13952 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
1385513953}
1385613954
1385713955fn checkPtrType(
......@@ -13860,6 +13958,7 @@ fn checkPtrType(
1386013958 ty_src: LazySrcLoc,
1386113959 ty: Type,
1386213960) CompileError!void {
13961 const target = sema.mod.getTarget();
1386313962 switch (ty.zigTypeTag()) {
1386413963 .Pointer => return,
1386513964 .Fn => {
......@@ -13868,7 +13967,7 @@ fn checkPtrType(
1386813967 block,
1386913968 ty_src,
1387013969 "expected pointer type, found '{}'",
13871 .{ty},
13970 .{ty.fmt(target)},
1387213971 );
1387313972 errdefer msg.destroy(sema.gpa);
1387413973
......@@ -13881,7 +13980,7 @@ fn checkPtrType(
1388113980 .Optional => if (ty.isPtrLikeOptional()) return,
1388213981 else => {},
1388313982 }
13884 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
13983 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
1388513984}
1388613985
1388713986fn checkVectorElemType(
......@@ -13894,7 +13993,8 @@ fn checkVectorElemType(
1389413993 .Int, .Float, .Bool => return,
1389513994 else => if (ty.isPtrAtRuntime()) return,
1389613995 }
13897 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty});
13996 const target = sema.mod.getTarget();
13997 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(target)});
1389813998}
1389913999
1390014000fn checkFloatType(
......@@ -13903,9 +14003,10 @@ fn checkFloatType(
1390314003 ty_src: LazySrcLoc,
1390414004 ty: Type,
1390514005) CompileError!void {
14006 const target = sema.mod.getTarget();
1390614007 switch (ty.zigTypeTag()) {
1390714008 .ComptimeInt, .ComptimeFloat, .Float => {},
13908 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty}),
14009 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(target)}),
1390914010 }
1391014011}
1391114012
......@@ -13915,13 +14016,14 @@ fn checkNumericType(
1391514016 ty_src: LazySrcLoc,
1391614017 ty: Type,
1391714018) CompileError!void {
14019 const target = sema.mod.getTarget();
1391814020 switch (ty.zigTypeTag()) {
1391914021 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
1392014022 .Vector => switch (ty.childType().zigTypeTag()) {
1392114023 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
1392214024 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
1392314025 },
13924 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty}),
14026 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(target)}),
1392514027 }
1392614028}
1392714029
......@@ -13957,7 +14059,7 @@ fn checkAtomicOperandType(
1395714059 block,
1395814060 ty_src,
1395914061 "expected bool, integer, float, enum, or pointer type; found {}",
13960 .{ty},
14062 .{ty.fmt(target)},
1396114063 );
1396214064 },
1396314065 };
......@@ -14021,6 +14123,7 @@ fn checkIntOrVector(
1402114123 operand_src: LazySrcLoc,
1402214124) CompileError!Type {
1402314125 const operand_ty = sema.typeOf(operand);
14126 const target = sema.mod.getTarget();
1402414127 switch (try operand_ty.zigTypeTagOrPoison()) {
1402514128 .Int => return operand_ty,
1402614129 .Vector => {
......@@ -14028,12 +14131,12 @@ fn checkIntOrVector(
1402814131 switch (try elem_ty.zigTypeTagOrPoison()) {
1402914132 .Int => return elem_ty,
1403014133 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14031 elem_ty,
14134 elem_ty.fmt(target),
1403214135 }),
1403314136 }
1403414137 },
1403514138 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14036 operand_ty,
14139 operand_ty.fmt(target),
1403714140 }),
1403814141 }
1403914142}
......@@ -14045,6 +14148,7 @@ fn checkIntOrVectorAllowComptime(
1404514148 operand_src: LazySrcLoc,
1404614149) CompileError!Type {
1404714150 const operand_ty = sema.typeOf(operand);
14151 const target = sema.mod.getTarget();
1404814152 switch (try operand_ty.zigTypeTagOrPoison()) {
1404914153 .Int, .ComptimeInt => return operand_ty,
1405014154 .Vector => {
......@@ -14052,20 +14156,21 @@ fn checkIntOrVectorAllowComptime(
1405214156 switch (try elem_ty.zigTypeTagOrPoison()) {
1405314157 .Int, .ComptimeInt => return elem_ty,
1405414158 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14055 elem_ty,
14159 elem_ty.fmt(target),
1405614160 }),
1405714161 }
1405814162 },
1405914163 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14060 operand_ty,
14164 operand_ty.fmt(target),
1406114165 }),
1406214166 }
1406314167}
1406414168
1406514169fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14170 const target = sema.mod.getTarget();
1406614171 switch (ty.zigTypeTag()) {
1406714172 .ErrorSet => return,
14068 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),
14173 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(target)}),
1406914174 }
1407014175}
1407114176
......@@ -14138,9 +14243,10 @@ fn checkVectorizableBinaryOperands(
1413814243 return sema.failWithOwnedErrorMsg(block, msg);
1413914244 }
1414014245 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
14246 const target = sema.mod.getTarget();
1414114247 const msg = msg: {
1414214248 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
14143 lhs_ty, rhs_ty,
14249 lhs_ty.fmt(target), rhs_ty.fmt(target),
1414414250 });
1414514251 errdefer msg.destroy(sema.gpa);
1414614252 if (lhs_zig_ty_tag == .Vector) {
......@@ -14179,8 +14285,9 @@ fn resolveExportOptions(
1417914285 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
1418014286 }
1418114287 const name_ty = Type.initTag(.const_slice_u8);
14288 const target = sema.mod.getTarget();
1418214289 return std.builtin.ExportOptions{
14183 .name = try name_val.toAllocatedBytes(name_ty, sema.arena),
14290 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, target),
1418414291 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
1418514292 .section = null, // TODO
1418614293 };
......@@ -14239,12 +14346,13 @@ fn zirCmpxchg(
1423914346 const ptr_ty = sema.typeOf(ptr);
1424014347 const elem_ty = ptr_ty.elemType();
1424114348 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
14349 const target = sema.mod.getTarget();
1424214350 if (elem_ty.zigTypeTag() == .Float) {
1424314351 return sema.fail(
1424414352 block,
1424514353 elem_ty_src,
1424614354 "expected bool, integer, enum, or pointer type; found '{}'",
14247 .{elem_ty},
14355 .{elem_ty.fmt(target)},
1424814356 );
1424914357 }
1425014358 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
......@@ -14281,7 +14389,7 @@ fn zirCmpxchg(
1428114389 return sema.addConstUndef(result_ty);
1428214390 }
1428314391 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: {
14392 const result_val = if (stored_val.eql(expected_val, elem_ty, target)) blk: {
1428514393 try sema.storePtr(block, src, ptr, new_value);
1428614394 break :blk Value.@"null";
1428714395 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
......@@ -14343,9 +14451,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1434314451 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");
1434414452 const operand = sema.resolveInst(extra.rhs);
1434514453 const operand_ty = sema.typeOf(operand);
14454 const target = sema.mod.getTarget();
1434614455
1434714456 if (operand_ty.zigTypeTag() != .Vector) {
14348 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty});
14457 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(target)});
1434914458 }
1435014459
1435114460 const scalar_ty = operand_ty.childType();
......@@ -14355,13 +14464,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1435514464 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
1435614465 .Int, .Bool => {},
1435714466 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{
14358 @tagName(operation), operand_ty,
14467 @tagName(operation), operand_ty.fmt(target),
1435914468 }),
1436014469 },
1436114470 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
1436214471 .Int, .Float => {},
1436314472 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{
14364 @tagName(operation), operand_ty,
14473 @tagName(operation), operand_ty.fmt(target),
1436514474 }),
1436614475 },
1436714476 }
......@@ -14376,18 +14485,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1437614485 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
1437714486 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
1437814487
14379 const target = sema.mod.getTarget();
1438014488 var accum: Value = try operand_val.elemValue(sema.arena, 0);
1438114489 var elem_buf: Value.ElemValueBuffer = undefined;
1438214490 var i: u32 = 1;
1438314491 while (i < vec_len) : (i += 1) {
1438414492 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);
1438514493 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),
14494 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),
14495 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),
14496 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target),
14497 .Min => accum = accum.numberMin(elem_val, target),
14498 .Max => accum = accum.numberMax(elem_val, target),
1439114499 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),
1439214500 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),
1439314501 }
......@@ -14417,10 +14525,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1441714525 var b = sema.resolveInst(extra.b);
1441814526 var mask = sema.resolveInst(extra.mask);
1441914527 var mask_ty = sema.typeOf(mask);
14528 const target = sema.mod.getTarget();
1442014529
1442114530 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
1442214531 .Array, .Vector => sema.typeOf(mask).arrayLen(),
14423 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask)}),
14532 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(target)}),
1442414533 };
1442514534 mask_ty = try Type.Tag.vector.create(sema.arena, .{
1442614535 .len = mask_len,
......@@ -14452,20 +14561,21 @@ fn analyzeShuffle(
1445214561 .elem_type = elem_ty,
1445314562 });
1445414563
14564 const target = sema.mod.getTarget();
1445514565 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
1445614566 .Array, .Vector => sema.typeOf(a).arrayLen(),
1445714567 .Undefined => null,
1445814568 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{
14459 elem_ty,
14460 sema.typeOf(a),
14569 elem_ty.fmt(target),
14570 sema.typeOf(a).fmt(target),
1446114571 }),
1446214572 };
1446314573 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
1446414574 .Array, .Vector => sema.typeOf(b).arrayLen(),
1446514575 .Undefined => null,
1446614576 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{
14467 elem_ty,
14468 sema.typeOf(b),
14577 elem_ty.fmt(target),
14578 sema.typeOf(b).fmt(target),
1446914579 }),
1447014580 };
1447114581 if (maybe_a_len == null and maybe_b_len == null) {
......@@ -14513,7 +14623,7 @@ fn analyzeShuffle(
1451314623
1451414624 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{
1451514625 unsigned,
14516 operand_info[chosen][2],
14626 operand_info[chosen][2].fmt(target),
1451714627 });
1451814628
1451914629 if (chosen == 1) {
......@@ -14704,12 +14814,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1470414814 .Xchg => operand_val,
1470514815 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),
1470614816 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),
14707 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena),
14817 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena, target),
1470814818 .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),
14819 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena, target),
14820 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena, target),
14821 .Max => stored_val.numberMax (operand_val, target),
14822 .Min => stored_val.numberMin (operand_val, target),
1471314823 // zig fmt: on
1471414824 };
1471514825 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);
......@@ -14788,7 +14898,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1478814898
1478914899 switch (ty.zigTypeTag()) {
1479014900 .ComptimeFloat, .Float, .Vector => {},
14791 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}),
14901 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(target)}),
1479214902 }
1479314903
1479414904 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
......@@ -14814,7 +14924,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1481414924 const scalar_ty = ty.scalarType();
1481514925 switch (scalar_ty.zigTypeTag()) {
1481614926 .ComptimeFloat, .Float => {},
14817 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty}),
14927 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty.fmt(target)}),
1481814928 }
1481914929
1482014930 const vec_len = ty.vectorLen();
......@@ -14906,9 +15016,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1490615016 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);
1490715017 };
1490815018
15019 const target = sema.mod.getTarget();
1490915020 const args_ty = sema.typeOf(args);
1491015021 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {
14911 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty});
15022 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(target)});
1491215023 }
1491315024
1491415025 var resolved_args: []Air.Inst.Ref = undefined;
......@@ -14945,9 +15056,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1494515056 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);
1494615057 const field_ptr = sema.resolveInst(extra.field_ptr);
1494715058 const field_ptr_ty = sema.typeOf(field_ptr);
15059 const target = sema.mod.getTarget();
1494815060
1494915061 if (struct_ty.zigTypeTag() != .Struct) {
14950 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty});
15062 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(target)});
1495115063 }
1495215064 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1495315065
......@@ -14956,7 +15068,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1495615068 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
1495715069
1495815070 if (field_ptr_ty.zigTypeTag() != .Pointer) {
14959 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty});
15071 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(target)});
1496015072 }
1496115073 const field = struct_obj.fields.values()[field_index];
1496215074 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
......@@ -14973,7 +15085,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
1497315085 ptr_ty_data.@"align" = field.abi_align;
1497415086 }
1497515087
14976 const target = sema.mod.getTarget();
1497715088 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1497815089 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
1497915090
......@@ -15042,8 +15153,9 @@ fn analyzeMinMax(
1504215153 .max => Value.numberMax,
1504315154 else => unreachable,
1504415155 };
15156 const target = sema.mod.getTarget();
1504515157 const vec_len = simd_op.len orelse {
15046 const result_val = opFunc(lhs_val, rhs_val);
15158 const result_val = opFunc(lhs_val, rhs_val, target);
1504715159 return sema.addConstant(simd_op.result_ty, result_val);
1504815160 };
1504915161 var lhs_buf: Value.ElemValueBuffer = undefined;
......@@ -15052,7 +15164,7 @@ fn analyzeMinMax(
1505215164 for (elems) |*elem, i| {
1505315165 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);
1505415166 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);
15055 elem.* = opFunc(lhs_elem_val, rhs_elem_val);
15167 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
1505615168 }
1505715169 return sema.addConstant(
1505815170 simd_op.result_ty,
......@@ -15078,17 +15190,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1507815190 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1507915191 const dest_ptr = sema.resolveInst(extra.dest);
1508015192 const dest_ptr_ty = sema.typeOf(dest_ptr);
15193 const target = sema.mod.getTarget();
1508115194
1508215195 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
1508315196 if (dest_ptr_ty.isConstPtr()) {
15084 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});
15197 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
1508515198 }
1508615199
1508715200 const uncasted_src_ptr = sema.resolveInst(extra.source);
1508815201 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);
1508915202 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);
1509015203 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
15091 const target = sema.mod.getTarget();
1509215204 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{
1509315205 .pointee_type = dest_ptr_ty.elemType2(),
1509415206 .@"align" = src_ptr_info.@"align",
......@@ -15136,9 +15248,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
1513615248 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1513715249 const dest_ptr = sema.resolveInst(extra.dest);
1513815250 const dest_ptr_ty = sema.typeOf(dest_ptr);
15251 const target = sema.mod.getTarget();
1513915252 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
1514015253 if (dest_ptr_ty.isConstPtr()) {
15141 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});
15254 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
1514215255 }
1514315256 const elem_ty = dest_ptr_ty.elemType2();
1514415257 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);
......@@ -15452,6 +15565,7 @@ fn zirPrefetch(
1545215565 const ptr = sema.resolveInst(extra.lhs);
1545315566 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
1545415567 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);
15568 const target = sema.mod.getTarget();
1545515569
1545615570 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
1545715571 const rw_val = try sema.resolveConstValue(block, opts_src, rw);
......@@ -15459,7 +15573,7 @@ fn zirPrefetch(
1545915573
1546015574 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
1546115575 const locality_val = try sema.resolveConstValue(block, opts_src, locality);
15462 const locality_int = @intCast(u2, locality_val.toUnsignedInt());
15576 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1546315577
1546415578 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
1546515579 const cache_val = try sema.resolveConstValue(block, opts_src, cache);
......@@ -15492,6 +15606,7 @@ fn zirBuiltinExtern(
1549215606
1549315607 var ty = try sema.resolveType(block, ty_src, extra.lhs);
1549415608 const options_inst = sema.resolveInst(extra.rhs);
15609 const target = sema.mod.getTarget();
1549515610
1549615611 const options = options: {
1549715612 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");
......@@ -15512,11 +15627,11 @@ fn zirBuiltinExtern(
1551215627 var library_name: ?[]const u8 = null;
1551315628 if (!library_name_val.isNull()) {
1551415629 const payload = library_name_val.castTag(.opt_payload).?.data;
15515 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena);
15630 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);
1551615631 }
1551715632
1551815633 break :options std.builtin.ExternOptions{
15519 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
15634 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
1552015635 .library_name = library_name,
1552115636 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
1552215637 .is_thread_local = is_thread_local_val.toBool(),
......@@ -15609,8 +15724,9 @@ fn validateVarType(
1560915724) CompileError!void {
1561015725 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
1561115726
15727 const target = sema.mod.getTarget();
1561215728 const msg = msg: {
15613 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty});
15729 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(target)});
1561415730 errdefer msg.destroy(sema.gpa);
1561515731
1561615732 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);
......@@ -15685,6 +15801,7 @@ fn explainWhyTypeIsComptime(
1568515801 ty: Type,
1568615802) CompileError!void {
1568715803 const mod = sema.mod;
15804 const target = mod.getTarget();
1568815805 switch (ty.zigTypeTag()) {
1568915806 .Bool,
1569015807 .Int,
......@@ -15698,7 +15815,7 @@ fn explainWhyTypeIsComptime(
1569815815
1569915816 .Fn => {
1570015817 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
15701 ty,
15818 ty.fmt(target),
1570215819 });
1570315820 },
1570415821
......@@ -15941,6 +16058,8 @@ fn fieldVal(
1594116058 else
1594216059 object_ty;
1594316060
16061 const target = sema.mod.getTarget();
16062
1594416063 switch (inner_ty.zigTypeTag()) {
1594516064 .Array => {
1594616065 if (mem.eql(u8, field_name, "len")) {
......@@ -15953,7 +16072,7 @@ fn fieldVal(
1595316072 block,
1595416073 field_name_src,
1595516074 "no member named '{s}' in '{}'",
15956 .{ field_name, object_ty },
16075 .{ field_name, object_ty.fmt(target) },
1595716076 );
1595816077 }
1595916078 },
......@@ -15977,7 +16096,7 @@ fn fieldVal(
1597716096 block,
1597816097 field_name_src,
1597916098 "no member named '{s}' in '{}'",
15980 .{ field_name, object_ty },
16099 .{ field_name, object_ty.fmt(target) },
1598116100 );
1598216101 }
1598316102 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
......@@ -15991,7 +16110,7 @@ fn fieldVal(
1599116110 block,
1599216111 field_name_src,
1599316112 "no member named '{s}' in '{}'",
15994 .{ field_name, ptr_info.pointee_type },
16113 .{ field_name, ptr_info.pointee_type.fmt(target) },
1599516114 );
1599616115 }
1599716116 }
......@@ -16013,7 +16132,7 @@ fn fieldVal(
1601316132 break :blk entry.key_ptr.*;
1601416133 }
1601516134 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16016 field_name, child_type,
16135 field_name, child_type.fmt(target),
1601716136 });
1601816137 } else (try sema.mod.getErrorValue(field_name)).key;
1601916138
......@@ -16067,10 +16186,10 @@ fn fieldVal(
1606716186 else => unreachable,
1606816187 };
1606916188 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{
16070 kw_name, child_type, field_name,
16189 kw_name, child_type.fmt(target), field_name,
1607116190 });
1607216191 },
16073 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),
16192 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
1607416193 }
1607516194 },
1607616195 .Struct => if (is_pointer_to) {
......@@ -16089,7 +16208,7 @@ fn fieldVal(
1608916208 },
1609016209 else => {},
1609116210 }
16092 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty});
16211 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(target)});
1609316212}
1609416213
1609516214fn fieldPtr(
......@@ -16103,11 +16222,12 @@ fn fieldPtr(
1610316222 // When editing this function, note that there is corresponding logic to be edited
1610416223 // in `fieldVal`. This function takes a pointer and returns a pointer.
1610516224
16225 const target = sema.mod.getTarget();
1610616226 const object_ptr_src = src; // TODO better source location
1610716227 const object_ptr_ty = sema.typeOf(object_ptr);
1610816228 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
1610916229 .Pointer => object_ptr_ty.elemType(),
16110 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}),
16230 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(target)}),
1611116231 };
1611216232
1611316233 // Zig allows dereferencing a single pointer during field lookup. Note that
......@@ -16120,8 +16240,6 @@ fn fieldPtr(
1612016240 else
1612116241 object_ty;
1612216242
16123 const target = sema.mod.getTarget();
16124
1612516243 switch (inner_ty.zigTypeTag()) {
1612616244 .Array => {
1612716245 if (mem.eql(u8, field_name, "len")) {
......@@ -16137,7 +16255,7 @@ fn fieldPtr(
1613716255 block,
1613816256 field_name_src,
1613916257 "no member named '{s}' in '{}'",
16140 .{ field_name, object_ty },
16258 .{ field_name, object_ty.fmt(target) },
1614116259 );
1614216260 }
1614316261 },
......@@ -16177,7 +16295,7 @@ fn fieldPtr(
1617716295
1617816296 return sema.analyzeDeclRef(try anon_decl.finish(
1617916297 Type.usize,
16180 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),
16298 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(target)),
1618116299 0, // default alignment
1618216300 ));
1618316301 }
......@@ -16195,7 +16313,7 @@ fn fieldPtr(
1619516313 block,
1619616314 field_name_src,
1619716315 "no member named '{s}' in '{}'",
16198 .{ field_name, object_ty },
16316 .{ field_name, object_ty.fmt(target) },
1619916317 );
1620016318 }
1620116319 },
......@@ -16219,7 +16337,7 @@ fn fieldPtr(
1621916337 break :blk entry.key_ptr.*;
1622016338 }
1622116339 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16222 field_name, child_type,
16340 field_name, child_type.fmt(target),
1622316341 });
1622416342 } else (try sema.mod.getErrorValue(field_name)).key;
1622516343
......@@ -16277,7 +16395,7 @@ fn fieldPtr(
1627716395 }
1627816396 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
1627916397 },
16280 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),
16398 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
1628116399 }
1628216400 },
1628316401 .Struct => {
......@@ -16296,7 +16414,7 @@ fn fieldPtr(
1629616414 },
1629716415 else => {},
1629816416 }
16299 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty, object_ptr_ty, field_name });
16417 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(target), object_ptr_ty.fmt(target), field_name });
1630016418}
1630116419
1630216420fn fieldCallBind(
......@@ -16310,12 +16428,13 @@ fn fieldCallBind(
1631016428 // When editing this function, note that there is corresponding logic to be edited
1631116429 // in `fieldVal`. This function takes a pointer and returns a pointer.
1631216430
16431 const target = sema.mod.getTarget();
1631316432 const raw_ptr_src = src; // TODO better source location
1631416433 const raw_ptr_ty = sema.typeOf(raw_ptr);
1631516434 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)
1631616435 raw_ptr_ty.childType()
1631716436 else
16318 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty});
16437 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(target)});
1631916438
1632016439 // Optionally dereference a second pointer to get the concrete type.
1632116440 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
......@@ -16375,7 +16494,7 @@ fn fieldCallBind(
1637516494 first_param_type.zigTypeTag() == .Pointer and
1637616495 (first_param_type.ptrSize() == .One or
1637716496 first_param_type.ptrSize() == .C) and
16378 first_param_type.childType().eql(concrete_ty)))
16497 first_param_type.childType().eql(concrete_ty, target)))
1637916498 {
1638016499 // zig fmt: on
1638116500 // TODO: bound fn calls on rvalues should probably
......@@ -16386,7 +16505,7 @@ fn fieldCallBind(
1638616505 .arg0_inst = object_ptr,
1638716506 });
1638816507 return sema.addConstant(ty, value);
16389 } else if (first_param_type.eql(concrete_ty)) {
16508 } else if (first_param_type.eql(concrete_ty, target)) {
1639016509 var deref = try sema.analyzeLoad(block, src, object_ptr, src);
1639116510 const ty = Type.Tag.bound_fn.init();
1639216511 const value = try Value.Tag.bound_fn.create(arena, .{
......@@ -16402,7 +16521,7 @@ fn fieldCallBind(
1640216521 else => {},
1640316522 }
1640416523
16405 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name });
16524 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(target), field_name });
1640616525}
1640716526
1640816527fn finishFieldCallBind(
......@@ -16540,10 +16659,11 @@ fn structFieldPtrByIndex(
1654016659 .@"addrspace" = struct_ptr_ty_info.@"addrspace",
1654116660 };
1654216661
16662 const target = sema.mod.getTarget();
16663
1654316664 // TODO handle when the struct pointer is overaligned, we should return a potentially
1654416665 // over-aligned field pointer too.
1654516666 if (struct_obj.layout == .Packed) {
16546 const target = sema.mod.getTarget();
1654716667 comptime assert(Type.packed_struct_layout_version == 2);
1654816668
1654916669 var running_bits: u16 = 0;
......@@ -16567,7 +16687,6 @@ fn structFieldPtrByIndex(
1656716687 ptr_ty_data.@"align" = field.abi_align;
1656816688 }
1656916689
16570 const target = sema.mod.getTarget();
1657116690 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1657216691
1657316692 if (field.is_comptime) {
......@@ -16667,14 +16786,15 @@ fn tupleFieldIndex(
1666716786 field_name: []const u8,
1666816787 field_name_src: LazySrcLoc,
1666916788) CompileError!u32 {
16789 const target = sema.mod.getTarget();
1667016790 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
1667116791 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
16672 tuple_ty, field_name, @errorName(err),
16792 tuple_ty.fmt(target), field_name, @errorName(err),
1667316793 });
1667416794 };
1667516795 if (field_index >= tuple_ty.structFieldCount()) {
1667616796 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{
16677 tuple_ty, field_name,
16797 tuple_ty.fmt(target), field_name,
1667816798 });
1667916799 }
1668016800 return field_index;
......@@ -16749,7 +16869,7 @@ fn unionFieldPtr(
1674916869 // .data = field_index,
1675016870 //};
1675116871 //const field_tag = Value.initPayload(&field_tag_buf.base);
16752 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
16872 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
1675316873 //if (!tag_matches) {
1675416874 // // TODO enhance this saying which one was active
1675516875 // // and which one was accessed, and showing where the union was declared.
......@@ -16798,7 +16918,8 @@ fn unionFieldVal(
1679816918 .data = field_index,
1679916919 };
1680016920 const field_tag = Value.initPayload(&field_tag_buf.base);
16801 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
16921 const target = sema.mod.getTarget();
16922 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
1680216923 switch (union_obj.layout) {
1680316924 .Auto => {
1680416925 if (tag_matches) {
......@@ -16813,7 +16934,7 @@ fn unionFieldVal(
1681316934 if (tag_matches) {
1681416935 return sema.addConstant(field.ty, tag_and_val.val);
1681516936 } else {
16816 const old_ty = union_ty.unionFieldType(tag_and_val.tag);
16937 const old_ty = union_ty.unionFieldType(tag_and_val.tag, target);
1681716938 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
1681816939 return sema.addConstant(field.ty, new_val);
1681916940 }
......@@ -16835,19 +16956,19 @@ fn elemPtr(
1683516956) CompileError!Air.Inst.Ref {
1683616957 const indexable_ptr_src = src; // TODO better source location
1683716958 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
16959 const target = sema.mod.getTarget();
1683816960 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
1683916961 .Pointer => indexable_ptr_ty.elemType(),
16840 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty}),
16962 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(target)}),
1684116963 };
1684216964 if (!indexable_ty.isIndexable()) {
16843 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});
16965 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
1684416966 }
1684516967
1684616968 switch (indexable_ty.zigTypeTag()) {
1684716969 .Pointer => {
1684816970 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
1684916971 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
16850 const target = sema.mod.getTarget();
1685116972 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);
1685216973 switch (indexable_ty.ptrSize()) {
1685316974 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),
......@@ -16858,8 +16979,8 @@ fn elemPtr(
1685816979 const runtime_src = rs: {
1685916980 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;
1686016981 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);
16982 const index = @intCast(usize, index_val.toUnsignedInt(target));
16983 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, target);
1686316984 return sema.addConstant(result_ty, elem_ptr);
1686416985 };
1686516986
......@@ -16876,7 +16997,7 @@ fn elemPtr(
1687616997 .Struct => {
1687716998 // Tuple field access.
1687816999 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16879 const index = @intCast(u32, index_val.toUnsignedInt());
17000 const index = @intCast(u32, index_val.toUnsignedInt(target));
1688017001 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
1688117002 },
1688217003 else => unreachable,
......@@ -16893,9 +17014,10 @@ fn elemVal(
1689317014) CompileError!Air.Inst.Ref {
1689417015 const indexable_src = src; // TODO better source location
1689517016 const indexable_ty = sema.typeOf(indexable);
17017 const target = sema.mod.getTarget();
1689617018
1689717019 if (!indexable_ty.isIndexable()) {
16898 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});
17020 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
1689917021 }
1690017022
1690117023 // TODO in case of a vector of pointers, we need to detect whether the element
......@@ -16912,7 +17034,7 @@ fn elemVal(
1691217034 const runtime_src = rs: {
1691317035 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
1691417036 const index_val = maybe_index_val orelse break :rs elem_index_src;
16915 const index = @intCast(usize, index_val.toUnsignedInt());
17037 const index = @intCast(usize, index_val.toUnsignedInt(target));
1691617038 const elem_ty = indexable_ty.elemType2();
1691717039
1691817040 var payload: Value.Payload.ElemPtr = .{ .data = .{
......@@ -16945,7 +17067,7 @@ fn elemVal(
1694517067 .Struct => {
1694617068 // Tuple field access.
1694717069 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16948 const index = @intCast(u32, index_val.toUnsignedInt());
17070 const index = @intCast(u32, index_val.toUnsignedInt(target));
1694917071 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
1695017072 },
1695117073 else => unreachable,
......@@ -17056,9 +17178,10 @@ fn elemValArray(
1705617178 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);
1705717179 // index must be defined since it can access out of bounds
1705817180 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17181 const target = sema.mod.getTarget();
1705917182
1706017183 if (maybe_index_val) |index_val| {
17061 const index = @intCast(usize, index_val.toUnsignedInt());
17184 const index = @intCast(usize, index_val.toUnsignedInt(target));
1706217185 if (index >= array_len_s) {
1706317186 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
1706417187 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -17069,7 +17192,7 @@ fn elemValArray(
1706917192 return sema.addConstUndef(elem_ty);
1707017193 }
1707117194 if (maybe_index_val) |index_val| {
17072 const index = @intCast(usize, index_val.toUnsignedInt());
17195 const index = @intCast(usize, index_val.toUnsignedInt(target));
1707317196 const elem_val = try array_val.elemValue(sema.arena, index);
1707417197 return sema.addConstant(elem_ty, elem_val);
1707517198 }
......@@ -17114,7 +17237,7 @@ fn elemPtrArray(
1711417237 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
1711517238
1711617239 if (maybe_index_val) |index_val| {
17117 const index = @intCast(usize, index_val.toUnsignedInt());
17240 const index = @intCast(usize, index_val.toUnsignedInt(target));
1711817241 if (index >= array_len_s) {
1711917242 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
1712017243 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -17125,8 +17248,8 @@ fn elemPtrArray(
1712517248 return sema.addConstUndef(elem_ptr_ty);
1712617249 }
1712717250 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);
17251 const index = @intCast(usize, index_val.toUnsignedInt(target));
17252 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, target);
1713017253 return sema.addConstant(elem_ptr_ty, elem_ptr);
1713117254 }
1713217255 }
......@@ -17162,16 +17285,17 @@ fn elemValSlice(
1716217285 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
1716317286 // index must be defined since it can index out of bounds
1716417287 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17288 const target = sema.mod.getTarget();
1716517289
1716617290 if (maybe_slice_val) |slice_val| {
1716717291 runtime_src = elem_index_src;
17168 const slice_len = slice_val.sliceLen();
17292 const slice_len = slice_val.sliceLen(target);
1716917293 const slice_len_s = slice_len + @boolToInt(slice_sent);
1717017294 if (slice_len_s == 0) {
1717117295 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
1717217296 }
1717317297 if (maybe_index_val) |index_val| {
17174 const index = @intCast(usize, index_val.toUnsignedInt());
17298 const index = @intCast(usize, index_val.toUnsignedInt(target));
1717517299 if (index >= slice_len_s) {
1717617300 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
1717717301 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
......@@ -17192,7 +17316,7 @@ fn elemValSlice(
1719217316 try sema.requireRuntimeBlock(block, runtime_src);
1719317317 if (block.wantSafety()) {
1719417318 const len_inst = if (maybe_slice_val) |slice_val|
17195 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen())
17319 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target))
1719617320 else
1719717321 try block.addTyOp(.slice_len, Type.usize, slice);
1719817322 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -17223,18 +17347,18 @@ fn elemPtrSlice(
1722317347 if (slice_val.isUndef()) {
1722417348 return sema.addConstUndef(elem_ptr_ty);
1722517349 }
17226 const slice_len = slice_val.sliceLen();
17350 const slice_len = slice_val.sliceLen(target);
1722717351 const slice_len_s = slice_len + @boolToInt(slice_sent);
1722817352 if (slice_len_s == 0) {
1722917353 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
1723017354 }
1723117355 if (maybe_index_val) |index_val| {
17232 const index = @intCast(usize, index_val.toUnsignedInt());
17356 const index = @intCast(usize, index_val.toUnsignedInt(target));
1723317357 if (index >= slice_len_s) {
1723417358 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
1723517359 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
1723617360 }
17237 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index);
17361 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);
1723817362 return sema.addConstant(elem_ptr_ty, elem_ptr_val);
1723917363 }
1724017364 }
......@@ -17245,7 +17369,7 @@ fn elemPtrSlice(
1724517369 const len_inst = len: {
1724617370 if (maybe_undef_slice_val) |slice_val|
1724717371 if (!slice_val.isUndef())
17248 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen());
17372 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
1724917373 break :len try block.addTyOp(.slice_len, Type.usize, slice);
1725017374 };
1725117375 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -17270,12 +17394,12 @@ fn coerce(
1727017394 const dest_ty_src = inst_src; // TODO better source location
1727117395 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);
1727217396 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));
17397 const target = sema.mod.getTarget();
1727317398 // If the types are the same, we can return the operand.
17274 if (dest_ty.eql(inst_ty))
17399 if (dest_ty.eql(inst_ty, target))
1727517400 return inst;
1727617401
1727717402 const arena = sema.arena;
17278 const target = sema.mod.getTarget();
1727917403 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);
1728017404
1728117405 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
......@@ -17379,7 +17503,7 @@ fn coerce(
1737917503 // *[N:s]T to [*]T
1738017504 if (dest_info.sentinel) |dst_sentinel| {
1738117505 if (array_ty.sentinel()) |src_sentinel| {
17382 if (src_sentinel.eql(dst_sentinel, dst_elem_type)) {
17506 if (src_sentinel.eql(dst_sentinel, dst_elem_type, target)) {
1738317507 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
1738417508 }
1738517509 }
......@@ -17448,7 +17572,7 @@ fn coerce(
1744817572 }
1744917573 if (inst_info.size == .Slice) {
1745017574 if (dest_info.sentinel == null or inst_info.sentinel == null or
17451 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))
17575 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
1745217576 break :p;
1745317577
1745417578 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -17515,7 +17639,7 @@ fn coerce(
1751517639 }
1751617640
1751717641 if (dest_info.sentinel == null or inst_info.sentinel == null or
17518 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))
17642 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
1751917643 break :p;
1752017644
1752117645 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -17528,11 +17652,11 @@ fn coerce(
1752817652 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
1752917653
1753017654 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 });
17655 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty, target), dest_ty.fmt(target) });
1753217656 }
1753317657 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {
1753417658 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 });
17659 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(target) });
1753617660 },
1753717661 else => |e| return e,
1753817662 };
......@@ -17542,7 +17666,7 @@ fn coerce(
1754217666 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
1754317667 // comptime known integer to other number
1754417668 if (!val.intFitsInType(dest_ty, target)) {
17545 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val.fmtValue(inst_ty) });
17669 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) });
1754617670 }
1754717671 return try sema.addConstant(dest_ty, val);
1754817672 }
......@@ -17572,12 +17696,12 @@ fn coerce(
1757217696 .Float => {
1757317697 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
1757417698 const result_val = try val.floatCast(sema.arena, dest_ty, target);
17575 if (!val.eql(result_val, dest_ty)) {
17699 if (!val.eql(result_val, dest_ty, target)) {
1757617700 return sema.fail(
1757717701 block,
1757817702 inst_src,
1757917703 "type {} cannot represent float value {}",
17580 .{ dest_ty, val.fmtValue(inst_ty) },
17704 .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) },
1758117705 );
1758217706 }
1758317707 return try sema.addConstant(dest_ty, result_val);
......@@ -17596,12 +17720,12 @@ fn coerce(
1759617720 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
1759717721 // TODO implement this compile error
1759817722 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
17599 //if (!int_again_val.eql(val, inst_ty)) {
17723 //if (!int_again_val.eql(val, inst_ty, target)) {
1760017724 // return sema.fail(
1760117725 // block,
1760217726 // inst_src,
1760317727 // "type {} cannot represent integer value {}",
17604 // .{ dest_ty, val },
17728 // .{ dest_ty.fmt(target), val },
1760517729 // );
1760617730 //}
1760717731 return try sema.addConstant(dest_ty, result_val);
......@@ -17622,7 +17746,7 @@ fn coerce(
1762217746 block,
1762317747 inst_src,
1762417748 "enum '{}' has no field named '{s}'",
17625 .{ dest_ty, bytes },
17749 .{ dest_ty.fmt(target), bytes },
1762617750 );
1762717751 errdefer msg.destroy(sema.gpa);
1762817752 try sema.mod.errNoteNonLazy(
......@@ -17643,7 +17767,7 @@ fn coerce(
1764317767 .Union => blk: {
1764417768 // union to its own tag type
1764517769 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;
17646 if (union_tag_ty.eql(dest_ty)) {
17770 if (union_tag_ty.eql(dest_ty, target)) {
1764717771 return sema.unionToTag(block, dest_ty, inst, inst_src);
1764817772 }
1764917773 },
......@@ -17743,7 +17867,7 @@ fn coerce(
1774317867 return sema.addConstUndef(dest_ty);
1774417868 }
1774517869
17746 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty });
17870 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(target), inst_ty.fmt(target) });
1774717871}
1774817872
1774917873const InMemoryCoercionResult = enum {
......@@ -17772,7 +17896,7 @@ fn coerceInMemoryAllowed(
1777217896 dest_src: LazySrcLoc,
1777317897 src_src: LazySrcLoc,
1777417898) CompileError!InMemoryCoercionResult {
17775 if (dest_ty.eql(src_ty))
17899 if (dest_ty.eql(src_ty, target))
1777617900 return .ok;
1777717901
1777817902 // Pointers / Pointer-like Optionals
......@@ -17823,7 +17947,7 @@ fn coerceInMemoryAllowed(
1782317947 }
1782417948 const ok_sent = dest_info.sentinel == null or
1782517949 (src_info.sentinel != null and
17826 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type));
17950 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, target));
1782717951 if (!ok_sent) {
1782817952 return .no_match;
1782917953 }
......@@ -18050,7 +18174,7 @@ fn coerceInMemoryAllowedPtrs(
1805018174
1805118175 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
1805218176 (src_info.sentinel != null and
18053 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type));
18177 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, target));
1805418178 if (!ok_sent) {
1805518179 return .no_match;
1805618180 }
......@@ -18091,7 +18215,7 @@ fn coerceInMemoryAllowedPtrs(
1809118215 // resolved and we compare the alignment numerically.
1809218216 alignment: {
1809318217 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
18094 dest_info.pointee_type.eql(src_info.pointee_type))
18218 dest_info.pointee_type.eql(src_info.pointee_type, target))
1809518219 {
1809618220 break :alignment;
1809718221 }
......@@ -18246,7 +18370,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
1824618370 // We have a pointer-to-array and a pointer-to-vector. If the elements and
1824718371 // lengths match, return the result.
1824818372 const vector_ty = sema.typeOf(prev_ptr).childType();
18249 if (array_ty.childType().eql(vector_ty.childType()) and
18373 const target = sema.mod.getTarget();
18374 if (array_ty.childType().eql(vector_ty.childType(), target) and
1825018375 array_ty.arrayLen() == vector_ty.vectorLen())
1825118376 {
1825218377 return prev_ptr;
......@@ -18668,10 +18793,10 @@ fn beginComptimePtrLoad(
1866818793 if (maybe_array_ty) |load_ty| {
1866918794 // It's possible that we're loading a [N]T, in which case we'd like to slice
1867018795 // the pointee array directly from our parent array.
18671 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty)) {
18796 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty, target)) {
1867218797 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
1867318798 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
18674 .ty = try Type.array(sema.arena, N, null, elem_ty),
18799 .ty = try Type.array(sema.arena, N, null, elem_ty, target),
1867518800 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),
1867618801 } else null;
1867718802 break :blk deref;
......@@ -18807,11 +18932,11 @@ pub fn bitCastVal(
1880718932 new_ty: Type,
1880818933 buffer_offset: usize,
1880918934) !Value {
18810 if (old_ty.eql(new_ty)) return val;
18935 const target = sema.mod.getTarget();
18936 if (old_ty.eql(new_ty, target)) return val;
1881118937
1881218938 // For types with well-defined memory layouts, we serialize them a byte buffer,
1881318939 // then deserialize to the new type.
18814 const target = sema.mod.getTarget();
1881518940 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
1881618941 const buffer = try sema.gpa.alloc(u8, abi_size);
1881718942 defer sema.gpa.free(buffer);
......@@ -18864,11 +18989,12 @@ fn coerceEnumToUnion(
1886418989 inst_src: LazySrcLoc,
1886518990) !Air.Inst.Ref {
1886618991 const inst_ty = sema.typeOf(inst);
18992 const target = sema.mod.getTarget();
1886718993
1886818994 const tag_ty = union_ty.unionTagType() orelse {
1886918995 const msg = msg: {
1887018996 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
18871 union_ty, inst_ty,
18997 union_ty.fmt(target), inst_ty.fmt(target),
1887218998 });
1887318999 errdefer msg.destroy(sema.gpa);
1887419000 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
......@@ -18881,10 +19007,10 @@ fn coerceEnumToUnion(
1888119007 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
1888219008 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
1888319009 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
18884 const field_index = union_obj.tag_ty.enumTagFieldIndex(val) orelse {
19010 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, target) orelse {
1888519011 const msg = msg: {
1888619012 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
18887 union_ty, val.fmtValue(tag_ty),
19013 union_ty.fmt(target), val.fmtValue(tag_ty, target),
1888819014 });
1888919015 errdefer msg.destroy(sema.gpa);
1889019016 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -18899,7 +19025,7 @@ fn coerceEnumToUnion(
1889919025 // also instead of 'union declared here' make it 'field "foo" declared here'.
1890019026 const msg = msg: {
1890119027 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{
18902 union_ty, field_ty,
19028 union_ty.fmt(target), field_ty.fmt(target),
1890319029 });
1890419030 errdefer msg.destroy(sema.gpa);
1890519031 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -18919,7 +19045,7 @@ fn coerceEnumToUnion(
1891919045 if (tag_ty.isNonexhaustiveEnum()) {
1892019046 const msg = msg: {
1892119047 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{
18922 union_ty,
19048 union_ty.fmt(target),
1892319049 });
1892419050 errdefer msg.destroy(sema.gpa);
1892519051 try sema.addDeclaredHereNote(msg, tag_ty);
......@@ -18937,7 +19063,7 @@ fn coerceEnumToUnion(
1893719063 // instead of the "union declared here" hint
1893819064 const msg = msg: {
1893919065 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{
18940 union_ty,
19066 union_ty.fmt(target),
1894119067 });
1894219068 errdefer msg.destroy(sema.gpa);
1894319069 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -19020,11 +19146,12 @@ fn coerceArrayLike(
1902019146 const inst_ty = sema.typeOf(inst);
1902119147 const inst_len = inst_ty.arrayLen();
1902219148 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19149 const target = sema.mod.getTarget();
1902319150
1902419151 if (dest_len != inst_len) {
1902519152 const msg = msg: {
1902619153 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19027 dest_ty, inst_ty,
19154 dest_ty.fmt(target), inst_ty.fmt(target),
1902819155 });
1902919156 errdefer msg.destroy(sema.gpa);
1903019157 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
......@@ -19034,7 +19161,6 @@ fn coerceArrayLike(
1903419161 return sema.failWithOwnedErrorMsg(block, msg);
1903519162 }
1903619163
19037 const target = sema.mod.getTarget();
1903819164 const dest_elem_ty = dest_ty.childType();
1903919165 const inst_elem_ty = inst_ty.childType();
1904019166 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);
......@@ -19092,11 +19218,12 @@ fn coerceTupleToArray(
1909219218 const inst_ty = sema.typeOf(inst);
1909319219 const inst_len = inst_ty.arrayLen();
1909419220 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19221 const target = sema.mod.getTarget();
1909519222
1909619223 if (dest_len != inst_len) {
1909719224 const msg = msg: {
1909819225 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19099 dest_ty, inst_ty,
19226 dest_ty.fmt(target), inst_ty.fmt(target),
1910019227 });
1910119228 errdefer msg.destroy(sema.gpa);
1910219229 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
......@@ -19149,7 +19276,8 @@ fn coerceTupleToSlicePtrs(
1914919276 const tuple_ty = sema.typeOf(ptr_tuple).childType();
1915019277 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
1915119278 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);
19279 const target = sema.mod.getTarget();
19280 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, target);
1915319281 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
1915419282 if (slice_info.@"align" != 0) {
1915519283 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
......@@ -19398,10 +19526,11 @@ fn analyzeLoad(
1939819526 ptr: Air.Inst.Ref,
1939919527 ptr_src: LazySrcLoc,
1940019528) CompileError!Air.Inst.Ref {
19529 const target = sema.mod.getTarget();
1940119530 const ptr_ty = sema.typeOf(ptr);
1940219531 const elem_ty = switch (ptr_ty.zigTypeTag()) {
1940319532 .Pointer => ptr_ty.childType(),
19404 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),
19533 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)}),
1940519534 };
1940619535 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
1940719536 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {
......@@ -19440,7 +19569,8 @@ fn analyzeSliceLen(
1944019569 if (slice_val.isUndef()) {
1944119570 return sema.addConstUndef(Type.usize);
1944219571 }
19443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen());
19572 const target = sema.mod.getTarget();
19573 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
1944419574 }
1944519575 try sema.requireRuntimeBlock(block, src);
1944619576 return block.addTyOp(.slice_len, Type.usize, slice_inst);
......@@ -19522,9 +19652,10 @@ fn analyzeSlice(
1952219652 // Slice expressions can operate on a variable whose type is an array. This requires
1952319653 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
1952419654 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
19655 const target = sema.mod.getTarget();
1952519656 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
1952619657 .Pointer => ptr_ptr_ty.elemType(),
19527 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty}),
19658 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(target)}),
1952819659 };
1952919660
1953019661 var array_ty = ptr_ptr_child_ty;
......@@ -19564,7 +19695,7 @@ fn analyzeSlice(
1956419695 elem_ty = ptr_ptr_child_ty.childType();
1956519696 },
1956619697 },
19567 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty}),
19698 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(target)}),
1956819699 }
1956919700
1957019701 const ptr = if (slice_ty.isSlice())
......@@ -19587,7 +19718,7 @@ fn analyzeSlice(
1958719718 if (!end_is_len) {
1958819719 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
1958919720 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {
19590 if (end_val.compare(.gt, len_val, Type.usize)) {
19721 if (end_val.compare(.gt, len_val, Type.usize, target)) {
1959119722 return sema.fail(
1959219723 block,
1959319724 end_src,
......@@ -19595,7 +19726,7 @@ fn analyzeSlice(
1959519726 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },
1959619727 );
1959719728 }
19598 if (end_val.eql(len_val, Type.usize)) {
19729 if (end_val.eql(len_val, Type.usize, target)) {
1959919730 end_is_len = true;
1960019731 }
1960119732 }
......@@ -19610,10 +19741,10 @@ fn analyzeSlice(
1961019741 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
1961119742 var int_payload: Value.Payload.U64 = .{
1961219743 .base = .{ .tag = .int_u64 },
19613 .data = slice_val.sliceLen(),
19744 .data = slice_val.sliceLen(target),
1961419745 };
1961519746 const slice_len_val = Value.initPayload(&int_payload.base);
19616 if (end_val.compare(.gt, slice_len_val, Type.usize)) {
19747 if (end_val.compare(.gt, slice_len_val, Type.usize, target)) {
1961719748 return sema.fail(
1961819749 block,
1961919750 end_src,
......@@ -19621,7 +19752,7 @@ fn analyzeSlice(
1962119752 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },
1962219753 );
1962319754 }
19624 if (end_val.eql(slice_len_val, Type.usize)) {
19755 if (end_val.eql(slice_len_val, Type.usize, target)) {
1962519756 end_is_len = true;
1962619757 }
1962719758 }
......@@ -19670,13 +19801,12 @@ fn analyzeSlice(
1967019801
1967119802 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;
1967219803 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
19673 const target = sema.mod.getTarget();
1967419804
1967519805 if (opt_new_len_val) |new_len_val| {
19676 const new_len_int = new_len_val.toUnsignedInt();
19806 const new_len_int = new_len_val.toUnsignedInt(target);
1967719807
1967819808 const return_ty = try Type.ptr(sema.arena, target, .{
19679 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty),
19809 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, target),
1968019810 .sentinel = null,
1968119811 .@"align" = new_ptr_ty_info.@"align",
1968219812 .@"addrspace" = new_ptr_ty_info.@"addrspace",
......@@ -19746,6 +19876,7 @@ fn cmpNumeric(
1974619876
1974719877 const lhs_ty_tag = lhs_ty.zigTypeTag();
1974819878 const rhs_ty_tag = rhs_ty.zigTypeTag();
19879 const target = sema.mod.getTarget();
1974919880
1975019881 const runtime_src: LazySrcLoc = src: {
1975119882 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
......@@ -19760,7 +19891,7 @@ fn cmpNumeric(
1976019891 return Air.Inst.Ref.bool_false;
1976119892 }
1976219893 }
19763 if (Value.compareHetero(lhs_val, op, rhs_val)) {
19894 if (Value.compareHetero(lhs_val, op, rhs_val, target)) {
1976419895 return Air.Inst.Ref.bool_true;
1976519896 } else {
1976619897 return Air.Inst.Ref.bool_false;
......@@ -19789,7 +19920,6 @@ fn cmpNumeric(
1978919920 .Float, .ComptimeFloat => true,
1979019921 else => false,
1979119922 };
19792 const target = sema.mod.getTarget();
1979319923 if (lhs_is_float and rhs_is_float) {
1979419924 // Implicit cast the smaller one to the larger one.
1979519925 const dest_ty = x: {
......@@ -19846,7 +19976,7 @@ fn cmpNumeric(
1984619976 }
1984719977 if (lhs_is_float) {
1984819978 var bigint_space: Value.BigIntSpace = undefined;
19849 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
19979 var bigint = try lhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
1985019980 defer bigint.deinit();
1985119981 if (lhs_val.floatHasFraction()) {
1985219982 switch (op) {
......@@ -19892,7 +20022,7 @@ fn cmpNumeric(
1989220022 }
1989320023 if (rhs_is_float) {
1989420024 var bigint_space: Value.BigIntSpace = undefined;
19895 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
20025 var bigint = try rhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
1989620026 defer bigint.deinit();
1989720027 if (rhs_val.floatHasFraction()) {
1989820028 switch (op) {
......@@ -19950,6 +20080,7 @@ fn cmpVector(
1995020080 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1995120081
1995220082 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");
20083 const target = sema.mod.getTarget();
1995320084
1995420085 const runtime_src: LazySrcLoc = src: {
1995520086 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
......@@ -19957,7 +20088,7 @@ fn cmpVector(
1995720088 if (lhs_val.isUndef() or rhs_val.isUndef()) {
1995820089 return sema.addConstUndef(result_ty);
1995920090 }
19960 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena);
20091 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, target);
1996120092 return sema.addConstant(result_ty, cmp_val);
1996220093 } else {
1996320094 break :src rhs_src;
......@@ -20108,7 +20239,7 @@ fn resolvePeerTypes(
2010820239 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
2010920240 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
2011020241
20111 if (candidate_ty.eql(chosen_ty))
20242 if (candidate_ty.eql(chosen_ty, target))
2011220243 continue;
2011320244
2011420245 switch (candidate_ty_tag) {
......@@ -20522,14 +20653,17 @@ fn resolvePeerTypes(
2052220653 );
2052320654
2052420655 const msg = msg: {
20525 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty });
20656 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
20657 chosen_ty.fmt(target),
20658 candidate_ty.fmt(target),
20659 });
2052620660 errdefer msg.destroy(sema.gpa);
2052720661
2052820662 if (chosen_src) |src_loc|
20529 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty});
20663 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(target)});
2053020664
2053120665 if (candidate_src) |src_loc|
20532 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty});
20666 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(target)});
2053320667
2053420668 break :msg msg;
2053520669 };
......@@ -20557,7 +20691,7 @@ fn resolvePeerTypes(
2055720691 else
2055820692 new_ptr_ty;
2055920693 const set_ty = err_set_ty orelse return opt_ptr_ty;
20560 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20694 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2056120695 }
2056220696
2056320697 if (seen_const) {
......@@ -20573,7 +20707,7 @@ fn resolvePeerTypes(
2057320707 else
2057420708 new_ptr_ty;
2057520709 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
20576 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20710 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2057720711 },
2057820712 .Pointer => {
2057920713 var info = chosen_ty.ptrInfo();
......@@ -20584,7 +20718,7 @@ fn resolvePeerTypes(
2058420718 else
2058520719 new_ptr_ty;
2058620720 const set_ty = err_set_ty orelse return opt_ptr_ty;
20587 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);
20721 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
2058820722 },
2058920723 else => return chosen_ty,
2059020724 }
......@@ -20596,16 +20730,16 @@ fn resolvePeerTypes(
2059620730 else => try Type.optional(sema.arena, chosen_ty),
2059720731 };
2059820732 const set_ty = err_set_ty orelse return opt_ty;
20599 return try Module.errorUnionType(sema.arena, set_ty, opt_ty);
20733 return try Type.errorUnion(sema.arena, set_ty, opt_ty, target);
2060020734 }
2060120735
2060220736 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
2060320737 .ErrorSet => return ty,
2060420738 .ErrorUnion => {
2060520739 const payload_ty = chosen_ty.errorUnionPayload();
20606 return try Module.errorUnionType(sema.arena, ty, payload_ty);
20740 return try Type.errorUnion(sema.arena, ty, payload_ty, target);
2060720741 },
20608 else => return try Module.errorUnionType(sema.arena, ty, chosen_ty),
20742 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, target),
2060920743 };
2061020744
2061120745 return chosen_ty;
......@@ -20662,11 +20796,12 @@ fn resolveStructLayout(
2066220796) CompileError!void {
2066320797 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
2066420798 if (resolved_ty.castTag(.@"struct")) |payload| {
20799 const target = sema.mod.getTarget();
2066520800 const struct_obj = payload.data;
2066620801 switch (struct_obj.status) {
2066720802 .none, .have_field_types => {},
2066820803 .field_types_wip, .layout_wip => {
20669 return sema.fail(block, src, "struct {} depends on itself", .{ty});
20804 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
2067020805 },
2067120806 .have_layout, .fully_resolved_wip, .fully_resolved => return,
2067220807 }
......@@ -20694,10 +20829,11 @@ fn resolveUnionLayout(
2069420829) CompileError!void {
2069520830 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
2069620831 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
20832 const target = sema.mod.getTarget();
2069720833 switch (union_obj.status) {
2069820834 .none, .have_field_types => {},
2069920835 .field_types_wip, .layout_wip => {
20700 return sema.fail(block, src, "union {} depends on itself", .{ty});
20836 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
2070120837 },
2070220838 .have_layout, .fully_resolved_wip, .fully_resolved => return,
2070320839 }
......@@ -20828,10 +20964,11 @@ fn resolveTypeFieldsStruct(
2082820964 ty: Type,
2082920965 struct_obj: *Module.Struct,
2083020966) CompileError!void {
20967 const target = sema.mod.getTarget();
2083120968 switch (struct_obj.status) {
2083220969 .none => {},
2083320970 .field_types_wip => {
20834 return sema.fail(block, src, "struct {} depends on itself", .{ty});
20971 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
2083520972 },
2083620973 .have_field_types,
2083720974 .have_layout,
......@@ -20858,10 +20995,11 @@ fn resolveTypeFieldsUnion(
2085820995 ty: Type,
2085920996 union_obj: *Module.Union,
2086020997) CompileError!void {
20998 const target = sema.mod.getTarget();
2086120999 switch (union_obj.status) {
2086221000 .none => {},
2086321001 .field_types_wip => {
20864 return sema.fail(block, src, "union {} depends on itself", .{ty});
21002 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
2086521003 },
2086621004 .have_field_types,
2086721005 .have_layout,
......@@ -21218,6 +21356,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2121821356 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
2121921357 }
2122021358
21359 const target = sema.mod.getTarget();
21360
2122121361 const bits_per_field = 4;
2122221362 const fields_per_u32 = 32 / bits_per_field;
2122321363 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
......@@ -21275,16 +21415,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2127521415 // This puts the memory into the union arena, not the enum arena, but
2127621416 // it is OK since they share the same lifetime.
2127721417 const copied_val = try val.copy(decl_arena_allocator);
21278 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
21418 map.putAssumeCapacityContext(copied_val, {}, .{
21419 .ty = int_tag_ty,
21420 .target = target,
21421 });
2127921422 } else {
2128021423 const val = if (last_tag_val) |val|
21281 try val.intAdd(Value.one, int_tag_ty, sema.arena)
21424 try val.intAdd(Value.one, int_tag_ty, sema.arena, target)
2128221425 else
2128321426 Value.zero;
2128421427 last_tag_val = val;
2128521428
2128621429 const copied_val = try val.copy(decl_arena_allocator);
21287 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
21430 map.putAssumeCapacityContext(copied_val, {}, .{
21431 .ty = int_tag_ty,
21432 .target = target,
21433 });
2128821434 }
2128921435 }
2129021436
......@@ -21359,7 +21505,10 @@ fn generateUnionTagTypeNumbered(
2135921505 };
2136021506 // Here we pre-allocate the maps using the decl arena.
2136121507 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 });
21508 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
21509 .ty = int_ty,
21510 .target = sema.mod.getTarget(),
21511 });
2136321512 try new_decl.finalizeNewArena(&new_decl_arena);
2136421513 return enum_ty;
2136521514}
......@@ -21962,7 +22111,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
2196222111 // The type is not in-memory coercible or the direct dereference failed, so it must
2196322112 // be bitcast according to the pointer type we are performing the load through.
2196422113 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});
22114 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(target)});
2196622115
2196722116 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2196822117
......@@ -21977,11 +22126,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
2197722126 if (deref.ty_without_well_defined_layout) |bad_ty| {
2197822127 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
2197922128 // 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});
22129 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(target)});
2198122130 } else {
2198222131 // If all encountered types had well-defined layouts, the parent is the root decl and it just
2198322132 // 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 });
22133 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(target), deref.parent.?.tv.ty.fmt(target) });
2198522134 }
2198622135}
2198722136
......@@ -22344,7 +22493,8 @@ fn anonStructFieldIndex(
2234422493 return @intCast(u32, i);
2234522494 }
2234622495 }
22496 const target = sema.mod.getTarget();
2234722497 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{
22348 struct_ty, field_name,
22498 struct_ty.fmt(target), field_name,
2234922499 });
2235022500}
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+488-248
......@@ -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,42 @@ 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(TypedValue.format) {
1487 var ty_payload: Value.Payload.Ty = .{
1488 .base = .{ .tag = .ty },
1489 .data = ty,
1490 };
1491 return .{ .data = .{
1492 .tv = .{
1493 .ty = Type.type,
1494 .val = Value.initPayload(&ty_payload.base),
1495 },
1496 .target = target,
1497 } };
1498 }
1499
1500 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
1501 return .{ .data = ty };
1502 }
1503
1504 /// This is a debug function. In order to print types in a meaningful way
1505 /// we also need access to the target.
1506 pub fn dump(
14781507 start_type: Type,
1479 comptime fmt: []const u8,
1508 comptime unused_format_string: []const u8,
14801509 options: std.fmt.FormatOptions,
14811510 writer: anytype,
14821511 ) @TypeOf(writer).Error!void {
14831512 _ = options;
1484 comptime assert(fmt.len == 0);
1513 comptime assert(unused_format_string.len == 0);
14851514 var ty = start_type;
14861515 while (true) {
14871516 const t = ty.tag();
......@@ -1584,7 +1613,7 @@ pub const Type = extern union {
15841613 try writer.writeAll("fn(");
15851614 for (payload.param_types) |param_type, i| {
15861615 if (i != 0) try writer.writeAll(", ");
1587 try param_type.format("", .{}, writer);
1616 try param_type.dump("", .{}, writer);
15881617 }
15891618 if (payload.is_var_args) {
15901619 if (payload.param_types.len != 0) {
......@@ -1622,7 +1651,7 @@ pub const Type = extern union {
16221651 .vector => {
16231652 const payload = ty.castTag(.vector).?.data;
16241653 try writer.print("@Vector({d}, ", .{payload.len});
1625 try payload.elem_type.format("", .{}, writer);
1654 try payload.elem_type.dump("", .{}, writer);
16261655 return writer.writeAll(")");
16271656 },
16281657 .array => {
......@@ -1633,7 +1662,10 @@ pub const Type = extern union {
16331662 },
16341663 .array_sentinel => {
16351664 const payload = ty.castTag(.array_sentinel).?.data;
1636 try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel.fmtValue(payload.elem_type) });
1665 try writer.print("[{d}:{}]", .{
1666 payload.len,
1667 payload.sentinel.fmtDebug(),
1668 });
16371669 ty = payload.elem_type;
16381670 continue;
16391671 },
......@@ -1646,9 +1678,9 @@ pub const Type = extern union {
16461678 if (val.tag() != .unreachable_value) {
16471679 try writer.writeAll("comptime ");
16481680 }
1649 try field_ty.format("", .{}, writer);
1681 try field_ty.dump("", .{}, writer);
16501682 if (val.tag() != .unreachable_value) {
1651 try writer.print(" = {}", .{val.fmtValue(field_ty)});
1683 try writer.print(" = {}", .{val.fmtDebug()});
16521684 }
16531685 }
16541686 try writer.writeAll("}");
......@@ -1665,9 +1697,9 @@ pub const Type = extern union {
16651697 }
16661698 try writer.writeAll(anon_struct.names[i]);
16671699 try writer.writeAll(": ");
1668 try field_ty.format("", .{}, writer);
1700 try field_ty.dump("", .{}, writer);
16691701 if (val.tag() != .unreachable_value) {
1670 try writer.print(" = {}", .{val.fmtValue(field_ty)});
1702 try writer.print(" = {}", .{val.fmtDebug()});
16711703 }
16721704 }
16731705 try writer.writeAll("}");
......@@ -1752,8 +1784,8 @@ pub const Type = extern union {
17521784 const payload = ty.castTag(.pointer).?.data;
17531785 if (payload.sentinel) |some| switch (payload.size) {
17541786 .One, .C => unreachable,
1755 .Many => try writer.print("[*:{}]", .{some.fmtValue(payload.pointee_type)}),
1756 .Slice => try writer.print("[:{}]", .{some.fmtValue(payload.pointee_type)}),
1787 .Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
1788 .Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
17571789 } else switch (payload.size) {
17581790 .One => try writer.writeAll("*"),
17591791 .Many => try writer.writeAll("[*]"),
......@@ -1780,7 +1812,7 @@ pub const Type = extern union {
17801812 },
17811813 .error_union => {
17821814 const payload = ty.castTag(.error_union).?.data;
1783 try payload.error_set.format("", .{}, writer);
1815 try payload.error_set.dump("", .{}, writer);
17841816 try writer.writeAll("!");
17851817 ty = payload.payload;
17861818 continue;
......@@ -1821,20 +1853,17 @@ pub const Type = extern union {
18211853 }
18221854 }
18231855
1824 pub fn nameAllocArena(ty: Type, arena: Allocator) Allocator.Error![:0]const u8 {
1825 return nameAllocAdvanced(ty, arena, true);
1826 }
1856 pub const nameAllocArena = nameAlloc;
18271857
1828 pub fn nameAlloc(ty: Type, gpa: Allocator) Allocator.Error![:0]const u8 {
1829 return nameAllocAdvanced(ty, gpa, false);
1858 pub fn nameAlloc(ty: Type, ally: Allocator, target: Target) Allocator.Error![:0]const u8 {
1859 var buffer = std.ArrayList(u8).init(ally);
1860 defer buffer.deinit();
1861 try ty.print(buffer.writer(), target);
1862 return buffer.toOwnedSliceSentinel(0);
18301863 }
18311864
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 {
1865 /// Prints a name suitable for `@typeName`.
1866 pub fn print(ty: Type, writer: anytype, target: Target) @TypeOf(writer).Error!void {
18381867 const t = ty.tag();
18391868 switch (t) {
18401869 .inferred_alloc_const => unreachable,
......@@ -1892,141 +1921,251 @@ pub const Type = extern union {
18921921 .comptime_int,
18931922 .comptime_float,
18941923 .noreturn,
1895 => return maybeDupe(@tagName(t), ally, is_arena),
1924 => try writer.writeAll(@tagName(t)),
18961925
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),
1926 .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"),
1927 .@"null" => try writer.writeAll("@TypeOf(null)"),
1928 .@"undefined" => try writer.writeAll("@TypeOf(undefined)"),
1929 .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"),
19011930
19021931 .empty_struct => {
19031932 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);
1933 try namespace.renderFullyQualifiedName("", writer);
19081934 },
19091935
19101936 .@"struct" => {
19111937 const struct_obj = ty.castTag(.@"struct").?.data;
1912 return try struct_obj.owner_decl.getFullyQualifiedName(ally);
1938 try struct_obj.owner_decl.renderFullyQualifiedName(writer);
19131939 },
19141940 .@"union", .union_tagged => {
19151941 const union_obj = ty.cast(Payload.Union).?.data;
1916 return try union_obj.owner_decl.getFullyQualifiedName(ally);
1942 try union_obj.owner_decl.renderFullyQualifiedName(writer);
19171943 },
19181944 .enum_full, .enum_nonexhaustive => {
19191945 const enum_full = ty.cast(Payload.EnumFull).?.data;
1920 return try enum_full.owner_decl.getFullyQualifiedName(ally);
1946 try enum_full.owner_decl.renderFullyQualifiedName(writer);
19211947 },
19221948 .enum_simple => {
19231949 const enum_simple = ty.castTag(.enum_simple).?.data;
1924 return try enum_simple.owner_decl.getFullyQualifiedName(ally);
1950 try enum_simple.owner_decl.renderFullyQualifiedName(writer);
19251951 },
19261952 .enum_numbered => {
19271953 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1928 return try enum_numbered.owner_decl.getFullyQualifiedName(ally);
1954 try enum_numbered.owner_decl.renderFullyQualifiedName(writer);
19291955 },
19301956 .@"opaque" => {
19311957 const opaque_obj = ty.cast(Payload.Opaque).?.data;
1932 return try opaque_obj.owner_decl.getFullyQualifiedName(ally);
1958 try opaque_obj.owner_decl.renderFullyQualifiedName(writer);
19331959 },
19341960
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),
1961 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
1962 .const_slice_u8 => try writer.writeAll("[]const u8"),
1963 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),
1964 .fn_noreturn_no_args => try writer.writeAll("fn() noreturn"),
1965 .fn_void_no_args => try writer.writeAll("fn() void"),
1966 .fn_naked_noreturn_no_args => try writer.writeAll("fn() callconv(.Naked) noreturn"),
1967 .fn_ccc_void_no_args => try writer.writeAll("fn() callconv(.C) void"),
1968 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
1969 .manyptr_u8 => try writer.writeAll("[*]u8"),
1970 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
1971 .manyptr_const_u8_sentinel_0 => try writer.writeAll("[*:0]const u8"),
19461972
19471973 .error_set_inferred => {
19481974 const func = ty.castTag(.error_set_inferred).?.data.func;
19491975
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);
1976 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
1977 try func.owner_decl.renderFullyQualifiedName(writer);
1978 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
19561979 },
19571980
19581981 .function => {
19591982 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);
1983 try writer.writeAll("fn(");
1984 for (fn_info.param_types) |param_ty, i| {
1985 if (i != 0) try writer.writeAll(", ");
1986 try print(param_ty, writer, target);
19681987 }
19691988 if (fn_info.is_var_args) {
19701989 if (fn_info.param_types.len != 0) {
1971 try buf.appendSlice(", ");
1990 try writer.writeAll(", ");
19721991 }
1973 try buf.appendSlice("...");
1992 try writer.writeAll("...");
19741993 }
1975 try buf.appendSlice(") ");
1994 try writer.writeAll(") ");
19761995 if (fn_info.cc != .Unspecified) {
1977 try buf.appendSlice("callconv(.");
1978 try buf.appendSlice(@tagName(fn_info.cc));
1979 try buf.appendSlice(") ");
1996 try writer.writeAll("callconv(.");
1997 try writer.writeAll(@tagName(fn_info.cc));
1998 try writer.writeAll(") ");
19801999 }
19812000 if (fn_info.alignment != 0) {
1982 try buf.writer().print("align({d}) ", .{fn_info.alignment});
1983 }
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);
2001 try writer.print("align({d}) ", .{fn_info.alignment});
19882002 }
1989 return try buf.toOwnedSliceSentinel(0);
2003 try print(fn_info.return_type, writer, target);
19902004 },
19912005
19922006 .error_union => {
19932007 const error_union = ty.castTag(.error_union).?.data;
2008 try print(error_union.error_set, writer, target);
2009 try writer.writeAll("!");
2010 try print(error_union.payload, writer, target);
2011 },
19942012
1995 var buf = std.ArrayList(u8).init(ally);
1996 defer buf.deinit();
2013 .array_u8 => {
2014 const len = ty.castTag(.array_u8).?.data;
2015 try writer.print("[{d}]u8", .{len});
2016 },
2017 .array_u8_sentinel_0 => {
2018 const len = ty.castTag(.array_u8_sentinel_0).?.data;
2019 try writer.print("[{d}:0]u8", .{len});
2020 },
2021 .vector => {
2022 const payload = ty.castTag(.vector).?.data;
2023 try writer.print("@Vector({d}, ", .{payload.len});
2024 try print(payload.elem_type, writer, target);
2025 try writer.writeAll(")");
2026 },
2027 .array => {
2028 const payload = ty.castTag(.array).?.data;
2029 try writer.print("[{d}]", .{payload.len});
2030 try print(payload.elem_type, writer, target);
2031 },
2032 .array_sentinel => {
2033 const payload = ty.castTag(.array_sentinel).?.data;
2034 try writer.print("[{d}:{}]", .{
2035 payload.len,
2036 payload.sentinel.fmtValue(payload.elem_type, target),
2037 });
2038 try print(payload.elem_type, writer, target);
2039 },
2040 .tuple => {
2041 const tuple = ty.castTag(.tuple).?.data;
19972042
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);
2043 try writer.writeAll("tuple{");
2044 for (tuple.types) |field_ty, i| {
2045 if (i != 0) try writer.writeAll(", ");
2046 const val = tuple.values[i];
2047 if (val.tag() != .unreachable_value) {
2048 try writer.writeAll("comptime ");
2049 }
2050 try print(field_ty, writer, target);
2051 if (val.tag() != .unreachable_value) {
2052 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2053 }
2054 }
2055 try writer.writeAll("}");
2056 },
2057 .anon_struct => {
2058 const anon_struct = ty.castTag(.anon_struct).?.data;
2059
2060 try writer.writeAll("struct{");
2061 for (anon_struct.types) |field_ty, i| {
2062 if (i != 0) try writer.writeAll(", ");
2063 const val = anon_struct.values[i];
2064 if (val.tag() != .unreachable_value) {
2065 try writer.writeAll("comptime ");
2066 }
2067 try writer.writeAll(anon_struct.names[i]);
2068 try writer.writeAll(": ");
2069
2070 try print(field_ty, writer, target);
2071
2072 if (val.tag() != .unreachable_value) {
2073 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2074 }
20022075 }
2076 try writer.writeAll("}");
2077 },
20032078
2004 try buf.appendSlice("!");
2079 .pointer,
2080 .single_const_pointer,
2081 .single_mut_pointer,
2082 .many_const_pointer,
2083 .many_mut_pointer,
2084 .c_const_pointer,
2085 .c_mut_pointer,
2086 .const_slice,
2087 .mut_slice,
2088 => {
2089 const info = ty.ptrInfo().data;
20052090
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);
2091 if (info.sentinel) |s| switch (info.size) {
2092 .One, .C => unreachable,
2093 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, target)}),
2094 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, target)}),
2095 } else switch (info.size) {
2096 .One => try writer.writeAll("*"),
2097 .Many => try writer.writeAll("[*]"),
2098 .C => try writer.writeAll("[*c]"),
2099 .Slice => try writer.writeAll("[]"),
20102100 }
2101 if (info.@"align" != 0 or info.host_size != 0) {
2102 try writer.print("align({d}", .{info.@"align"});
20112103
2012 return try buf.toOwnedSliceSentinel(0);
2013 },
2104 if (info.bit_offset != 0) {
2105 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
2106 }
2107 try writer.writeAll(") ");
2108 }
2109 if (info.@"addrspace" != .generic) {
2110 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
2111 }
2112 if (!info.mutable) try writer.writeAll("const ");
2113 if (info.@"volatile") try writer.writeAll("volatile ");
2114 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
20142115
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);
2116 try print(info.pointee_type, writer, target);
20212117 },
2022 }
2023 }
20242118
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);
2119 .int_signed => {
2120 const bits = ty.castTag(.int_signed).?.data;
2121 return writer.print("i{d}", .{bits});
2122 },
2123 .int_unsigned => {
2124 const bits = ty.castTag(.int_unsigned).?.data;
2125 return writer.print("u{d}", .{bits});
2126 },
2127 .optional => {
2128 const child_type = ty.castTag(.optional).?.data;
2129 try writer.writeByte('?');
2130 try print(child_type, writer, target);
2131 },
2132 .optional_single_mut_pointer => {
2133 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
2134 try writer.writeAll("?*");
2135 try print(pointee_type, writer, target);
2136 },
2137 .optional_single_const_pointer => {
2138 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
2139 try writer.writeAll("?*const ");
2140 try print(pointee_type, writer, target);
2141 },
2142 .anyframe_T => {
2143 const return_type = ty.castTag(.anyframe_T).?.data;
2144 try writer.print("anyframe->", .{});
2145 try print(return_type, writer, target);
2146 },
2147 .error_set => {
2148 const names = ty.castTag(.error_set).?.data.names.keys();
2149 try writer.writeAll("error{");
2150 for (names) |name, i| {
2151 if (i != 0) try writer.writeByte(',');
2152 try writer.writeAll(name);
2153 }
2154 try writer.writeAll("}");
2155 },
2156 .error_set_single => {
2157 const name = ty.castTag(.error_set_single).?.data;
2158 return writer.print("error{{{s}}}", .{name});
2159 },
2160 .error_set_merged => {
2161 const names = ty.castTag(.error_set_merged).?.data.keys();
2162 try writer.writeAll("error{");
2163 for (names) |name, i| {
2164 if (i != 0) try writer.writeByte(',');
2165 try writer.writeAll(name);
2166 }
2167 try writer.writeAll("}");
2168 },
20302169 }
20312170 }
20322171
......@@ -2518,8 +2657,33 @@ pub const Type = extern union {
25182657 }
25192658
25202659 /// Returns 0 for 0-bit types.
2521 pub fn abiAlignment(self: Type, target: Target) u32 {
2522 return switch (self.tag()) {
2660 pub fn abiAlignment(ty: Type, target: Target) u32 {
2661 return ty.abiAlignmentAdvanced(target, .eager).scalar;
2662 }
2663
2664 /// May capture a reference to `ty`.
2665 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {
2666 switch (ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {
2667 .val => |val| return try val,
2668 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
2669 }
2670 }
2671
2672 /// If you pass `eager` you will get back `scalar` and assert the type is resolved.
2673 /// If you pass `lazy` you may get back `scalar` or `val`.
2674 /// If `val` is returned, a reference to `ty` has been captured.
2675 fn abiAlignmentAdvanced(
2676 ty: Type,
2677 target: Target,
2678 strat: union(enum) {
2679 eager,
2680 lazy: Allocator,
2681 },
2682 ) union(enum) {
2683 scalar: u32,
2684 val: Allocator.Error!Value,
2685 } {
2686 return switch (ty.tag()) {
25232687 .u1,
25242688 .u8,
25252689 .i8,
......@@ -2538,25 +2702,25 @@ pub const Type = extern union {
25382702 .extern_options,
25392703 .@"opaque",
25402704 .anyopaque,
2541 => return 1,
2705 => return .{ .scalar = 1 },
25422706
25432707 .fn_noreturn_no_args, // represents machine code; not a pointer
25442708 .fn_void_no_args, // represents machine code; not a pointer
25452709 .fn_naked_noreturn_no_args, // represents machine code; not a pointer
25462710 .fn_ccc_void_no_args, // represents machine code; not a pointer
2547 => return target_util.defaultFunctionAlignment(target),
2711 => return .{ .scalar = target_util.defaultFunctionAlignment(target) },
25482712
25492713 // represents machine code; not a pointer
25502714 .function => {
2551 const alignment = self.castTag(.function).?.data.alignment;
2552 if (alignment != 0) return alignment;
2553 return target_util.defaultFunctionAlignment(target);
2715 const alignment = ty.castTag(.function).?.data.alignment;
2716 if (alignment != 0) return .{ .scalar = alignment };
2717 return .{ .scalar = target_util.defaultFunctionAlignment(target) };
25542718 },
25552719
2556 .i16, .u16 => return 2,
2557 .i32, .u32 => return 4,
2558 .i64, .u64 => return 8,
2559 .u128, .i128 => return 16,
2720 .i16, .u16 => return .{ .scalar = 2 },
2721 .i32, .u32 => return .{ .scalar = 4 },
2722 .i64, .u64 => return .{ .scalar = 8 },
2723 .u128, .i128 => return .{ .scalar = 16 },
25602724
25612725 .isize,
25622726 .usize,
......@@ -2579,40 +2743,40 @@ pub const Type = extern union {
25792743 .manyptr_const_u8_sentinel_0,
25802744 .@"anyframe",
25812745 .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,
2746 => return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
2747
2748 .c_short => return .{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
2749 .c_ushort => return .{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
2750 .c_int => return .{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
2751 .c_uint => return .{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
2752 .c_long => return .{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
2753 .c_ulong => return .{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2754 .c_longlong => return .{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2755 .c_ulonglong => return .{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
2756
2757 .f16 => return .{ .scalar = 2 },
2758 .f32 => return .{ .scalar = 4 },
2759 .f64 => return .{ .scalar = 8 },
2760 .f128 => return .{ .scalar = 16 },
25972761
25982762 .f80 => switch (target.cpu.arch) {
2599 .i386 => return 4,
2600 .x86_64 => return 16,
2763 .i386 => return .{ .scalar = 4 },
2764 .x86_64 => return .{ .scalar = 16 },
26012765 else => {
26022766 var payload: Payload.Bits = .{
26032767 .base = .{ .tag = .int_unsigned },
26042768 .data = 80,
26052769 };
26062770 const u80_ty = initPayload(&payload.base);
2607 return abiAlignment(u80_ty, target);
2771 return .{ .scalar = abiAlignment(u80_ty, target) };
26082772 },
26092773 },
26102774 .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),
2775 16 => return .{ .scalar = abiAlignment(Type.f16, target) },
2776 32 => return .{ .scalar = abiAlignment(Type.f32, target) },
2777 64 => return .{ .scalar = abiAlignment(Type.f64, target) },
2778 80 => return .{ .scalar = abiAlignment(Type.f80, target) },
2779 128 => return .{ .scalar = abiAlignment(Type.f128, target) },
26162780 else => unreachable,
26172781 },
26182782
......@@ -2622,60 +2786,93 @@ pub const Type = extern union {
26222786 .anyerror,
26232787 .error_set_inferred,
26242788 .error_set_merged,
2625 => return 2, // TODO revisit this when we have the concept of the error tag type
2789 => return .{ .scalar = 2 }, // TODO revisit this when we have the concept of the error tag type
26262790
2627 .array, .array_sentinel => return self.elemType().abiAlignment(target),
2791 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
26282792
26292793 // TODO audit this - is there any more complicated logic to determine
26302794 // ABI alignment of vectors?
2631 .vector => return 16,
2795 .vector => return .{ .scalar = 16 },
26322796
26332797 .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;
2798 const bits: u16 = ty.cast(Payload.Bits).?.data;
2799 if (bits == 0) return .{ .scalar = 0 };
2800 if (bits <= 8) return .{ .scalar = 1 };
2801 if (bits <= 16) return .{ .scalar = 2 };
2802 if (bits <= 32) return .{ .scalar = 4 };
2803 if (bits <= 64) return .{ .scalar = 8 };
2804 return .{ .scalar = 16 };
26412805 },
26422806
26432807 .optional => {
26442808 var buf: Payload.ElemType = undefined;
2645 const child_type = self.optionalChild(&buf);
2646 if (!child_type.hasRuntimeBits()) return 1;
2809 const child_type = ty.optionalChild(&buf);
26472810
2648 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr())
2649 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
2811 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) {
2812 return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
2813 }
26502814
2651 return child_type.abiAlignment(target);
2815 switch (strat) {
2816 .eager => {
2817 if (!child_type.hasRuntimeBits()) return .{ .scalar = 1 };
2818 return .{ .scalar = child_type.abiAlignment(target) };
2819 },
2820 .lazy => |arena| switch (child_type.abiAlignmentAdvanced(target, strat)) {
2821 .scalar => |x| return .{ .scalar = @maximum(x, 1) },
2822 .val => return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2823 },
2824 }
26522825 },
26532826
26542827 .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);
2828 const data = ty.castTag(.error_union).?.data;
2829 switch (strat) {
2830 .eager => {
2831 if (!data.error_set.hasRuntimeBits()) {
2832 return .{ .scalar = data.payload.abiAlignment(target) };
2833 } else if (!data.payload.hasRuntimeBits()) {
2834 return .{ .scalar = data.error_set.abiAlignment(target) };
2835 }
2836 return .{ .scalar = @maximum(
2837 data.payload.abiAlignment(target),
2838 data.error_set.abiAlignment(target),
2839 ) };
2840 },
2841 .lazy => |arena| {
2842 switch (data.payload.abiAlignmentAdvanced(target, strat)) {
2843 .scalar => |payload_align| {
2844 if (payload_align == 0) {
2845 return data.error_set.abiAlignmentAdvanced(target, strat);
2846 }
2847 switch (data.error_set.abiAlignmentAdvanced(target, strat)) {
2848 .scalar => |err_set_align| {
2849 return .{ .scalar = @maximum(payload_align, err_set_align) };
2850 },
2851 .val => {},
2852 }
2853 },
2854 .val => {},
2855 }
2856 return .{ .val = Value.Tag.lazy_align.create(arena, ty) };
2857 },
26602858 }
2661 return @maximum(
2662 data.payload.abiAlignment(target),
2663 data.error_set.abiAlignment(target),
2664 );
26652859 },
26662860
26672861 .@"struct" => {
2668 const fields = self.structFields();
2669 if (self.castTag(.@"struct")) |payload| {
2862 if (ty.castTag(.@"struct")) |payload| {
26702863 const struct_obj = payload.data;
2671 assert(struct_obj.haveLayout());
2864 if (!struct_obj.haveLayout()) switch (strat) {
2865 .eager => unreachable, // struct layout not resolved
2866 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2867 };
26722868 if (struct_obj.layout == .Packed) {
26732869 var buf: Type.Payload.Bits = undefined;
26742870 const int_ty = struct_obj.packedIntegerType(target, &buf);
2675 return int_ty.abiAlignment(target);
2871 return .{ .scalar = int_ty.abiAlignment(target) };
26762872 }
26772873 }
26782874
2875 const fields = ty.structFields();
26792876 var big_align: u32 = 0;
26802877 for (fields.values()) |field| {
26812878 if (!field.ty.hasRuntimeBits()) continue;
......@@ -2683,31 +2880,45 @@ pub const Type = extern union {
26832880 const field_align = field.normalAlignment(target);
26842881 big_align = @maximum(big_align, field_align);
26852882 }
2686 return big_align;
2883 return .{ .scalar = big_align };
26872884 },
26882885
26892886 .tuple, .anon_struct => {
2690 const tuple = self.tupleFields();
2887 const tuple = ty.tupleFields();
26912888 var big_align: u32 = 0;
26922889 for (tuple.types) |field_ty, i| {
26932890 const val = tuple.values[i];
26942891 if (val.tag() != .unreachable_value) continue; // comptime field
2695 if (!field_ty.hasRuntimeBits()) continue;
26962892
2697 const field_align = field_ty.abiAlignment(target);
2698 big_align = @maximum(big_align, field_align);
2893 switch (field_ty.abiAlignmentAdvanced(target, strat)) {
2894 .scalar => |field_align| big_align = @maximum(big_align, field_align),
2895 .val => switch (strat) {
2896 .eager => unreachable, // field type alignment not resolved
2897 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2898 },
2899 }
26992900 }
2700 return big_align;
2901 return .{ .scalar = big_align };
27012902 },
27022903
27032904 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
27042905 var buffer: Payload.Bits = undefined;
2705 const int_tag_ty = self.intTagType(&buffer);
2706 return int_tag_ty.abiAlignment(target);
2906 const int_tag_ty = ty.intTagType(&buffer);
2907 return .{ .scalar = int_tag_ty.abiAlignment(target) };
2908 },
2909 .@"union" => switch (strat) {
2910 .eager => {
2911 // TODO pass `true` for have_tag when unions have a safety tag
2912 return .{ .scalar = ty.castTag(.@"union").?.data.abiAlignment(target, false) };
2913 },
2914 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2915 },
2916 .union_tagged => switch (strat) {
2917 .eager => {
2918 return .{ .scalar = ty.castTag(.union_tagged).?.data.abiAlignment(target, true) };
2919 },
2920 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
27072921 },
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),
27112922
27122923 .empty_struct,
27132924 .void,
......@@ -2719,7 +2930,7 @@ pub const Type = extern union {
27192930 .@"undefined",
27202931 .enum_literal,
27212932 .type_info,
2722 => return 0,
2933 => return .{ .scalar = 0 },
27232934
27242935 .noreturn,
27252936 .inferred_alloc_const,
......@@ -3392,10 +3603,7 @@ pub const Type = extern union {
33923603
33933604 .optional => {
33943605 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;
33973606 if (child_ty.zigTypeTag() != .Pointer) return false;
3398
33993607 const info = child_ty.ptrInfo().data;
34003608 switch (info.size) {
34013609 .Slice, .C => return false,
......@@ -3663,9 +3871,9 @@ pub const Type = extern union {
36633871 return union_obj.fields;
36643872 }
36653873
3666 pub fn unionFieldType(ty: Type, enum_tag: Value) Type {
3874 pub fn unionFieldType(ty: Type, enum_tag: Value, target: Target) Type {
36673875 const union_obj = ty.cast(Payload.Union).?.data;
3668 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag).?;
3876 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, target).?;
36693877 assert(union_obj.haveFieldTypes());
36703878 return union_obj.fields.values()[index].ty;
36713879 }
......@@ -4679,20 +4887,20 @@ pub const Type = extern union {
46794887 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
46804888 /// an integer which represents the enum value. Returns the field index in
46814889 /// declaration order, or `null` if `enum_tag` does not match any field.
4682 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value) ?usize {
4890 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, target: Target) ?usize {
46834891 if (enum_tag.castTag(.enum_field_index)) |payload| {
46844892 return @as(usize, payload.data);
46854893 }
46864894 const S = struct {
4687 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize) ?usize {
4895 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, tg: Target) ?usize {
46884896 if (int_val.compareWithZero(.lt)) return null;
46894897 var end_payload: Value.Payload.U64 = .{
46904898 .base = .{ .tag = .int_u64 },
46914899 .data = end,
46924900 };
46934901 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());
4902 if (int_val.compare(.gte, end_val, int_ty, tg)) return null;
4903 return @intCast(usize, int_val.toUnsignedInt(tg));
46964904 }
46974905 };
46984906 switch (ty.tag()) {
......@@ -4700,18 +4908,24 @@ pub const Type = extern union {
47004908 const enum_full = ty.cast(Payload.EnumFull).?.data;
47014909 const tag_ty = enum_full.tag_ty;
47024910 if (enum_full.values.count() == 0) {
4703 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count());
4911 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), target);
47044912 } else {
4705 return enum_full.values.getIndexContext(enum_tag, .{ .ty = tag_ty });
4913 return enum_full.values.getIndexContext(enum_tag, .{
4914 .ty = tag_ty,
4915 .target = target,
4916 });
47064917 }
47074918 },
47084919 .enum_numbered => {
47094920 const enum_obj = ty.castTag(.enum_numbered).?.data;
47104921 const tag_ty = enum_obj.tag_ty;
47114922 if (enum_obj.values.count() == 0) {
4712 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count());
4923 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), target);
47134924 } else {
4714 return enum_obj.values.getIndexContext(enum_tag, .{ .ty = tag_ty });
4925 return enum_obj.values.getIndexContext(enum_tag, .{
4926 .ty = tag_ty,
4927 .target = target,
4928 });
47154929 }
47164930 },
47174931 .enum_simple => {
......@@ -4723,7 +4937,7 @@ pub const Type = extern union {
47234937 .data = bits,
47244938 };
47254939 const tag_ty = Type.initPayload(&buffer.base);
4726 return S.fieldWithRange(tag_ty, enum_tag, fields_len);
4940 return S.fieldWithRange(tag_ty, enum_tag, fields_len, target);
47274941 },
47284942 .atomic_order,
47294943 .atomic_rmw_op,
......@@ -5018,14 +5232,14 @@ pub const Type = extern union {
50185232 /// Asserts the type is an enum.
50195233 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {
50205234 const S = struct {
5021 fn intInRange(tag_ty: Type, int_val: Value, end: usize) bool {
5235 fn intInRange(tag_ty: Type, int_val: Value, end: usize, tg: Target) bool {
50225236 if (int_val.compareWithZero(.lt)) return false;
50235237 var end_payload: Value.Payload.U64 = .{
50245238 .base = .{ .tag = .int_u64 },
50255239 .data = end,
50265240 };
50275241 const end_val = Value.initPayload(&end_payload.base);
5028 if (int_val.compare(.gte, end_val, tag_ty)) return false;
5242 if (int_val.compare(.gte, end_val, tag_ty, tg)) return false;
50295243 return true;
50305244 }
50315245 };
......@@ -5035,18 +5249,24 @@ pub const Type = extern union {
50355249 const enum_full = ty.castTag(.enum_full).?.data;
50365250 const tag_ty = enum_full.tag_ty;
50375251 if (enum_full.values.count() == 0) {
5038 return S.intInRange(tag_ty, int, enum_full.fields.count());
5252 return S.intInRange(tag_ty, int, enum_full.fields.count(), target);
50395253 } else {
5040 return enum_full.values.containsContext(int, .{ .ty = tag_ty });
5254 return enum_full.values.containsContext(int, .{
5255 .ty = tag_ty,
5256 .target = target,
5257 });
50415258 }
50425259 },
50435260 .enum_numbered => {
50445261 const enum_obj = ty.castTag(.enum_numbered).?.data;
50455262 const tag_ty = enum_obj.tag_ty;
50465263 if (enum_obj.values.count() == 0) {
5047 return S.intInRange(tag_ty, int, enum_obj.fields.count());
5264 return S.intInRange(tag_ty, int, enum_obj.fields.count(), target);
50485265 } else {
5049 return enum_obj.values.containsContext(int, .{ .ty = tag_ty });
5266 return enum_obj.values.containsContext(int, .{
5267 .ty = tag_ty,
5268 .target = target,
5269 });
50505270 }
50515271 },
50525272 .enum_simple => {
......@@ -5058,7 +5278,7 @@ pub const Type = extern union {
50585278 .data = bits,
50595279 };
50605280 const tag_ty = Type.initPayload(&buffer.base);
5061 return S.intInRange(tag_ty, int, fields_len);
5281 return S.intInRange(tag_ty, int, fields_len, target);
50625282 },
50635283 .atomic_order,
50645284 .atomic_rmw_op,
......@@ -5070,7 +5290,7 @@ pub const Type = extern union {
50705290 .prefetch_options,
50715291 .export_options,
50725292 .extern_options,
5073 => @panic("TODO resolve std.builtin types"),
5293 => unreachable,
50745294
50755295 else => unreachable,
50765296 }
......@@ -5620,7 +5840,7 @@ pub const Type = extern union {
56205840 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")
56215841 {
56225842 if (d.sentinel) |sent| {
5623 if (!d.mutable and d.pointee_type.eql(Type.u8)) {
5843 if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
56245844 switch (d.size) {
56255845 .Slice => {
56265846 if (sent.compareWithZero(.eq)) {
......@@ -5635,7 +5855,7 @@ pub const Type = extern union {
56355855 else => {},
56365856 }
56375857 }
5638 } else if (!d.mutable and d.pointee_type.eql(Type.u8)) {
5858 } else if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
56395859 switch (d.size) {
56405860 .Slice => return Type.initTag(.const_slice_u8),
56415861 .Many => return Type.initTag(.manyptr_const_u8),
......@@ -5669,10 +5889,11 @@ pub const Type = extern union {
56695889 len: u64,
56705890 sent: ?Value,
56715891 elem_type: Type,
5892 target: Target,
56725893 ) Allocator.Error!Type {
5673 if (elem_type.eql(Type.u8)) {
5894 if (elem_type.eql(Type.u8, target)) {
56745895 if (sent) |some| {
5675 if (some.eql(Value.zero, elem_type)) {
5896 if (some.eql(Value.zero, elem_type, target)) {
56765897 return Tag.array_u8_sentinel_0.create(arena, len);
56775898 }
56785899 } else {
......@@ -5715,6 +5936,25 @@ pub const Type = extern union {
57155936 }
57165937 }
57175938
5939 pub fn errorUnion(
5940 arena: Allocator,
5941 error_set: Type,
5942 payload: Type,
5943 target: Target,
5944 ) Allocator.Error!Type {
5945 assert(error_set.zigTypeTag() == .ErrorSet);
5946 if (error_set.eql(Type.@"anyerror", target) and
5947 payload.eql(Type.void, target))
5948 {
5949 return Type.initTag(.anyerror_void_error_union);
5950 }
5951
5952 return Type.Tag.error_union.create(arena, .{
5953 .error_set = error_set,
5954 .payload = payload,
5955 });
5956 }
5957
57185958 pub fn smallestUnsignedBits(max: u64) u16 {
57195959 if (max == 0) return 0;
57205960 const base = std.math.log2(max);
src/value.zig+258-206
......@@ -8,6 +8,7 @@ const Target = std.Target;
88const Allocator = std.mem.Allocator;
99const Module = @import("Module.zig");
1010const Air = @import("Air.zig");
11const TypedValue = @import("TypedValue.zig");
1112
1213/// This is the raw data, with no bookkeeping, no memory awareness,
1314/// no de-duplication, and no type system awareness.
......@@ -175,6 +176,8 @@ pub const Value = extern union {
175176 /// and refers directly to the air. It will never be referenced by the air itself.
176177 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.
177178 bound_fn,
179 /// The ABI alignment of the payload type.
180 lazy_align,
178181
179182 pub const last_no_payload_tag = Tag.empty_array;
180183 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -283,7 +286,10 @@ pub const Value = extern union {
283286
284287 .enum_field_index => Payload.U32,
285288
286 .ty => Payload.Ty,
289 .ty,
290 .lazy_align,
291 => Payload.Ty,
292
287293 .int_type => Payload.IntType,
288294 .int_u64 => Payload.U64,
289295 .int_i64 => Payload.I64,
......@@ -453,7 +459,7 @@ pub const Value = extern union {
453459 .bound_fn,
454460 => unreachable,
455461
456 .ty => {
462 .ty, .lazy_align => {
457463 const payload = self.castTag(.ty).?;
458464 const new_payload = try arena.create(Payload.Ty);
459465 new_payload.* = .{
......@@ -608,7 +614,7 @@ pub const Value = extern union {
608614 @compileError("do not use format values directly; use either fmtDebug or fmtValue");
609615 }
610616
611 /// TODO this should become a debug dump() function. In order to print values in a meaningful way
617 /// This is a debug function. In order to print values in a meaningful way
612618 /// we also need access to the type.
613619 pub fn dump(
614620 start_val: Value,
......@@ -699,7 +705,12 @@ pub const Value = extern union {
699705 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
700706 .bool_true => return out_stream.writeAll("true"),
701707 .bool_false => return out_stream.writeAll("false"),
702 .ty => return val.castTag(.ty).?.data.format("", options, out_stream),
708 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
709 .lazy_align => {
710 try out_stream.writeAll("@alignOf(");
711 try val.castTag(.lazy_align).?.data.dump("", options, out_stream);
712 try out_stream.writeAll(")");
713 },
703714 .int_type => {
704715 const int_type = val.castTag(.int_type).?.data;
705716 return out_stream.print("{s}{d}", .{
......@@ -778,15 +789,16 @@ pub const Value = extern union {
778789 return .{ .data = val };
779790 }
780791
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 } };
792 pub fn fmtValue(val: Value, ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {
793 return .{ .data = .{
794 .tv = .{ .ty = ty, .val = val },
795 .target = target,
796 } };
785797 }
786798
787799 /// Asserts that the value is representable as an array of bytes.
788800 /// 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 {
801 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, target: Target) ![]u8 {
790802 switch (val.tag()) {
791803 .bytes => {
792804 const bytes = val.castTag(.bytes).?.data;
......@@ -796,7 +808,7 @@ pub const Value = extern union {
796808 },
797809 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
798810 .repeated => {
799 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt());
811 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));
800812 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
801813 std.mem.set(u8, result, byte);
802814 return result;
......@@ -804,23 +816,23 @@ pub const Value = extern union {
804816 .decl_ref => {
805817 const decl = val.castTag(.decl_ref).?.data;
806818 const decl_val = try decl.value();
807 return decl_val.toAllocatedBytes(decl.ty, allocator);
819 return decl_val.toAllocatedBytes(decl.ty, allocator, target);
808820 },
809821 .the_only_possible_value => return &[_]u8{},
810822 .slice => {
811823 const slice = val.castTag(.slice).?.data;
812 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(), allocator);
824 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, target);
813825 },
814 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator),
826 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, target),
815827 }
816828 }
817829
818 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator) ![]u8 {
830 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, target: Target) ![]u8 {
819831 const result = try allocator.alloc(u8, @intCast(usize, len));
820832 var elem_value_buf: ElemValueBuffer = undefined;
821833 for (result) |*elem, i| {
822834 const elem_val = val.elemValueBuffer(i, &elem_value_buf);
823 elem.* = @intCast(u8, elem_val.toUnsignedInt());
835 elem.* = @intCast(u8, elem_val.toUnsignedInt(target));
824836 }
825837 return result;
826838 }
......@@ -977,8 +989,8 @@ pub const Value = extern union {
977989 }
978990
979991 /// Asserts the value is an integer.
980 pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {
981 switch (self.tag()) {
992 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {
993 switch (val.tag()) {
982994 .zero,
983995 .bool_false,
984996 .the_only_possible_value, // i0, u0
......@@ -988,19 +1000,25 @@ pub const Value = extern union {
9881000 .bool_true,
9891001 => return BigIntMutable.init(&space.limbs, 1).toConst(),
9901002
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(),
1003 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
1004 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
1005 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
1006 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
9951007
9961008 .undef => unreachable,
1009
1010 .lazy_align => {
1011 const x = val.castTag(.lazy_align).?.data.abiAlignment(target);
1012 return BigIntMutable.init(&space.limbs, x).toConst();
1013 },
1014
9971015 else => unreachable,
9981016 }
9991017 }
10001018
10011019 /// If the value fits in a u64, return it, otherwise null.
10021020 /// Asserts not undefined.
1003 pub fn getUnsignedInt(val: Value) ?u64 {
1021 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {
10041022 switch (val.tag()) {
10051023 .zero,
10061024 .bool_false,
......@@ -1017,13 +1035,16 @@ pub const Value = extern union {
10171035 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
10181036
10191037 .undef => unreachable,
1038
1039 .lazy_align => return val.castTag(.lazy_align).?.data.abiAlignment(target),
1040
10201041 else => return null,
10211042 }
10221043 }
10231044
10241045 /// Asserts the value is an integer and it fits in a u64
1025 pub fn toUnsignedInt(val: Value) u64 {
1026 return getUnsignedInt(val).?;
1046 pub fn toUnsignedInt(val: Value, target: Target) u64 {
1047 return getUnsignedInt(val, target).?;
10271048 }
10281049
10291050 /// Asserts the value is an integer and it fits in a i64
......@@ -1066,7 +1087,7 @@ pub const Value = extern union {
10661087 switch (ty.zigTypeTag()) {
10671088 .Int => {
10681089 var bigint_buffer: BigIntSpace = undefined;
1069 const bigint = val.toBigInt(&bigint_buffer);
1090 const bigint = val.toBigInt(&bigint_buffer, target);
10701091 const bits = ty.intInfo(target).bits;
10711092 const abi_size = @intCast(usize, ty.abiSize(target));
10721093 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
......@@ -1075,7 +1096,7 @@ pub const Value = extern union {
10751096 var enum_buffer: Payload.U64 = undefined;
10761097 const int_val = val.enumToInt(ty, &enum_buffer);
10771098 var bigint_buffer: BigIntSpace = undefined;
1078 const bigint = int_val.toBigInt(&bigint_buffer);
1099 const bigint = int_val.toBigInt(&bigint_buffer, target);
10791100 const bits = ty.intInfo(target).bits;
10801101 const abi_size = @intCast(usize, ty.abiSize(target));
10811102 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
......@@ -1151,7 +1172,7 @@ pub const Value = extern union {
11511172 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),
11521173 else => unreachable,
11531174 },
1154 .Int, .Bool => field_val.toBigInt(&field_space),
1175 .Int, .Bool => field_val.toBigInt(&field_space, target),
11551176 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),
11561177 else => unreachable,
11571178 };
......@@ -1511,7 +1532,7 @@ pub const Value = extern union {
15111532 const info = ty.intInfo(target);
15121533
15131534 var buffer: Value.BigIntSpace = undefined;
1514 const operand_bigint = val.toBigInt(&buffer);
1535 const operand_bigint = val.toBigInt(&buffer, target);
15151536
15161537 var limbs_buffer: [4]std.math.big.Limb = undefined;
15171538 var result_bigint = BigIntMutable{
......@@ -1532,7 +1553,7 @@ pub const Value = extern union {
15321553 const info = ty.intInfo(target);
15331554
15341555 var buffer: Value.BigIntSpace = undefined;
1535 const operand_bigint = val.toBigInt(&buffer);
1556 const operand_bigint = val.toBigInt(&buffer, target);
15361557
15371558 const limbs = try arena.alloc(
15381559 std.math.big.Limb,
......@@ -1553,7 +1574,7 @@ pub const Value = extern union {
15531574 assert(info.bits % 8 == 0);
15541575
15551576 var buffer: Value.BigIntSpace = undefined;
1556 const operand_bigint = val.toBigInt(&buffer);
1577 const operand_bigint = val.toBigInt(&buffer, target);
15571578
15581579 const limbs = try arena.alloc(
15591580 std.math.big.Limb,
......@@ -1597,7 +1618,7 @@ pub const Value = extern union {
15971618
15981619 else => {
15991620 var buffer: BigIntSpace = undefined;
1600 return self.toBigInt(&buffer).bitCountTwosComp();
1621 return self.toBigInt(&buffer, target).bitCountTwosComp();
16011622 },
16021623 }
16031624 }
......@@ -1624,6 +1645,17 @@ pub const Value = extern union {
16241645 else => unreachable,
16251646 },
16261647
1648 .lazy_align => {
1649 const info = ty.intInfo(target);
1650 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
1651 // If it is u16 or bigger we know the alignment fits without resolving it.
1652 if (info.bits >= max_needed_bits) return true;
1653 const x = self.castTag(.lazy_align).?.data.abiAlignment(target);
1654 if (x == 0) return true;
1655 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
1656 return info.bits >= actual_needed_bits;
1657 },
1658
16271659 .int_u64 => switch (ty.zigTypeTag()) {
16281660 .Int => {
16291661 const x = self.castTag(.int_u64).?.data;
......@@ -1643,7 +1675,7 @@ pub const Value = extern union {
16431675 if (info.signedness == .unsigned and x < 0)
16441676 return false;
16451677 var buffer: BigIntSpace = undefined;
1646 return self.toBigInt(&buffer).fitsInTwosComp(info.signedness, info.bits);
1678 return self.toBigInt(&buffer, target).fitsInTwosComp(info.signedness, info.bits);
16471679 },
16481680 .ComptimeInt => return true,
16491681 else => unreachable,
......@@ -1765,6 +1797,15 @@ pub const Value = extern union {
17651797 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
17661798 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
17671799
1800 .lazy_align => {
1801 const ty = lhs.castTag(.lazy_align).?.data;
1802 if (ty.hasRuntimeBitsIgnoreComptime()) {
1803 return .gt;
1804 } else {
1805 return .eq;
1806 }
1807 },
1808
17681809 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
17691810 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
17701811 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
......@@ -1776,7 +1817,7 @@ pub const Value = extern union {
17761817 }
17771818
17781819 /// Asserts the value is comparable.
1779 pub fn order(lhs: Value, rhs: Value) std.math.Order {
1820 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {
17801821 const lhs_tag = lhs.tag();
17811822 const rhs_tag = rhs.tag();
17821823 const lhs_against_zero = lhs.orderAgainstZero();
......@@ -1814,14 +1855,14 @@ pub const Value = extern union {
18141855
18151856 var lhs_bigint_space: BigIntSpace = undefined;
18161857 var rhs_bigint_space: BigIntSpace = undefined;
1817 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space);
1818 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space);
1858 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, target);
1859 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, target);
18191860 return lhs_bigint.order(rhs_bigint);
18201861 }
18211862
18221863 /// Asserts the value is comparable. Does not take a type parameter because it supports
18231864 /// comparisons between heterogeneous types.
1824 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value) bool {
1865 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {
18251866 if (lhs.pointerDecl()) |lhs_decl| {
18261867 if (rhs.pointerDecl()) |rhs_decl| {
18271868 switch (op) {
......@@ -1843,39 +1884,39 @@ pub const Value = extern union {
18431884 else => {},
18441885 }
18451886 }
1846 return order(lhs, rhs).compare(op);
1887 return order(lhs, rhs, target).compare(op);
18471888 }
18481889
18491890 /// Asserts the values are comparable. Both operands have type `ty`.
18501891 /// Vector results will be reduced with AND.
1851 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {
1892 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
18521893 if (ty.zigTypeTag() == .Vector) {
18531894 var i: usize = 0;
18541895 while (i < ty.vectorLen()) : (i += 1) {
1855 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType())) {
1896 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target)) {
18561897 return false;
18571898 }
18581899 }
18591900 return true;
18601901 }
1861 return compareScalar(lhs, op, rhs, ty);
1902 return compareScalar(lhs, op, rhs, ty, target);
18621903 }
18631904
18641905 /// 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 {
1906 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
18661907 return switch (op) {
1867 .eq => lhs.eql(rhs, ty),
1868 .neq => !lhs.eql(rhs, ty),
1869 else => compareHetero(lhs, op, rhs),
1908 .eq => lhs.eql(rhs, ty, target),
1909 .neq => !lhs.eql(rhs, ty, target),
1910 else => compareHetero(lhs, op, rhs, target),
18701911 };
18711912 }
18721913
18731914 /// 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 {
1915 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
18751916 assert(ty.zigTypeTag() == .Vector);
18761917 const result_data = try allocator.alloc(Value, ty.vectorLen());
18771918 for (result_data) |*scalar, i| {
1878 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType());
1919 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target);
18791920 scalar.* = if (res_bool) Value.@"true" else Value.@"false";
18801921 }
18811922 return Value.Tag.aggregate.create(allocator, result_data);
......@@ -1899,12 +1940,12 @@ pub const Value = extern union {
18991940
19001941 /// This function is used by hash maps and so treats floating-point NaNs as equal
19011942 /// to each other, and not equal to other floating-point values.
1902 pub fn eql(a: Value, b: Value, ty: Type) bool {
1943 /// Similarly, it treats `undef` as a distinct value from all other values.
1944 pub fn eql(a: Value, b: Value, ty: Type, target: Target) bool {
19031945 const a_tag = a.tag();
19041946 const b_tag = b.tag();
1905 assert(a_tag != .undef);
1906 assert(b_tag != .undef);
19071947 if (a_tag == b_tag) switch (a_tag) {
1948 .undef => return true,
19081949 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
19091950 .enum_literal => {
19101951 const a_name = a.castTag(.enum_literal).?.data;
......@@ -1920,31 +1961,31 @@ pub const Value = extern union {
19201961 const a_payload = a.castTag(.opt_payload).?.data;
19211962 const b_payload = b.castTag(.opt_payload).?.data;
19221963 var buffer: Type.Payload.ElemType = undefined;
1923 return eql(a_payload, b_payload, ty.optionalChild(&buffer));
1964 return eql(a_payload, b_payload, ty.optionalChild(&buffer), target);
19241965 },
19251966 .slice => {
19261967 const a_payload = a.castTag(.slice).?.data;
19271968 const b_payload = b.castTag(.slice).?.data;
1928 if (!eql(a_payload.len, b_payload.len, Type.usize)) return false;
1969 if (!eql(a_payload.len, b_payload.len, Type.usize, target)) return false;
19291970
19301971 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
19311972 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
19321973
1933 return eql(a_payload.ptr, b_payload.ptr, ptr_ty);
1974 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, target);
19341975 },
19351976 .elem_ptr => {
19361977 const a_payload = a.castTag(.elem_ptr).?.data;
19371978 const b_payload = b.castTag(.elem_ptr).?.data;
19381979 if (a_payload.index != b_payload.index) return false;
19391980
1940 return eql(a_payload.array_ptr, b_payload.array_ptr, ty);
1981 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, target);
19411982 },
19421983 .field_ptr => {
19431984 const a_payload = a.castTag(.field_ptr).?.data;
19441985 const b_payload = b.castTag(.field_ptr).?.data;
19451986 if (a_payload.field_index != b_payload.field_index) return false;
19461987
1947 return eql(a_payload.container_ptr, b_payload.container_ptr, ty);
1988 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, target);
19481989 },
19491990 .@"error" => {
19501991 const a_name = a.castTag(.@"error").?.data.name;
......@@ -1954,7 +1995,7 @@ pub const Value = extern union {
19541995 .eu_payload => {
19551996 const a_payload = a.castTag(.eu_payload).?.data;
19561997 const b_payload = b.castTag(.eu_payload).?.data;
1957 return eql(a_payload, b_payload, ty.errorUnionPayload());
1998 return eql(a_payload, b_payload, ty.errorUnionPayload(), target);
19581999 },
19592000 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
19602001 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
......@@ -1972,7 +2013,7 @@ pub const Value = extern union {
19722013 const types = ty.tupleFields().types;
19732014 assert(types.len == a_field_vals.len);
19742015 for (types) |field_ty, i| {
1975 if (!eql(a_field_vals[i], b_field_vals[i], field_ty)) return false;
2016 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, target)) return false;
19762017 }
19772018 return true;
19782019 }
......@@ -1981,7 +2022,7 @@ pub const Value = extern union {
19812022 const fields = ty.structFields().values();
19822023 assert(fields.len == a_field_vals.len);
19832024 for (fields) |field, i| {
1984 if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false;
2025 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, target)) return false;
19852026 }
19862027 return true;
19872028 }
......@@ -1990,7 +2031,7 @@ pub const Value = extern union {
19902031 for (a_field_vals) |a_elem, i| {
19912032 const b_elem = b_field_vals[i];
19922033
1993 if (!eql(a_elem, b_elem, elem_ty)) return false;
2034 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
19942035 }
19952036 return true;
19962037 },
......@@ -2005,17 +2046,19 @@ pub const Value = extern union {
20052046 },
20062047 .Auto => {
20072048 const tag_ty = ty.unionTagTypeHypothetical();
2008 if (!a_union.tag.eql(b_union.tag, tag_ty)) {
2049 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
20092050 return false;
20102051 }
2011 const active_field_ty = ty.unionFieldType(a_union.tag);
2012 return a_union.val.eql(b_union.val, active_field_ty);
2052 const active_field_ty = ty.unionFieldType(a_union.tag, target);
2053 return a_union.val.eql(b_union.val, active_field_ty, target);
20132054 },
20142055 }
20152056 },
20162057 else => {},
20172058 } else if (a_tag == .null_value or b_tag == .null_value) {
20182059 return false;
2060 } else if (a_tag == .undef or b_tag == .undef) {
2061 return false;
20192062 }
20202063
20212064 if (a.pointerDecl()) |a_decl| {
......@@ -2034,7 +2077,7 @@ pub const Value = extern union {
20342077 var buf_b: ToTypeBuffer = undefined;
20352078 const a_type = a.toType(&buf_a);
20362079 const b_type = b.toType(&buf_b);
2037 return a_type.eql(b_type);
2080 return a_type.eql(b_type, target);
20382081 },
20392082 .Enum => {
20402083 var buf_a: Payload.U64 = undefined;
......@@ -2043,7 +2086,7 @@ pub const Value = extern union {
20432086 const b_val = b.enumToInt(ty, &buf_b);
20442087 var buf_ty: Type.Payload.Bits = undefined;
20452088 const int_ty = ty.intTagType(&buf_ty);
2046 return eql(a_val, b_val, int_ty);
2089 return eql(a_val, b_val, int_ty, target);
20472090 },
20482091 .Array, .Vector => {
20492092 const len = ty.arrayLen();
......@@ -2054,7 +2097,7 @@ pub const Value = extern union {
20542097 while (i < len) : (i += 1) {
20552098 const a_elem = elemValueBuffer(a, i, &a_buf);
20562099 const b_elem = elemValueBuffer(b, i, &b_buf);
2057 if (!eql(a_elem, b_elem, elem_ty)) return false;
2100 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
20582101 }
20592102 return true;
20602103 },
......@@ -2070,15 +2113,15 @@ pub const Value = extern union {
20702113 if (a_nan or b_nan) {
20712114 return a_nan and b_nan;
20722115 }
2073 return order(a, b).compare(.eq);
2116 return order(a, b, target).compare(.eq);
20742117 },
2075 else => return order(a, b).compare(.eq),
2118 else => return order(a, b, target).compare(.eq),
20762119 }
20772120 }
20782121
20792122 /// This function is used by hash maps and so treats floating-point NaNs as equal
20802123 /// to each other, and not equal to other floating-point values.
2081 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash) void {
2124 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
20822125 const zig_ty_tag = ty.zigTypeTag();
20832126 std.hash.autoHash(hasher, zig_ty_tag);
20842127 if (val.isUndef()) return;
......@@ -2095,7 +2138,7 @@ pub const Value = extern union {
20952138
20962139 .Type => {
20972140 var buf: ToTypeBuffer = undefined;
2098 return val.toType(&buf).hashWithHasher(hasher);
2141 return val.toType(&buf).hashWithHasher(hasher, target);
20992142 },
21002143 .Float, .ComptimeFloat => {
21012144 // Normalize the float here because this hash must match eql semantics.
......@@ -2116,11 +2159,11 @@ pub const Value = extern union {
21162159 const slice = val.castTag(.slice).?.data;
21172160 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
21182161 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2119 hash(slice.ptr, ptr_ty, hasher);
2120 hash(slice.len, Type.usize, hasher);
2162 hash(slice.ptr, ptr_ty, hasher, target);
2163 hash(slice.len, Type.usize, hasher, target);
21212164 },
21222165
2123 else => return hashPtr(val, hasher),
2166 else => return hashPtr(val, hasher, target),
21242167 },
21252168 .Array, .Vector => {
21262169 const len = ty.arrayLen();
......@@ -2129,14 +2172,14 @@ pub const Value = extern union {
21292172 var elem_value_buf: ElemValueBuffer = undefined;
21302173 while (index < len) : (index += 1) {
21312174 const elem_val = val.elemValueBuffer(index, &elem_value_buf);
2132 elem_val.hash(elem_ty, hasher);
2175 elem_val.hash(elem_ty, hasher, target);
21332176 }
21342177 },
21352178 .Struct => {
21362179 if (ty.isTupleOrAnonStruct()) {
21372180 const fields = ty.tupleFields();
21382181 for (fields.values) |field_val, i| {
2139 field_val.hash(fields.types[i], hasher);
2182 field_val.hash(fields.types[i], hasher, target);
21402183 }
21412184 return;
21422185 }
......@@ -2145,13 +2188,13 @@ pub const Value = extern union {
21452188 switch (val.tag()) {
21462189 .empty_struct_value => {
21472190 for (fields) |field| {
2148 field.default_val.hash(field.ty, hasher);
2191 field.default_val.hash(field.ty, hasher, target);
21492192 }
21502193 },
21512194 .aggregate => {
21522195 const field_values = val.castTag(.aggregate).?.data;
21532196 for (field_values) |field_val, i| {
2154 field_val.hash(fields[i].ty, hasher);
2197 field_val.hash(fields[i].ty, hasher, target);
21552198 }
21562199 },
21572200 else => unreachable,
......@@ -2163,7 +2206,7 @@ pub const Value = extern union {
21632206 const sub_val = payload.data;
21642207 var buffer: Type.Payload.ElemType = undefined;
21652208 const sub_ty = ty.optionalChild(&buffer);
2166 sub_val.hash(sub_ty, hasher);
2209 sub_val.hash(sub_ty, hasher, target);
21672210 } else {
21682211 std.hash.autoHash(hasher, false); // non-null
21692212 }
......@@ -2172,14 +2215,14 @@ pub const Value = extern union {
21722215 if (val.tag() == .@"error") {
21732216 std.hash.autoHash(hasher, false); // error
21742217 const sub_ty = ty.errorUnionSet();
2175 val.hash(sub_ty, hasher);
2218 val.hash(sub_ty, hasher, target);
21762219 return;
21772220 }
21782221
21792222 if (val.castTag(.eu_payload)) |payload| {
21802223 std.hash.autoHash(hasher, true); // payload
21812224 const sub_ty = ty.errorUnionPayload();
2182 payload.data.hash(sub_ty, hasher);
2225 payload.data.hash(sub_ty, hasher, target);
21832226 return;
21842227 } else unreachable;
21852228 },
......@@ -2192,15 +2235,15 @@ pub const Value = extern union {
21922235 .Enum => {
21932236 var enum_space: Payload.U64 = undefined;
21942237 const int_val = val.enumToInt(ty, &enum_space);
2195 hashInt(int_val, hasher);
2238 hashInt(int_val, hasher, target);
21962239 },
21972240 .Union => {
21982241 const union_obj = val.cast(Payload.Union).?.data;
21992242 if (ty.unionTagType()) |tag_ty| {
2200 union_obj.tag.hash(tag_ty, hasher);
2243 union_obj.tag.hash(tag_ty, hasher, target);
22012244 }
2202 const active_field_ty = ty.unionFieldType(union_obj.tag);
2203 union_obj.val.hash(active_field_ty, hasher);
2245 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
2246 union_obj.val.hash(active_field_ty, hasher, target);
22042247 },
22052248 .Fn => {
22062249 const func: *Module.Fn = val.castTag(.function).?.data;
......@@ -2225,28 +2268,30 @@ pub const Value = extern union {
22252268
22262269 pub const ArrayHashContext = struct {
22272270 ty: Type,
2271 target: Target,
22282272
22292273 pub fn hash(self: @This(), val: Value) u32 {
2230 const other_context: HashContext = .{ .ty = self.ty };
2274 const other_context: HashContext = .{ .ty = self.ty, .target = self.target };
22312275 return @truncate(u32, other_context.hash(val));
22322276 }
22332277 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {
22342278 _ = b_index;
2235 return a.eql(b, self.ty);
2279 return a.eql(b, self.ty, self.target);
22362280 }
22372281 };
22382282
22392283 pub const HashContext = struct {
22402284 ty: Type,
2285 target: Target,
22412286
22422287 pub fn hash(self: @This(), val: Value) u64 {
22432288 var hasher = std.hash.Wyhash.init(0);
2244 val.hash(self.ty, &hasher);
2289 val.hash(self.ty, &hasher, self.target);
22452290 return hasher.final();
22462291 }
22472292
22482293 pub fn eql(self: @This(), a: Value, b: Value) bool {
2249 return a.eql(b, self.ty);
2294 return a.eql(b, self.ty, self.target);
22502295 }
22512296 };
22522297
......@@ -2296,16 +2341,16 @@ pub const Value = extern union {
22962341 };
22972342 }
22982343
2299 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash) void {
2344 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
23002345 var buffer: BigIntSpace = undefined;
2301 const big = int_val.toBigInt(&buffer);
2346 const big = int_val.toBigInt(&buffer, target);
23022347 std.hash.autoHash(hasher, big.positive);
23032348 for (big.limbs) |limb| {
23042349 std.hash.autoHash(hasher, limb);
23052350 }
23062351 }
23072352
2308 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash) void {
2353 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
23092354 switch (ptr_val.tag()) {
23102355 .decl_ref,
23112356 .decl_ref_mut,
......@@ -2319,25 +2364,25 @@ pub const Value = extern union {
23192364
23202365 .elem_ptr => {
23212366 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2322 hashPtr(elem_ptr.array_ptr, hasher);
2367 hashPtr(elem_ptr.array_ptr, hasher, target);
23232368 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
23242369 std.hash.autoHash(hasher, elem_ptr.index);
23252370 },
23262371 .field_ptr => {
23272372 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
23282373 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2329 hashPtr(field_ptr.container_ptr, hasher);
2374 hashPtr(field_ptr.container_ptr, hasher, target);
23302375 std.hash.autoHash(hasher, field_ptr.field_index);
23312376 },
23322377 .eu_payload_ptr => {
23332378 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
23342379 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2335 hashPtr(err_union_ptr.container_ptr, hasher);
2380 hashPtr(err_union_ptr.container_ptr, hasher, target);
23362381 },
23372382 .opt_payload_ptr => {
23382383 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
23392384 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2340 hashPtr(opt_ptr.container_ptr, hasher);
2385 hashPtr(opt_ptr.container_ptr, hasher, target);
23412386 },
23422387
23432388 .zero,
......@@ -2349,7 +2394,7 @@ pub const Value = extern union {
23492394 .bool_false,
23502395 .bool_true,
23512396 .the_only_possible_value,
2352 => return hashInt(ptr_val, hasher),
2397 => return hashInt(ptr_val, hasher, target),
23532398
23542399 else => unreachable,
23552400 }
......@@ -2411,9 +2456,9 @@ pub const Value = extern union {
24112456 };
24122457 }
24132458
2414 pub fn sliceLen(val: Value) u64 {
2459 pub fn sliceLen(val: Value, target: Target) u64 {
24152460 return switch (val.tag()) {
2416 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(),
2461 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(target),
24172462 .decl_ref => {
24182463 const decl = val.castTag(.decl_ref).?.data;
24192464 if (decl.ty.zigTypeTag() == .Array) {
......@@ -2561,7 +2606,7 @@ pub const Value = extern union {
25612606 }
25622607
25632608 /// 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 {
2609 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize, target: Target) Allocator.Error!Value {
25652610 const elem_ty = ty.elemType2();
25662611 const ptr_val = switch (val.tag()) {
25672612 .slice => val.castTag(.slice).?.data.ptr,
......@@ -2570,7 +2615,7 @@ pub const Value = extern union {
25702615
25712616 if (ptr_val.tag() == .elem_ptr) {
25722617 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2573 if (elem_ptr.elem_ty.eql(elem_ty)) {
2618 if (elem_ptr.elem_ty.eql(elem_ty, target)) {
25742619 return Tag.elem_ptr.create(arena, .{
25752620 .array_ptr = elem_ptr.array_ptr,
25762621 .elem_ty = elem_ptr.elem_ty,
......@@ -2821,8 +2866,8 @@ pub const Value = extern union {
28212866
28222867 var lhs_space: Value.BigIntSpace = undefined;
28232868 var rhs_space: Value.BigIntSpace = undefined;
2824 const lhs_bigint = lhs.toBigInt(&lhs_space);
2825 const rhs_bigint = rhs.toBigInt(&rhs_space);
2869 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2870 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
28262871 const limbs = try arena.alloc(
28272872 std.math.big.Limb,
28282873 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2865,7 +2910,7 @@ pub const Value = extern union {
28652910 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
28662911
28672912 if (ty.zigTypeTag() == .ComptimeInt) {
2868 return intAdd(lhs, rhs, ty, arena);
2913 return intAdd(lhs, rhs, ty, arena, target);
28692914 }
28702915
28712916 if (ty.isAnyFloat()) {
......@@ -2925,8 +2970,8 @@ pub const Value = extern union {
29252970
29262971 var lhs_space: Value.BigIntSpace = undefined;
29272972 var rhs_space: Value.BigIntSpace = undefined;
2928 const lhs_bigint = lhs.toBigInt(&lhs_space);
2929 const rhs_bigint = rhs.toBigInt(&rhs_space);
2973 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2974 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
29302975 const limbs = try arena.alloc(
29312976 std.math.big.Limb,
29322977 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2947,8 +2992,8 @@ pub const Value = extern union {
29472992
29482993 var lhs_space: Value.BigIntSpace = undefined;
29492994 var rhs_space: Value.BigIntSpace = undefined;
2950 const lhs_bigint = lhs.toBigInt(&lhs_space);
2951 const rhs_bigint = rhs.toBigInt(&rhs_space);
2995 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2996 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
29522997 const limbs = try arena.alloc(
29532998 std.math.big.Limb,
29542999 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -2991,7 +3036,7 @@ pub const Value = extern union {
29913036 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
29923037
29933038 if (ty.zigTypeTag() == .ComptimeInt) {
2994 return intSub(lhs, rhs, ty, arena);
3039 return intSub(lhs, rhs, ty, arena, target);
29953040 }
29963041
29973042 if (ty.isAnyFloat()) {
......@@ -3035,8 +3080,8 @@ pub const Value = extern union {
30353080
30363081 var lhs_space: Value.BigIntSpace = undefined;
30373082 var rhs_space: Value.BigIntSpace = undefined;
3038 const lhs_bigint = lhs.toBigInt(&lhs_space);
3039 const rhs_bigint = rhs.toBigInt(&rhs_space);
3083 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3084 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
30403085 const limbs = try arena.alloc(
30413086 std.math.big.Limb,
30423087 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3057,8 +3102,8 @@ pub const Value = extern union {
30573102
30583103 var lhs_space: Value.BigIntSpace = undefined;
30593104 var rhs_space: Value.BigIntSpace = undefined;
3060 const lhs_bigint = lhs.toBigInt(&lhs_space);
3061 const rhs_bigint = rhs.toBigInt(&rhs_space);
3105 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3106 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
30623107 const limbs = try arena.alloc(
30633108 std.math.big.Limb,
30643109 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -3110,7 +3155,7 @@ pub const Value = extern union {
31103155 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
31113156
31123157 if (ty.zigTypeTag() == .ComptimeInt) {
3113 return intMul(lhs, rhs, ty, arena);
3158 return intMul(lhs, rhs, ty, arena, target);
31143159 }
31153160
31163161 if (ty.isAnyFloat()) {
......@@ -3154,8 +3199,8 @@ pub const Value = extern union {
31543199
31553200 var lhs_space: Value.BigIntSpace = undefined;
31563201 var rhs_space: Value.BigIntSpace = undefined;
3157 const lhs_bigint = lhs.toBigInt(&lhs_space);
3158 const rhs_bigint = rhs.toBigInt(&rhs_space);
3202 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3203 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
31593204 const limbs = try arena.alloc(
31603205 std.math.big.Limb,
31613206 std.math.max(
......@@ -3175,24 +3220,24 @@ pub const Value = extern union {
31753220 }
31763221
31773222 /// Supports both floats and ints; handles undefined.
3178 pub fn numberMax(lhs: Value, rhs: Value) Value {
3223 pub fn numberMax(lhs: Value, rhs: Value, target: Target) Value {
31793224 if (lhs.isUndef() or rhs.isUndef()) return undef;
31803225 if (lhs.isNan()) return rhs;
31813226 if (rhs.isNan()) return lhs;
31823227
3183 return switch (order(lhs, rhs)) {
3228 return switch (order(lhs, rhs, target)) {
31843229 .lt => rhs,
31853230 .gt, .eq => lhs,
31863231 };
31873232 }
31883233
31893234 /// Supports both floats and ints; handles undefined.
3190 pub fn numberMin(lhs: Value, rhs: Value) Value {
3235 pub fn numberMin(lhs: Value, rhs: Value, target: Target) Value {
31913236 if (lhs.isUndef() or rhs.isUndef()) return undef;
31923237 if (lhs.isNan()) return rhs;
31933238 if (rhs.isNan()) return lhs;
31943239
3195 return switch (order(lhs, rhs)) {
3240 return switch (order(lhs, rhs, target)) {
31963241 .lt => lhs,
31973242 .gt, .eq => rhs,
31983243 };
......@@ -3224,7 +3269,7 @@ pub const Value = extern union {
32243269 // TODO is this a performance issue? maybe we should try the operation without
32253270 // resorting to BigInt first.
32263271 var val_space: Value.BigIntSpace = undefined;
3227 const val_bigint = val.toBigInt(&val_space);
3272 const val_bigint = val.toBigInt(&val_space, target);
32283273 const limbs = try arena.alloc(
32293274 std.math.big.Limb,
32303275 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3236,27 +3281,27 @@ pub const Value = extern union {
32363281 }
32373282
32383283 /// operands must be (vectors of) integers; handles undefined scalars.
3239 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3284 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
32403285 if (ty.zigTypeTag() == .Vector) {
32413286 const result_data = try allocator.alloc(Value, ty.vectorLen());
32423287 for (result_data) |*scalar, i| {
3243 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3288 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
32443289 }
32453290 return Value.Tag.aggregate.create(allocator, result_data);
32463291 }
3247 return bitwiseAndScalar(lhs, rhs, allocator);
3292 return bitwiseAndScalar(lhs, rhs, allocator, target);
32483293 }
32493294
32503295 /// operands must be integers; handles undefined.
3251 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3296 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
32523297 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32533298
32543299 // TODO is this a performance issue? maybe we should try the operation without
32553300 // resorting to BigInt first.
32563301 var lhs_space: Value.BigIntSpace = undefined;
32573302 var rhs_space: Value.BigIntSpace = undefined;
3258 const lhs_bigint = lhs.toBigInt(&lhs_space);
3259 const rhs_bigint = rhs.toBigInt(&rhs_space);
3303 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3304 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
32603305 const limbs = try arena.alloc(
32613306 std.math.big.Limb,
32623307 // + 1 for negatives
......@@ -3283,38 +3328,38 @@ pub const Value = extern union {
32833328 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {
32843329 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32853330
3286 const anded = try bitwiseAnd(lhs, rhs, ty, arena);
3331 const anded = try bitwiseAnd(lhs, rhs, ty, arena, target);
32873332
32883333 const all_ones = if (ty.isSignedInt())
32893334 try Value.Tag.int_i64.create(arena, -1)
32903335 else
32913336 try ty.maxInt(arena, target);
32923337
3293 return bitwiseXor(anded, all_ones, ty, arena);
3338 return bitwiseXor(anded, all_ones, ty, arena, target);
32943339 }
32953340
32963341 /// operands must be (vectors of) integers; handles undefined scalars.
3297 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3342 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
32983343 if (ty.zigTypeTag() == .Vector) {
32993344 const result_data = try allocator.alloc(Value, ty.vectorLen());
33003345 for (result_data) |*scalar, i| {
3301 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3346 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33023347 }
33033348 return Value.Tag.aggregate.create(allocator, result_data);
33043349 }
3305 return bitwiseOrScalar(lhs, rhs, allocator);
3350 return bitwiseOrScalar(lhs, rhs, allocator, target);
33063351 }
33073352
33083353 /// operands must be integers; handles undefined.
3309 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3354 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
33103355 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33113356
33123357 // TODO is this a performance issue? maybe we should try the operation without
33133358 // resorting to BigInt first.
33143359 var lhs_space: Value.BigIntSpace = undefined;
33153360 var rhs_space: Value.BigIntSpace = undefined;
3316 const lhs_bigint = lhs.toBigInt(&lhs_space);
3317 const rhs_bigint = rhs.toBigInt(&rhs_space);
3361 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3362 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33183363 const limbs = try arena.alloc(
33193364 std.math.big.Limb,
33203365 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
......@@ -3325,27 +3370,27 @@ pub const Value = extern union {
33253370 }
33263371
33273372 /// operands must be (vectors of) integers; handles undefined scalars.
3328 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3373 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33293374 if (ty.zigTypeTag() == .Vector) {
33303375 const result_data = try allocator.alloc(Value, ty.vectorLen());
33313376 for (result_data) |*scalar, i| {
3332 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3377 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33333378 }
33343379 return Value.Tag.aggregate.create(allocator, result_data);
33353380 }
3336 return bitwiseXorScalar(lhs, rhs, allocator);
3381 return bitwiseXorScalar(lhs, rhs, allocator, target);
33373382 }
33383383
33393384 /// operands must be integers; handles undefined.
3340 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {
3385 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
33413386 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33423387
33433388 // TODO is this a performance issue? maybe we should try the operation without
33443389 // resorting to BigInt first.
33453390 var lhs_space: Value.BigIntSpace = undefined;
33463391 var rhs_space: Value.BigIntSpace = undefined;
3347 const lhs_bigint = lhs.toBigInt(&lhs_space);
3348 const rhs_bigint = rhs.toBigInt(&rhs_space);
3392 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3393 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33493394 const limbs = try arena.alloc(
33503395 std.math.big.Limb,
33513396 // + 1 for negatives
......@@ -3356,24 +3401,24 @@ pub const Value = extern union {
33563401 return fromBigInt(arena, result_bigint.toConst());
33573402 }
33583403
3359 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3404 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33603405 if (ty.zigTypeTag() == .Vector) {
33613406 const result_data = try allocator.alloc(Value, ty.vectorLen());
33623407 for (result_data) |*scalar, i| {
3363 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3408 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33643409 }
33653410 return Value.Tag.aggregate.create(allocator, result_data);
33663411 }
3367 return intAddScalar(lhs, rhs, allocator);
3412 return intAddScalar(lhs, rhs, allocator, target);
33683413 }
33693414
3370 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3415 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
33713416 // TODO is this a performance issue? maybe we should try the operation without
33723417 // resorting to BigInt first.
33733418 var lhs_space: Value.BigIntSpace = undefined;
33743419 var rhs_space: Value.BigIntSpace = undefined;
3375 const lhs_bigint = lhs.toBigInt(&lhs_space);
3376 const rhs_bigint = rhs.toBigInt(&rhs_space);
3420 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3421 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
33773422 const limbs = try allocator.alloc(
33783423 std.math.big.Limb,
33793424 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -3383,24 +3428,24 @@ pub const Value = extern union {
33833428 return fromBigInt(allocator, result_bigint.toConst());
33843429 }
33853430
3386 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3431 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
33873432 if (ty.zigTypeTag() == .Vector) {
33883433 const result_data = try allocator.alloc(Value, ty.vectorLen());
33893434 for (result_data) |*scalar, i| {
3390 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3435 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
33913436 }
33923437 return Value.Tag.aggregate.create(allocator, result_data);
33933438 }
3394 return intSubScalar(lhs, rhs, allocator);
3439 return intSubScalar(lhs, rhs, allocator, target);
33953440 }
33963441
3397 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3442 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
33983443 // TODO is this a performance issue? maybe we should try the operation without
33993444 // resorting to BigInt first.
34003445 var lhs_space: Value.BigIntSpace = undefined;
34013446 var rhs_space: Value.BigIntSpace = undefined;
3402 const lhs_bigint = lhs.toBigInt(&lhs_space);
3403 const rhs_bigint = rhs.toBigInt(&rhs_space);
3447 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3448 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34043449 const limbs = try allocator.alloc(
34053450 std.math.big.Limb,
34063451 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -3410,24 +3455,24 @@ pub const Value = extern union {
34103455 return fromBigInt(allocator, result_bigint.toConst());
34113456 }
34123457
3413 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3458 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34143459 if (ty.zigTypeTag() == .Vector) {
34153460 const result_data = try allocator.alloc(Value, ty.vectorLen());
34163461 for (result_data) |*scalar, i| {
3417 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3462 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34183463 }
34193464 return Value.Tag.aggregate.create(allocator, result_data);
34203465 }
3421 return intDivScalar(lhs, rhs, allocator);
3466 return intDivScalar(lhs, rhs, allocator, target);
34223467 }
34233468
3424 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3469 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34253470 // TODO is this a performance issue? maybe we should try the operation without
34263471 // resorting to BigInt first.
34273472 var lhs_space: Value.BigIntSpace = undefined;
34283473 var rhs_space: Value.BigIntSpace = undefined;
3429 const lhs_bigint = lhs.toBigInt(&lhs_space);
3430 const rhs_bigint = rhs.toBigInt(&rhs_space);
3474 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3475 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34313476 const limbs_q = try allocator.alloc(
34323477 std.math.big.Limb,
34333478 lhs_bigint.limbs.len,
......@@ -3446,24 +3491,24 @@ pub const Value = extern union {
34463491 return fromBigInt(allocator, result_q.toConst());
34473492 }
34483493
3449 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3494 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34503495 if (ty.zigTypeTag() == .Vector) {
34513496 const result_data = try allocator.alloc(Value, ty.vectorLen());
34523497 for (result_data) |*scalar, i| {
3453 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3498 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34543499 }
34553500 return Value.Tag.aggregate.create(allocator, result_data);
34563501 }
3457 return intDivFloorScalar(lhs, rhs, allocator);
3502 return intDivFloorScalar(lhs, rhs, allocator, target);
34583503 }
34593504
3460 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3505 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34613506 // TODO is this a performance issue? maybe we should try the operation without
34623507 // resorting to BigInt first.
34633508 var lhs_space: Value.BigIntSpace = undefined;
34643509 var rhs_space: Value.BigIntSpace = undefined;
3465 const lhs_bigint = lhs.toBigInt(&lhs_space);
3466 const rhs_bigint = rhs.toBigInt(&rhs_space);
3510 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3511 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
34673512 const limbs_q = try allocator.alloc(
34683513 std.math.big.Limb,
34693514 lhs_bigint.limbs.len,
......@@ -3482,24 +3527,24 @@ pub const Value = extern union {
34823527 return fromBigInt(allocator, result_q.toConst());
34833528 }
34843529
3485 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3530 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
34863531 if (ty.zigTypeTag() == .Vector) {
34873532 const result_data = try allocator.alloc(Value, ty.vectorLen());
34883533 for (result_data) |*scalar, i| {
3489 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3534 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
34903535 }
34913536 return Value.Tag.aggregate.create(allocator, result_data);
34923537 }
3493 return intRemScalar(lhs, rhs, allocator);
3538 return intRemScalar(lhs, rhs, allocator, target);
34943539 }
34953540
3496 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3541 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
34973542 // TODO is this a performance issue? maybe we should try the operation without
34983543 // resorting to BigInt first.
34993544 var lhs_space: Value.BigIntSpace = undefined;
35003545 var rhs_space: Value.BigIntSpace = undefined;
3501 const lhs_bigint = lhs.toBigInt(&lhs_space);
3502 const rhs_bigint = rhs.toBigInt(&rhs_space);
3546 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3547 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
35033548 const limbs_q = try allocator.alloc(
35043549 std.math.big.Limb,
35053550 lhs_bigint.limbs.len,
......@@ -3520,24 +3565,24 @@ pub const Value = extern union {
35203565 return fromBigInt(allocator, result_r.toConst());
35213566 }
35223567
3523 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3568 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
35243569 if (ty.zigTypeTag() == .Vector) {
35253570 const result_data = try allocator.alloc(Value, ty.vectorLen());
35263571 for (result_data) |*scalar, i| {
3527 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3572 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
35283573 }
35293574 return Value.Tag.aggregate.create(allocator, result_data);
35303575 }
3531 return intModScalar(lhs, rhs, allocator);
3576 return intModScalar(lhs, rhs, allocator, target);
35323577 }
35333578
3534 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3579 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
35353580 // TODO is this a performance issue? maybe we should try the operation without
35363581 // resorting to BigInt first.
35373582 var lhs_space: Value.BigIntSpace = undefined;
35383583 var rhs_space: Value.BigIntSpace = undefined;
3539 const lhs_bigint = lhs.toBigInt(&lhs_space);
3540 const rhs_bigint = rhs.toBigInt(&rhs_space);
3584 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3585 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
35413586 const limbs_q = try allocator.alloc(
35423587 std.math.big.Limb,
35433588 lhs_bigint.limbs.len,
......@@ -3658,24 +3703,24 @@ pub const Value = extern union {
36583703 }
36593704 }
36603705
3661 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3706 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
36623707 if (ty.zigTypeTag() == .Vector) {
36633708 const result_data = try allocator.alloc(Value, ty.vectorLen());
36643709 for (result_data) |*scalar, i| {
3665 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3710 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
36663711 }
36673712 return Value.Tag.aggregate.create(allocator, result_data);
36683713 }
3669 return intMulScalar(lhs, rhs, allocator);
3714 return intMulScalar(lhs, rhs, allocator, target);
36703715 }
36713716
3672 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3717 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
36733718 // TODO is this a performance issue? maybe we should try the operation without
36743719 // resorting to BigInt first.
36753720 var lhs_space: Value.BigIntSpace = undefined;
36763721 var rhs_space: Value.BigIntSpace = undefined;
3677 const lhs_bigint = lhs.toBigInt(&lhs_space);
3678 const rhs_bigint = rhs.toBigInt(&rhs_space);
3722 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3723 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
36793724 const limbs = try allocator.alloc(
36803725 std.math.big.Limb,
36813726 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -3690,34 +3735,41 @@ pub const Value = extern union {
36903735 return fromBigInt(allocator, result_bigint.toConst());
36913736 }
36923737
3693 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
3738 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
36943739 if (ty.zigTypeTag() == .Vector) {
36953740 const result_data = try allocator.alloc(Value, ty.vectorLen());
36963741 for (result_data) |*scalar, i| {
3697 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits);
3742 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits, target);
36983743 }
36993744 return Value.Tag.aggregate.create(allocator, result_data);
37003745 }
3701 return intTruncScalar(val, allocator, signedness, bits);
3746 return intTruncScalar(val, allocator, signedness, bits, target);
37023747 }
37033748
37043749 /// 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 {
3750 pub fn intTruncBitsAsValue(
3751 val: Value,
3752 ty: Type,
3753 allocator: Allocator,
3754 signedness: std.builtin.Signedness,
3755 bits: Value,
3756 target: Target,
3757 ) !Value {
37063758 if (ty.zigTypeTag() == .Vector) {
37073759 const result_data = try allocator.alloc(Value, ty.vectorLen());
37083760 for (result_data) |*scalar, i| {
3709 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt()));
3761 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt(target)), target);
37103762 }
37113763 return Value.Tag.aggregate.create(allocator, result_data);
37123764 }
3713 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt()));
3765 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);
37143766 }
37153767
3716 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {
3768 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
37173769 if (bits == 0) return Value.zero;
37183770
37193771 var val_space: Value.BigIntSpace = undefined;
3720 const val_bigint = val.toBigInt(&val_space);
3772 const val_bigint = val.toBigInt(&val_space, target);
37213773
37223774 const limbs = try allocator.alloc(
37233775 std.math.big.Limb,
......@@ -3729,23 +3781,23 @@ pub const Value = extern union {
37293781 return fromBigInt(allocator, result_bigint.toConst());
37303782 }
37313783
3732 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3784 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
37333785 if (ty.zigTypeTag() == .Vector) {
37343786 const result_data = try allocator.alloc(Value, ty.vectorLen());
37353787 for (result_data) |*scalar, i| {
3736 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3788 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
37373789 }
37383790 return Value.Tag.aggregate.create(allocator, result_data);
37393791 }
3740 return shlScalar(lhs, rhs, allocator);
3792 return shlScalar(lhs, rhs, allocator, target);
37413793 }
37423794
3743 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3795 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
37443796 // TODO is this a performance issue? maybe we should try the operation without
37453797 // resorting to BigInt first.
37463798 var lhs_space: Value.BigIntSpace = undefined;
3747 const lhs_bigint = lhs.toBigInt(&lhs_space);
3748 const shift = @intCast(usize, rhs.toUnsignedInt());
3799 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3800 const shift = @intCast(usize, rhs.toUnsignedInt(target));
37493801 const limbs = try allocator.alloc(
37503802 std.math.big.Limb,
37513803 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -3768,8 +3820,8 @@ pub const Value = extern union {
37683820 ) !OverflowArithmeticResult {
37693821 const info = ty.intInfo(target);
37703822 var lhs_space: Value.BigIntSpace = undefined;
3771 const lhs_bigint = lhs.toBigInt(&lhs_space);
3772 const shift = @intCast(usize, rhs.toUnsignedInt());
3823 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3824 const shift = @intCast(usize, rhs.toUnsignedInt(target));
37733825 const limbs = try allocator.alloc(
37743826 std.math.big.Limb,
37753827 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
......@@ -3819,8 +3871,8 @@ pub const Value = extern union {
38193871 const info = ty.intInfo(target);
38203872
38213873 var lhs_space: Value.BigIntSpace = undefined;
3822 const lhs_bigint = lhs.toBigInt(&lhs_space);
3823 const shift = @intCast(usize, rhs.toUnsignedInt());
3874 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3875 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38243876 const limbs = try arena.alloc(
38253877 std.math.big.Limb,
38263878 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -3858,29 +3910,29 @@ pub const Value = extern union {
38583910 arena: Allocator,
38593911 target: Target,
38603912 ) !Value {
3861 const shifted = try lhs.shl(rhs, ty, arena);
3913 const shifted = try lhs.shl(rhs, ty, arena, target);
38623914 const int_info = ty.intInfo(target);
3863 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits);
3915 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, target);
38643916 return truncated;
38653917 }
38663918
3867 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {
3919 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
38683920 if (ty.zigTypeTag() == .Vector) {
38693921 const result_data = try allocator.alloc(Value, ty.vectorLen());
38703922 for (result_data) |*scalar, i| {
3871 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);
3923 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
38723924 }
38733925 return Value.Tag.aggregate.create(allocator, result_data);
38743926 }
3875 return shrScalar(lhs, rhs, allocator);
3927 return shrScalar(lhs, rhs, allocator, target);
38763928 }
38773929
3878 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {
3930 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
38793931 // TODO is this a performance issue? maybe we should try the operation without
38803932 // resorting to BigInt first.
38813933 var lhs_space: Value.BigIntSpace = undefined;
3882 const lhs_bigint = lhs.toBigInt(&lhs_space);
3883 const shift = @intCast(usize, rhs.toUnsignedInt());
3934 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3935 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38843936
38853937 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
38863938 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}