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

Merge pull request #11260 from ziglang/lazy-alignof

stage2: lazy `@alignOf`

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

src/Compilation.zig+3-1
...@@ -2781,7 +2781,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress...@@ -2781,7 +2781,9 @@ fn processOneJob(comp: *Compilation, job: Job, main_progress_node: *std.Progress
2781 .error_msg = null,2781 .error_msg = null,
2782 .decl = decl,2782 .decl = decl,
2783 .fwd_decl = fwd_decl.toManaged(gpa),2783 .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 }),
2785 .typedefs_arena = typedefs_arena.allocator(),2787 .typedefs_arena = typedefs_arena.allocator(),
2786 };2788 };
2787 defer dg.fwd_decl.deinit();2789 defer dg.fwd_decl.deinit();
src/Module.zig+25-33
...@@ -146,6 +146,8 @@ const MonomorphedFuncsSet = std.HashMapUnmanaged(...@@ -146,6 +146,8 @@ const MonomorphedFuncsSet = std.HashMapUnmanaged(
146);146);
147147
148const MonomorphedFuncsContext = struct {148const MonomorphedFuncsContext = struct {
149 target: Target,
150
149 pub fn eql(ctx: @This(), a: *Fn, b: *Fn) bool {151 pub fn eql(ctx: @This(), a: *Fn, b: *Fn) bool {
150 _ = ctx;152 _ = ctx;
151 return a == b;153 return a == b;
...@@ -153,7 +155,6 @@ const MonomorphedFuncsContext = struct {...@@ -153,7 +155,6 @@ const MonomorphedFuncsContext = struct {
153155
154 /// Must match `Sema.GenericCallAdapter.hash`.156 /// Must match `Sema.GenericCallAdapter.hash`.
155 pub fn hash(ctx: @This(), key: *Fn) u64 {157 pub fn hash(ctx: @This(), key: *Fn) u64 {
156 _ = ctx;
157 var hasher = std.hash.Wyhash.init(0);158 var hasher = std.hash.Wyhash.init(0);
158159
159 // The generic function Decl is guaranteed to be the first dependency160 // The generic function Decl is guaranteed to be the first dependency
...@@ -168,7 +169,7 @@ const MonomorphedFuncsContext = struct {...@@ -168,7 +169,7 @@ const MonomorphedFuncsContext = struct {
168 const generic_ty_info = generic_owner_decl.ty.fnInfo();169 const generic_ty_info = generic_owner_decl.ty.fnInfo();
169 for (generic_ty_info.param_types) |param_ty, i| {170 for (generic_ty_info.param_types) |param_ty, i| {
170 if (generic_ty_info.paramIsComptime(i) and param_ty.tag() != .generic_poison) {171 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);
172 }173 }
173 }174 }
174175
...@@ -176,6 +177,12 @@ const MonomorphedFuncsContext = struct {...@@ -176,6 +177,12 @@ const MonomorphedFuncsContext = struct {
176 }177 }
177};178};
178179
180pub const WipAnalysis = struct {
181 sema: *Sema,
182 block: *Sema.Block,
183 src: Module.LazySrcLoc,
184};
185
179pub const MemoizedCallSet = std.HashMapUnmanaged(186pub const MemoizedCallSet = std.HashMapUnmanaged(
180 MemoizedCall.Key,187 MemoizedCall.Key,
181 MemoizedCall.Result,188 MemoizedCall.Result,
...@@ -184,6 +191,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(...@@ -184,6 +191,8 @@ pub const MemoizedCallSet = std.HashMapUnmanaged(
184);191);
185192
186pub const MemoizedCall = struct {193pub const MemoizedCall = struct {
194 target: std.Target,
195
187 pub const Key = struct {196 pub const Key = struct {
188 func: *Fn,197 func: *Fn,
189 args: []TypedValue,198 args: []TypedValue,
...@@ -195,14 +204,12 @@ pub const MemoizedCall = struct {...@@ -195,14 +204,12 @@ pub const MemoizedCall = struct {
195 };204 };
196205
197 pub fn eql(ctx: @This(), a: Key, b: Key) bool {206 pub fn eql(ctx: @This(), a: Key, b: Key) bool {
198 _ = ctx;
199
200 if (a.func != b.func) return false;207 if (a.func != b.func) return false;
201208
202 assert(a.args.len == b.args.len);209 assert(a.args.len == b.args.len);
203 for (a.args) |a_arg, arg_i| {210 for (a.args) |a_arg, arg_i| {
204 const b_arg = b.args[arg_i];211 const b_arg = b.args[arg_i];
205 if (!a_arg.eql(b_arg)) {212 if (!a_arg.eql(b_arg, ctx.target)) {
206 return false;213 return false;
207 }214 }
208 }215 }
...@@ -212,8 +219,6 @@ pub const MemoizedCall = struct {...@@ -212,8 +219,6 @@ pub const MemoizedCall = struct {
212219
213 /// Must match `Sema.GenericCallAdapter.hash`.220 /// Must match `Sema.GenericCallAdapter.hash`.
214 pub fn hash(ctx: @This(), key: Key) u64 {221 pub fn hash(ctx: @This(), key: Key) u64 {
215 _ = ctx;
216
217 var hasher = std.hash.Wyhash.init(0);222 var hasher = std.hash.Wyhash.init(0);
218223
219 // The generic function Decl is guaranteed to be the first dependency224 // The generic function Decl is guaranteed to be the first dependency
...@@ -223,7 +228,7 @@ pub const MemoizedCall = struct {...@@ -223,7 +228,7 @@ pub const MemoizedCall = struct {
223 // This logic must be kept in sync with the logic in `analyzeCall` that228 // This logic must be kept in sync with the logic in `analyzeCall` that
224 // computes the hash.229 // computes the hash.
225 for (key.args) |arg| {230 for (key.args) |arg| {
226 arg.hash(&hasher);231 arg.hash(&hasher, ctx.target);
227 }232 }
228233
229 return hasher.final();234 return hasher.final();
...@@ -1230,7 +1235,7 @@ pub const Union = struct {...@@ -1230,7 +1235,7 @@ pub const Union = struct {
1230 if (field.abi_align == 0) {1235 if (field.abi_align == 0) {
1231 break :a field.ty.abiAlignment(target);1236 break :a field.ty.abiAlignment(target);
1232 } else {1237 } else {
1233 break :a @intCast(u32, field.abi_align.toUnsignedInt());1238 break :a field.abi_align;
1234 }1239 }
1235 };1240 };
1236 if (field_align > most_alignment) {1241 if (field_align > most_alignment) {
...@@ -3877,6 +3882,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3877,6 +3882,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3877 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);3882 const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref);
3878 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;3883 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
3879 };3884 };
3885 const target = sema.mod.getTarget();
3880 const address_space = blk: {3886 const address_space = blk: {
3881 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {3887 const addrspace_ctx: Sema.AddressSpaceContext = switch (decl_tv.val.tag()) {
3882 .function, .extern_fn => .function,3888 .function, .extern_fn => .function,
...@@ -3886,9 +3892,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3886,9 +3892,9 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
38863892
3887 break :blk switch (decl.zirAddrspaceRef()) {3893 break :blk switch (decl.zirAddrspaceRef()) {
3888 .none => switch (addrspace_ctx) {3894 .none => switch (addrspace_ctx) {
3889 .function => target_util.defaultAddressSpace(sema.mod.getTarget(), .function),3895 .function => target_util.defaultAddressSpace(target, .function),
3890 .variable => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_mutable),3896 .variable => target_util.defaultAddressSpace(target, .global_mutable),
3891 .constant => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),3897 .constant => target_util.defaultAddressSpace(target, .global_constant),
3892 else => unreachable,3898 else => unreachable,
3893 },3899 },
3894 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),3900 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
...@@ -3904,13 +3910,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3904,13 +3910,15 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39043910
3905 if (decl.is_usingnamespace) {3911 if (decl.is_usingnamespace) {
3906 const ty_ty = Type.initTag(.type);3912 const ty_ty = Type.initTag(.type);
3907 if (!decl_tv.ty.eql(ty_ty)) {3913 if (!decl_tv.ty.eql(ty_ty, target)) {
3908 return sema.fail(&block_scope, src, "expected type, found {}", .{decl_tv.ty});3914 return sema.fail(&block_scope, src, "expected type, found {}", .{
3915 decl_tv.ty.fmt(target),
3916 });
3909 }3917 }
3910 var buffer: Value.ToTypeBuffer = undefined;3918 var buffer: Value.ToTypeBuffer = undefined;
3911 const ty = decl_tv.val.toType(&buffer);3919 const ty = decl_tv.val.toType(&buffer);
3912 if (ty.getNamespace() == null) {3920 if (ty.getNamespace() == null) {
3913 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty});3921 return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(target)});
3914 }3922 }
39153923
3916 decl.ty = ty_ty;3924 decl.ty = ty_ty;
...@@ -3937,7 +3945,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3937,7 +3945,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
39373945
3938 if (decl.has_tv) {3946 if (decl.has_tv) {
3939 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();3947 prev_type_has_bits = decl.ty.isFnOrHasRuntimeBits();
3940 type_changed = !decl.ty.eql(decl_tv.ty);3948 type_changed = !decl.ty.eql(decl_tv.ty, target);
3941 if (decl.getFunction()) |prev_func| {3949 if (decl.getFunction()) |prev_func| {
3942 prev_is_inline = prev_func.state == .inline_only;3950 prev_is_inline = prev_func.state == .inline_only;
3943 }3951 }
...@@ -3986,7 +3994,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3986,7 +3994,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3986 }3994 }
3987 var type_changed = true;3995 var type_changed = true;
3988 if (decl.has_tv) {3996 if (decl.has_tv) {
3989 type_changed = !decl.ty.eql(decl_tv.ty);3997 type_changed = !decl.ty.eql(decl_tv.ty, target);
3990 decl.clearValues(gpa);3998 decl.clearValues(gpa);
3991 }3999 }
39924000
...@@ -5054,22 +5062,6 @@ pub fn errNoteNonLazy(...@@ -5054,22 +5062,6 @@ pub fn errNoteNonLazy(
5054 };5062 };
5055}5063}
50565064
5057pub fn errorUnionType(
5058 arena: Allocator,
5059 error_set: Type,
5060 payload: Type,
5061) Allocator.Error!Type {
5062 assert(error_set.zigTypeTag() == .ErrorSet);
5063 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
5064 return Type.initTag(.anyerror_void_error_union);
5065 }
5066
5067 return Type.Tag.error_union.create(arena, .{
5068 .error_set = error_set,
5069 .payload = payload,
5070 });
5071}
5072
5073pub fn getTarget(mod: Module) Target {5065pub fn getTarget(mod: Module) Target {
5074 return mod.comp.bin_file.options.target;5066 return mod.comp.bin_file.options.target;
5075}5067}
src/RangeSet.zig+22-9
...@@ -6,6 +6,7 @@ const RangeSet = @This();...@@ -6,6 +6,7 @@ const RangeSet = @This();
6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;6const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;
77
8ranges: std.ArrayList(Range),8ranges: std.ArrayList(Range),
9target: std.Target,
910
10pub const Range = struct {11pub const Range = struct {
11 first: Value,12 first: Value,
...@@ -13,9 +14,10 @@ pub const Range = struct {...@@ -13,9 +14,10 @@ pub const Range = struct {
13 src: SwitchProngSrc,14 src: SwitchProngSrc,
14};15};
1516
16pub fn init(allocator: std.mem.Allocator) RangeSet {17pub fn init(allocator: std.mem.Allocator, target: std.Target) RangeSet {
17 return .{18 return .{
18 .ranges = std.ArrayList(Range).init(allocator),19 .ranges = std.ArrayList(Range).init(allocator),
20 .target = target,
19 };21 };
20}22}
2123
...@@ -30,8 +32,12 @@ pub fn add(...@@ -30,8 +32,12 @@ pub fn add(
30 ty: Type,32 ty: Type,
31 src: SwitchProngSrc,33 src: SwitchProngSrc,
32) !?SwitchProngSrc {34) !?SwitchProngSrc {
35 const target = self.target;
36
33 for (self.ranges.items) |range| {37 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 {
35 return range.src; // They overlap.41 return range.src; // They overlap.
36 }42 }
37 }43 }
...@@ -43,19 +49,26 @@ pub fn add(...@@ -43,19 +49,26 @@ pub fn add(
43 return null;49 return null;
44}50}
4551
52const LessThanContext = struct { ty: Type, target: std.Target };
53
46/// Assumes a and b do not overlap54/// Assumes a and b do not overlap
47fn lessThan(ty: Type, a: Range, b: Range) bool {55fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
48 return a.first.compare(.lt, b.first, ty);56 return a.first.compare(.lt, b.first, ctx.ty, ctx.target);
49}57}
5058
51pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {59pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
52 if (self.ranges.items.len == 0)60 if (self.ranges.items.len == 0)
53 return false;61 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) or70 if (!self.ranges.items[0].first.eql(first, ty, target) or
58 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty))71 !self.ranges.items[self.ranges.items.len - 1].last.eql(last, ty, target))
59 {72 {
60 return false;73 return false;
61 }74 }
...@@ -71,10 +84,10 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {...@@ -71,10 +84,10 @@ pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
71 const prev = self.ranges.items[i];84 const prev = self.ranges.items[i];
7285
73 // prev.last + 1 == cur.first86 // prev.last + 1 == cur.first
74 try counter.copy(prev.last.toBigInt(&space));87 try counter.copy(prev.last.toBigInt(&space, target));
75 try counter.addScalar(counter.toConst(), 1);88 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);
78 if (!cur_start_int.eq(counter.toConst())) {91 if (!cur_start_int.eq(counter.toConst())) {
79 return false;92 return false;
80 }93 }
src/Sema.zig+541-366
...@@ -1303,7 +1303,8 @@ pub fn resolveConstString(...@@ -1303,7 +1303,8 @@ pub fn resolveConstString(
1303 const wanted_type = Type.initTag(.const_slice_u8);1303 const wanted_type = Type.initTag(.const_slice_u8);
1304 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1304 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1305 const val = try sema.resolveConstValue(block, src, coerced_inst);1305 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);
1307}1308}
13081309
1309pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {1310pub 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...@@ -1457,19 +1458,29 @@ fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileErro
1457}1458}
14581459
1459fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {1460fn 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 });
1461}1465}
14621466
1463fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, optional_ty: Type) CompileError {1467fn 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)});
1465}1470}
14661471
1467fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1472fn 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 });
1469}1477}
14701478
1471fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {1479fn 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 });
1473}1484}
14741485
1475fn failWithErrorSetCodeMissing(1486fn failWithErrorSetCodeMissing(
...@@ -1479,8 +1490,9 @@ fn failWithErrorSetCodeMissing(...@@ -1479,8 +1490,9 @@ fn failWithErrorSetCodeMissing(
1479 dest_err_set_ty: Type,1490 dest_err_set_ty: Type,
1480 src_err_set_ty: Type,1491 src_err_set_ty: Type,
1481) CompileError {1492) CompileError {
1493 const target = sema.mod.getTarget();
1482 return sema.fail(block, src, "expected type '{}', found type '{}'", .{1494 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),
1484 });1496 });
1485}1497}
14861498
...@@ -1578,8 +1590,8 @@ fn resolveInt(...@@ -1578,8 +1590,8 @@ fn resolveInt(
1578 const air_inst = sema.resolveInst(zir_ref);1590 const air_inst = sema.resolveInst(zir_ref);
1579 const coerced = try sema.coerce(block, dest_ty, air_inst, src);1591 const coerced = try sema.coerce(block, dest_ty, air_inst, src);
1580 const val = try sema.resolveConstValue(block, src, coerced);1592 const val = try sema.resolveConstValue(block, src, coerced);
15811593 const target = sema.mod.getTarget();
1582 return val.toUnsignedInt();1594 return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
1583}1595}
15841596
1585// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for1597// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for
...@@ -1864,6 +1876,7 @@ fn createTypeName(...@@ -1864,6 +1876,7 @@ fn createTypeName(
1864 },1876 },
1865 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),1877 .parent => return sema.gpa.dupeZ(u8, mem.sliceTo(block.src_decl.name, 0)),
1866 .func => {1878 .func => {
1879 const target = sema.mod.getTarget();
1867 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);1880 const fn_info = sema.code.getFnInfo(sema.func.?.zir_body_inst);
1868 const zir_tags = sema.code.instructions.items(.tag);1881 const zir_tags = sema.code.instructions.items(.tag);
18691882
...@@ -1881,7 +1894,7 @@ fn createTypeName(...@@ -1881,7 +1894,7 @@ fn createTypeName(
1881 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;1894 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable;
18821895
1883 if (arg_i != 0) try buf.appendSlice(",");1896 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
1886 arg_i += 1;1899 arg_i += 1;
1887 continue;1900 continue;
...@@ -2045,6 +2058,7 @@ fn zirEnumDecl(...@@ -2045,6 +2058,7 @@ fn zirEnumDecl(
2045 enum_obj.tag_ty_inferred = true;2058 enum_obj.tag_ty_inferred = true;
2046 }2059 }
2047 }2060 }
2061 const target = mod.getTarget();
20482062
2049 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);2063 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
2050 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {2064 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
...@@ -2053,6 +2067,7 @@ fn zirEnumDecl(...@@ -2053,6 +2067,7 @@ fn zirEnumDecl(
2053 if (any_values) {2067 if (any_values) {
2054 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{2068 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
2055 .ty = enum_obj.tag_ty,2069 .ty = enum_obj.tag_ty,
2070 .target = target,
2056 });2071 });
2057 }2072 }
20582073
...@@ -2102,16 +2117,18 @@ fn zirEnumDecl(...@@ -2102,16 +2117,18 @@ fn zirEnumDecl(
2102 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2117 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2103 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2118 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2104 .ty = enum_obj.tag_ty,2119 .ty = enum_obj.tag_ty,
2120 .target = target,
2105 });2121 });
2106 } else if (any_values) {2122 } else if (any_values) {
2107 const tag_val = if (last_tag_val) |val|2123 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)
2109 else2125 else
2110 Value.zero;2126 Value.zero;
2111 last_tag_val = tag_val;2127 last_tag_val = tag_val;
2112 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);2128 const copied_tag_val = try tag_val.copy(new_decl_arena_allocator);
2113 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{2129 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
2114 .ty = enum_obj.tag_ty,2130 .ty = enum_obj.tag_ty,
2131 .target = target,
2115 });2132 });
2116 }2133 }
2117 }2134 }
...@@ -2417,13 +2434,14 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2417,13 +2434,14 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2417 else2434 else
2418 object_ty;2435 object_ty;
24192436
2437 const target = sema.mod.getTarget();
2420 if (!array_ty.isIndexable()) {2438 if (!array_ty.isIndexable()) {
2421 const msg = msg: {2439 const msg = msg: {
2422 const msg = try sema.errMsg(2440 const msg = try sema.errMsg(
2423 block,2441 block,
2424 src,2442 src,
2425 "type '{}' does not support indexing",2443 "type '{}' does not support indexing",
2426 .{array_ty},2444 .{array_ty.fmt(target)},
2427 );2445 );
2428 errdefer msg.destroy(sema.gpa);2446 errdefer msg.destroy(sema.gpa);
2429 try sema.errNote(2447 try sema.errNote(
...@@ -3346,8 +3364,9 @@ fn failWithBadMemberAccess(...@@ -3346,8 +3364,9 @@ fn failWithBadMemberAccess(
3346 else => unreachable,3364 else => unreachable,
3347 };3365 };
3348 const msg = msg: {3366 const msg = msg: {
3367 const target = sema.mod.getTarget();
3349 const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{3368 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,
3351 });3370 });
3352 errdefer msg.destroy(sema.gpa);3371 errdefer msg.destroy(sema.gpa);
3353 try sema.addDeclaredHereNote(msg, agg_ty);3372 try sema.addDeclaredHereNote(msg, agg_ty);
...@@ -3680,6 +3699,7 @@ fn zirCompileLog(...@@ -3680,6 +3699,7 @@ fn zirCompileLog(
3680 const src_node = extra.data.src_node;3699 const src_node = extra.data.src_node;
3681 const src: LazySrcLoc = .{ .node_offset = src_node };3700 const src: LazySrcLoc = .{ .node_offset = src_node };
3682 const args = sema.code.refSlice(extra.end, extended.small);3701 const args = sema.code.refSlice(extra.end, extended.small);
3702 const target = sema.mod.getTarget();
36833703
3684 for (args) |arg_ref, i| {3704 for (args) |arg_ref, i| {
3685 if (i != 0) try writer.print(", ", .{});3705 if (i != 0) try writer.print(", ", .{});
...@@ -3687,9 +3707,11 @@ fn zirCompileLog(...@@ -3687,9 +3707,11 @@ fn zirCompileLog(
3687 const arg = sema.resolveInst(arg_ref);3707 const arg = sema.resolveInst(arg_ref);
3688 const arg_ty = sema.typeOf(arg);3708 const arg_ty = sema.typeOf(arg);
3689 if (try sema.resolveMaybeUndefVal(block, src, arg)) |val| {3709 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 });
3691 } else {3713 } else {
3692 try writer.print("@as({}, [runtime value])", .{arg_ty});3714 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(target)});
3693 }3715 }
3694 }3716 }
3695 try writer.print("\n", .{});3717 try writer.print("\n", .{});
...@@ -3982,9 +4004,10 @@ fn analyzeBlockBody(...@@ -3982,9 +4004,10 @@ fn analyzeBlockBody(
39824004
3983 const type_src = src; // TODO: better source location4005 const type_src = src; // TODO: better source location
3984 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);4006 const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);
4007 const target = sema.mod.getTarget();
3985 if (!valid_rt) {4008 if (!valid_rt) {
3986 const msg = msg: {4009 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)});
3988 errdefer msg.destroy(sema.gpa);4011 errdefer msg.destroy(sema.gpa);
39894012
3990 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;4013 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
...@@ -4012,7 +4035,7 @@ fn analyzeBlockBody(...@@ -4012,7 +4035,7 @@ fn analyzeBlockBody(
4012 const br_operand = sema.air_instructions.items(.data)[br].br.operand;4035 const br_operand = sema.air_instructions.items(.data)[br].br.operand;
4013 const br_operand_src = src;4036 const br_operand_src = src;
4014 const br_operand_ty = sema.typeOf(br_operand);4037 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)) {
4016 // No type coercion needed.4039 // No type coercion needed.
4017 continue;4040 continue;
4018 }4041 }
...@@ -4102,12 +4125,15 @@ pub fn analyzeExport(...@@ -4102,12 +4125,15 @@ pub fn analyzeExport(
4102) !void {4125) !void {
4103 const Export = Module.Export;4126 const Export = Module.Export;
4104 const mod = sema.mod;4127 const mod = sema.mod;
4128 const target = mod.getTarget();
41054129
4106 try mod.ensureDeclAnalyzed(exported_decl);4130 try mod.ensureDeclAnalyzed(exported_decl);
4107 // TODO run the same checks as we do for C ABI struct fields4131 // TODO run the same checks as we do for C ABI struct fields
4108 switch (exported_decl.ty.zigTypeTag()) {4132 switch (exported_decl.ty.zigTypeTag()) {
4109 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},4133 .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 }),
4111 }4137 }
41124138
4113 const gpa = mod.gpa;4139 const gpa = mod.gpa;
...@@ -4520,6 +4546,7 @@ const GenericCallAdapter = struct {...@@ -4520,6 +4546,7 @@ const GenericCallAdapter = struct {
4520 precomputed_hash: u64,4546 precomputed_hash: u64,
4521 func_ty_info: Type.Payload.Function.Data,4547 func_ty_info: Type.Payload.Function.Data,
4522 comptime_tvs: []const TypedValue,4548 comptime_tvs: []const TypedValue,
4549 target: std.Target,
45234550
4524 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {4551 pub fn eql(ctx: @This(), adapted_key: void, other_key: *Module.Fn) bool {
4525 _ = adapted_key;4552 _ = adapted_key;
...@@ -4532,7 +4559,7 @@ const GenericCallAdapter = struct {...@@ -4532,7 +4559,7 @@ const GenericCallAdapter = struct {
4532 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {4559 for (other_comptime_args[0..ctx.func_ty_info.param_types.len]) |other_arg, i| {
4533 if (other_arg.ty.tag() != .generic_poison) {4560 if (other_arg.ty.tag() != .generic_poison) {
4534 // anytype parameter4561 // 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)) {
4536 return false;4563 return false;
4537 }4564 }
4538 }4565 }
...@@ -4543,7 +4570,7 @@ const GenericCallAdapter = struct {...@@ -4543,7 +4570,7 @@ const GenericCallAdapter = struct {
4543 // but the callsite does not.4570 // but the callsite does not.
4544 return false;4571 return false;
4545 }4572 }
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)) {
4547 return false;4574 return false;
4548 }4575 }
4549 }4576 }
...@@ -4588,6 +4615,7 @@ fn analyzeCall(...@@ -4588,6 +4615,7 @@ fn analyzeCall(
4588 const mod = sema.mod;4615 const mod = sema.mod;
45894616
4590 const callee_ty = sema.typeOf(func);4617 const callee_ty = sema.typeOf(func);
4618 const target = sema.mod.getTarget();
4591 const func_ty = func_ty: {4619 const func_ty = func_ty: {
4592 switch (callee_ty.zigTypeTag()) {4620 switch (callee_ty.zigTypeTag()) {
4593 .Fn => break :func_ty callee_ty,4621 .Fn => break :func_ty callee_ty,
...@@ -4599,7 +4627,7 @@ fn analyzeCall(...@@ -4599,7 +4627,7 @@ fn analyzeCall(
4599 },4627 },
4600 else => {},4628 else => {},
4601 }4629 }
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)});
4603 };4631 };
46044632
4605 const func_ty_info = func_ty.fnInfo();4633 const func_ty_info = func_ty.fnInfo();
...@@ -4873,7 +4901,7 @@ fn analyzeCall(...@@ -4873,7 +4901,7 @@ fn analyzeCall(
4873 // bug generating invalid LLVM IR.4901 // bug generating invalid LLVM IR.
4874 const res2: Air.Inst.Ref = res2: {4902 const res2: Air.Inst.Ref = res2: {
4875 if (should_memoize and is_comptime_call) {4903 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| {
4877 const ty_inst = try sema.addType(fn_ret_ty);4905 const ty_inst = try sema.addType(fn_ret_ty);
4878 try sema.air_values.append(gpa, result.val);4906 try sema.air_values.append(gpa, result.val);
4879 sema.air_instructions.set(block_inst, .{4907 sema.air_instructions.set(block_inst, .{
...@@ -4945,10 +4973,10 @@ fn analyzeCall(...@@ -4945,10 +4973,10 @@ fn analyzeCall(
4945 arg.* = try arg.*.copy(arena);4973 arg.* = try arg.*.copy(arena);
4946 }4974 }
49474975
4948 try mod.memoized_calls.put(gpa, memoized_call_key, .{4976 try mod.memoized_calls.putContext(gpa, memoized_call_key, .{
4949 .val = try result_val.copy(arena),4977 .val = try result_val.copy(arena),
4950 .arena = arena_allocator.state,4978 .arena = arena_allocator.state,
4951 });4979 }, .{ .target = sema.mod.getTarget() });
4952 delete_memoized_call_key = false;4980 delete_memoized_call_key = false;
4953 }4981 }
4954 }4982 }
...@@ -5037,6 +5065,7 @@ fn instantiateGenericCall(...@@ -5037,6 +5065,7 @@ fn instantiateGenericCall(
5037 std.hash.autoHash(&hasher, @ptrToInt(module_fn));5065 std.hash.autoHash(&hasher, @ptrToInt(module_fn));
50385066
5039 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);5067 const comptime_tvs = try sema.arena.alloc(TypedValue, func_ty_info.param_types.len);
5068 const target = sema.mod.getTarget();
50405069
5041 for (func_ty_info.param_types) |param_ty, i| {5070 for (func_ty_info.param_types) |param_ty, i| {
5042 const is_comptime = func_ty_info.paramIsComptime(i);5071 const is_comptime = func_ty_info.paramIsComptime(i);
...@@ -5045,7 +5074,7 @@ fn instantiateGenericCall(...@@ -5045,7 +5074,7 @@ fn instantiateGenericCall(
5045 const casted_arg = try sema.coerce(block, param_ty, uncasted_args[i], arg_src);5074 const casted_arg = try sema.coerce(block, param_ty, uncasted_args[i], arg_src);
5046 if (try sema.resolveMaybeUndefVal(block, arg_src, casted_arg)) |arg_val| {5075 if (try sema.resolveMaybeUndefVal(block, arg_src, casted_arg)) |arg_val| {
5047 if (param_ty.tag() != .generic_poison) {5076 if (param_ty.tag() != .generic_poison) {
5048 arg_val.hash(param_ty, &hasher);5077 arg_val.hash(param_ty, &hasher, target);
5049 }5078 }
5050 comptime_tvs[i] = .{5079 comptime_tvs[i] = .{
5051 // This will be different than `param_ty` in the case of `generic_poison`.5080 // This will be different than `param_ty` in the case of `generic_poison`.
...@@ -5070,8 +5099,9 @@ fn instantiateGenericCall(...@@ -5070,8 +5099,9 @@ fn instantiateGenericCall(
5070 .precomputed_hash = precomputed_hash,5099 .precomputed_hash = precomputed_hash,
5071 .func_ty_info = func_ty_info,5100 .func_ty_info = func_ty_info,
5072 .comptime_tvs = comptime_tvs,5101 .comptime_tvs = comptime_tvs,
5102 .target = target,
5073 };5103 };
5074 const gop = try mod.monomorphed_funcs.getOrPutAdapted(gpa, {}, adapter);5104 const gop = try mod.monomorphed_funcs.getOrPutContextAdapted(gpa, {}, adapter, .{ .target = target });
5075 if (!gop.found_existing) {5105 if (!gop.found_existing) {
5076 const new_module_func = try gpa.create(Module.Fn);5106 const new_module_func = try gpa.create(Module.Fn);
5077 gop.key_ptr.* = new_module_func;5107 gop.key_ptr.* = new_module_func;
...@@ -5255,7 +5285,7 @@ fn instantiateGenericCall(...@@ -5255,7 +5285,7 @@ fn instantiateGenericCall(
5255 new_decl.analysis = .complete;5285 new_decl.analysis = .complete;
52565286
5257 log.debug("generic function '{s}' instantiated with type {}", .{5287 log.debug("generic function '{s}' instantiated with type {}", .{
5258 new_decl.name, new_decl.ty,5288 new_decl.name, new_decl.ty.fmtDebug(),
5259 });5289 });
52605290
5261 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field5291 // 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...@@ -5410,7 +5440,8 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5410 const bin_inst = sema.code.instructions.items(.data)[inst].bin;5440 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
5411 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);5441 const len = try sema.resolveInt(block, .unneeded, bin_inst.lhs, Type.usize);
5412 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);5442 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
5415 return sema.addType(array_ty);5446 return sema.addType(array_ty);
5416}5447}
...@@ -5429,7 +5460,8 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -5429,7 +5460,8 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
5429 const uncasted_sentinel = sema.resolveInst(extra.sentinel);5460 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
5430 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);5461 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
5431 const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel);5462 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
5434 return sema.addType(array_ty);5466 return sema.addType(array_ty);
5435}5467}
...@@ -5456,13 +5488,14 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5456,13 +5488,14 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5456 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };5488 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
5457 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);5489 const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
5458 const payload = try sema.resolveType(block, rhs_src, extra.rhs);5490 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
5491 const target = sema.mod.getTarget();
54595492
5460 if (error_set.zigTypeTag() != .ErrorSet) {5493 if (error_set.zigTypeTag() != .ErrorSet) {
5461 return sema.fail(block, lhs_src, "expected error set type, found {}", .{5494 return sema.fail(block, lhs_src, "expected error set type, found {}", .{
5462 error_set,5495 error_set.fmt(target),
5463 });5496 });
5464 }5497 }
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);
5466 return sema.addType(err_union_ty);5499 return sema.addType(err_union_ty);
5467}5500}
54685501
...@@ -5520,9 +5553,10 @@ fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -5520,9 +5553,10 @@ fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
5520 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5553 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
55215554
5522 const op = sema.resolveInst(inst_data.operand);5555 const op = sema.resolveInst(inst_data.operand);
5556 const target = sema.mod.getTarget();
55235557
5524 if (try sema.resolveDefinedValue(block, operand_src, op)) |value| {5558 if (try sema.resolveDefinedValue(block, operand_src, op)) |value| {
5525 const int = value.toUnsignedInt();5559 const int = value.toUnsignedInt(target);
5526 if (int > sema.mod.global_error_set.count() or int == 0)5560 if (int > sema.mod.global_error_set.count() or int == 0)
5527 return sema.fail(block, operand_src, "integer value {d} represents no error", .{int});5561 return sema.fail(block, operand_src, "integer value {d} represents no error", .{int});
5528 const payload = try sema.arena.create(Value.Payload.Error);5562 const payload = try sema.arena.create(Value.Payload.Error);
...@@ -5569,10 +5603,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5569,10 +5603,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5569 }5603 }
5570 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);5604 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
5571 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);5605 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
5606 const target = sema.mod.getTarget();
5572 if (lhs_ty.zigTypeTag() != .ErrorSet)5607 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)});
5574 if (rhs_ty.zigTypeTag() != .ErrorSet)5609 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
5577 // Anything merged with anyerror is anyerror.5612 // Anything merged with anyerror is anyerror.
5578 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {5613 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...@@ -5618,6 +5653,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5618 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5653 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5619 const operand = sema.resolveInst(inst_data.operand);5654 const operand = sema.resolveInst(inst_data.operand);
5620 const operand_ty = sema.typeOf(operand);5655 const operand_ty = sema.typeOf(operand);
5656 const target = sema.mod.getTarget();
56215657
5622 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {5658 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
5623 .Enum => operand,5659 .Enum => operand,
...@@ -5634,7 +5670,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5634,7 +5670,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5634 },5670 },
5635 else => {5671 else => {
5636 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{5672 return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{
5637 operand_ty,5673 operand_ty.fmt(target),
5638 });5674 });
5639 },5675 },
5640 };5676 };
...@@ -5668,7 +5704,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -5668,7 +5704,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5668 const operand = sema.resolveInst(extra.rhs);5704 const operand = sema.resolveInst(extra.rhs);
56695705
5670 if (dest_ty.zigTypeTag() != .Enum) {5706 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)});
5672 }5708 }
56735709
5674 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {5710 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...@@ -5684,7 +5720,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
5684 block,5720 block,
5685 src,5721 src,
5686 "enum '{}' has no tag with value {}",5722 "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) },
5688 );5724 );
5689 errdefer msg.destroy(sema.gpa);5725 errdefer msg.destroy(sema.gpa);
5690 try sema.mod.errNoteNonLazy(5726 try sema.mod.errNoteNonLazy(
...@@ -5733,13 +5769,13 @@ fn analyzeOptionalPayloadPtr(...@@ -5733,13 +5769,13 @@ fn analyzeOptionalPayloadPtr(
5733 const optional_ptr_ty = sema.typeOf(optional_ptr);5769 const optional_ptr_ty = sema.typeOf(optional_ptr);
5734 assert(optional_ptr_ty.zigTypeTag() == .Pointer);5770 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
57355771
5772 const target = sema.mod.getTarget();
5736 const opt_type = optional_ptr_ty.elemType();5773 const opt_type = optional_ptr_ty.elemType();
5737 if (opt_type.zigTypeTag() != .Optional) {5774 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)});
5739 }5776 }
57405777
5741 const child_type = try opt_type.optionalChildAlloc(sema.arena);5778 const child_type = try opt_type.optionalChildAlloc(sema.arena);
5742 const target = sema.mod.getTarget();
5743 const child_pointer = try Type.ptr(sema.arena, target, .{5779 const child_pointer = try Type.ptr(sema.arena, target, .{
5744 .pointee_type = child_type,5780 .pointee_type = child_type,
5745 .mutable = !optional_ptr_ty.isConstPtr(),5781 .mutable = !optional_ptr_ty.isConstPtr(),
...@@ -5858,8 +5894,12 @@ fn zirErrUnionPayload(...@@ -5858,8 +5894,12 @@ fn zirErrUnionPayload(
5858 const operand = sema.resolveInst(inst_data.operand);5894 const operand = sema.resolveInst(inst_data.operand);
5859 const operand_src = src;5895 const operand_src = src;
5860 const operand_ty = sema.typeOf(operand);5896 const operand_ty = sema.typeOf(operand);
5861 if (operand_ty.zigTypeTag() != .ErrorUnion)5897 if (operand_ty.zigTypeTag() != .ErrorUnion) {
5862 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{operand_ty});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
5864 if (try sema.resolveDefinedValue(block, src, operand)) |val| {5904 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
5865 if (val.getError()) |name| {5905 if (val.getError()) |name| {
...@@ -5906,11 +5946,14 @@ fn analyzeErrUnionPayloadPtr(...@@ -5906,11 +5946,14 @@ fn analyzeErrUnionPayloadPtr(
5906 const operand_ty = sema.typeOf(operand);5946 const operand_ty = sema.typeOf(operand);
5907 assert(operand_ty.zigTypeTag() == .Pointer);5947 assert(operand_ty.zigTypeTag() == .Pointer);
59085948
5909 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)5949 const target = sema.mod.getTarget();
5910 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});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
5912 const payload_ty = operand_ty.elemType().errorUnionPayload();5956 const payload_ty = operand_ty.elemType().errorUnionPayload();
5913 const target = sema.mod.getTarget();
5914 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{5957 const operand_pointer_ty = try Type.ptr(sema.arena, target, .{
5915 .pointee_type = payload_ty,5958 .pointee_type = payload_ty,
5916 .mutable = !operand_ty.isConstPtr(),5959 .mutable = !operand_ty.isConstPtr(),
...@@ -5970,8 +6013,12 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5970,8 +6013,12 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
5970 const src = inst_data.src();6013 const src = inst_data.src();
5971 const operand = sema.resolveInst(inst_data.operand);6014 const operand = sema.resolveInst(inst_data.operand);
5972 const operand_ty = sema.typeOf(operand);6015 const operand_ty = sema.typeOf(operand);
5973 if (operand_ty.zigTypeTag() != .ErrorUnion)6016 const target = sema.mod.getTarget();
5974 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});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
5976 const result_ty = operand_ty.errorUnionSet();6023 const result_ty = operand_ty.errorUnionSet();
59776024
...@@ -5995,8 +6042,12 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -5995,8 +6042,12 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
5995 const operand_ty = sema.typeOf(operand);6042 const operand_ty = sema.typeOf(operand);
5996 assert(operand_ty.zigTypeTag() == .Pointer);6043 assert(operand_ty.zigTypeTag() == .Pointer);
59976044
5998 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)6045 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) {
5999 return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()});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
6001 const result_ty = operand_ty.elemType().errorUnionSet();6052 const result_ty = operand_ty.elemType().errorUnionSet();
60026053
...@@ -6019,8 +6070,12 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -6019,8 +6070,12 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
6019 const src = inst_data.src();6070 const src = inst_data.src();
6020 const operand = sema.resolveInst(inst_data.operand);6071 const operand = sema.resolveInst(inst_data.operand);
6021 const operand_ty = sema.typeOf(operand);6072 const operand_ty = sema.typeOf(operand);
6022 if (operand_ty.zigTypeTag() != .ErrorUnion)6073 const target = sema.mod.getTarget();
6023 return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty});6074 if (operand_ty.zigTypeTag() != .ErrorUnion) {
6075 return sema.fail(block, src, "expected error union type, found '{}'", .{
6076 operand_ty.fmt(target),
6077 });
6078 }
6024 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {6079 if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) {
6025 return sema.fail(block, src, "expression value is ignored", .{});6080 return sema.fail(block, src, "expression value is ignored", .{});
6026 }6081 }
...@@ -6205,7 +6260,7 @@ fn funcCommon(...@@ -6205,7 +6260,7 @@ fn funcCommon(
62056260
6206 const fn_ty: Type = fn_ty: {6261 const fn_ty: Type = fn_ty: {
6207 const alignment: u32 = if (align_val.tag() == .null_value) 0 else a: {6262 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));
6209 if (alignment == target_util.defaultFunctionAlignment(target)) {6264 if (alignment == target_util.defaultFunctionAlignment(target)) {
6210 break :a 0;6265 break :a 0;
6211 } else {6266 } else {
...@@ -6494,7 +6549,8 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -6494,7 +6549,8 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
6494 const ptr = sema.resolveInst(inst_data.operand);6549 const ptr = sema.resolveInst(inst_data.operand);
6495 const ptr_ty = sema.typeOf(ptr);6550 const ptr_ty = sema.typeOf(ptr);
6496 if (!ptr_ty.isPtrAtRuntime()) {6551 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)});
6498 }6554 }
6499 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {6555 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
6500 return sema.addConstant(Type.usize, ptr_val);6556 return sema.addConstant(Type.usize, ptr_val);
...@@ -6652,6 +6708,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6652,6 +6708,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6652 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);6708 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
6653 const operand = sema.resolveInst(extra.rhs);6709 const operand = sema.resolveInst(extra.rhs);
66546710
6711 const target = sema.mod.getTarget();
6655 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {6712 const dest_is_comptime_float = switch (dest_ty.zigTypeTag()) {
6656 .ComptimeFloat => true,6713 .ComptimeFloat => true,
6657 .Float => false,6714 .Float => false,
...@@ -6659,7 +6716,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6659,7 +6716,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6659 block,6716 block,
6660 dest_ty_src,6717 dest_ty_src,
6661 "expected float type, found '{}'",6718 "expected float type, found '{}'",
6662 .{dest_ty},6719 .{dest_ty.fmt(target)},
6663 ),6720 ),
6664 };6721 };
66656722
...@@ -6670,7 +6727,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6670,7 +6727,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6670 block,6727 block,
6671 operand_src,6728 operand_src,
6672 "expected float type, found '{}'",6729 "expected float type, found '{}'",
6673 .{operand_ty},6730 .{operand_ty.fmt(target)},
6674 ),6731 ),
6675 }6732 }
66766733
...@@ -6680,7 +6737,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -6680,7 +6737,6 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
6680 if (dest_is_comptime_float) {6737 if (dest_is_comptime_float) {
6681 return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{});6738 return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{});
6682 }6739 }
6683 const target = sema.mod.getTarget();
6684 const src_bits = operand_ty.floatBits(target);6740 const src_bits = operand_ty.floatBits(target);
6685 const dst_bits = dest_ty.floatBits(target);6741 const dst_bits = dest_ty.floatBits(target);
6686 if (dst_bits >= src_bits) {6742 if (dst_bits >= src_bits) {
...@@ -6839,13 +6895,14 @@ fn zirSwitchCapture(...@@ -6839,13 +6895,14 @@ fn zirSwitchCapture(
6839 const item = sema.resolveInst(scalar_prong.item);6895 const item = sema.resolveInst(scalar_prong.item);
6840 // Previous switch validation ensured this will succeed6896 // Previous switch validation ensured this will succeed
6841 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;6897 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;
6898 const target = sema.mod.getTarget();
68426899
6843 switch (operand_ty.zigTypeTag()) {6900 switch (operand_ty.zigTypeTag()) {
6844 .Union => {6901 .Union => {
6845 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;6902 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
6846 const enum_ty = union_obj.tag_ty;6903 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).?;
6849 const field_index = @intCast(u32, field_index_usize);6906 const field_index = @intCast(u32, field_index_usize);
6850 const field = union_obj.fields.values()[field_index];6907 const field = union_obj.fields.values()[field_index];
68516908
...@@ -6854,7 +6911,6 @@ fn zirSwitchCapture(...@@ -6854,7 +6911,6 @@ fn zirSwitchCapture(
6854 if (is_ref) {6911 if (is_ref) {
6855 assert(operand_is_ref);6912 assert(operand_is_ref);
68566913
6857 const target = sema.mod.getTarget();
6858 const field_ty_ptr = try Type.ptr(sema.arena, target, .{6914 const field_ty_ptr = try Type.ptr(sema.arena, target, .{
6859 .pointee_type = field.ty,6915 .pointee_type = field.ty,
6860 .@"addrspace" = .generic,6916 .@"addrspace" = .generic,
...@@ -6894,7 +6950,7 @@ fn zirSwitchCapture(...@@ -6894,7 +6950,7 @@ fn zirSwitchCapture(
6894 },6950 },
6895 else => {6951 else => {
6896 return sema.fail(block, operand_src, "switch on type '{}' provides no capture value", .{6952 return sema.fail(block, operand_src, "switch on type '{}' provides no capture value", .{
6897 operand_ty,6953 operand_ty.fmt(target),
6898 });6954 });
6899 },6955 },
6900 }6956 }
...@@ -6915,6 +6971,7 @@ fn zirSwitchCond(...@@ -6915,6 +6971,7 @@ fn zirSwitchCond(
6915 else6971 else
6916 operand_ptr;6972 operand_ptr;
6917 const operand_ty = sema.typeOf(operand);6973 const operand_ty = sema.typeOf(operand);
6974 const target = sema.mod.getTarget();
69186975
6919 switch (operand_ty.zigTypeTag()) {6976 switch (operand_ty.zigTypeTag()) {
6920 .Type,6977 .Type,
...@@ -6962,7 +7019,7 @@ fn zirSwitchCond(...@@ -6962,7 +7019,7 @@ fn zirSwitchCond(
6962 .Vector,7019 .Vector,
6963 .Frame,7020 .Frame,
6964 .AnyFrame,7021 .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)}),
6966 }7023 }
6967}7024}
69687025
...@@ -7030,6 +7087,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7030,6 +7087,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7030 return sema.failWithOwnedErrorMsg(block, msg);7087 return sema.failWithOwnedErrorMsg(block, msg);
7031 }7088 }
70327089
7090 const target = sema.mod.getTarget();
7091
7033 // Validate for duplicate items, missing else prong, and invalid range.7092 // Validate for duplicate items, missing else prong, and invalid range.
7034 switch (operand_ty.zigTypeTag()) {7093 switch (operand_ty.zigTypeTag()) {
7035 .Enum => {7094 .Enum => {
...@@ -7115,7 +7174,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7115,7 +7174,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7115 operand_ty.declSrcLoc(),7174 operand_ty.declSrcLoc(),
7116 msg,7175 msg,
7117 "enum '{}' declared here",7176 "enum '{}' declared here",
7118 .{operand_ty},7177 .{operand_ty.fmt(target)},
7119 );7178 );
7120 break :msg msg;7179 break :msg msg;
7121 };7180 };
...@@ -7232,7 +7291,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7232,7 +7291,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7232 operand_ty.declSrcLoc(),7291 operand_ty.declSrcLoc(),
7233 msg,7292 msg,
7234 "error set '{}' declared here",7293 "error set '{}' declared here",
7235 .{operand_ty},7294 .{operand_ty.fmt(target)},
7236 );7295 );
7237 return sema.failWithOwnedErrorMsg(block, msg);7296 return sema.failWithOwnedErrorMsg(block, msg);
7238 }7297 }
...@@ -7260,7 +7319,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7260,7 +7319,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7260 },7319 },
7261 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),7320 .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
7262 .Int, .ComptimeInt => {7321 .Int, .ComptimeInt => {
7263 var range_set = RangeSet.init(gpa);7322 var range_set = RangeSet.init(gpa, target);
7264 defer range_set.deinit();7323 defer range_set.deinit();
72657324
7266 var extra_index: usize = special.end;7325 var extra_index: usize = special.end;
...@@ -7333,7 +7392,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7333,7 +7392,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7333 var arena = std.heap.ArenaAllocator.init(gpa);7392 var arena = std.heap.ArenaAllocator.init(gpa);
7334 defer arena.deinit();7393 defer arena.deinit();
73357394
7336 const target = sema.mod.getTarget();
7337 const min_int = try operand_ty.minInt(arena.allocator(), target);7395 const min_int = try operand_ty.minInt(arena.allocator(), target);
7338 const max_int = try operand_ty.maxInt(arena.allocator(), target);7396 const max_int = try operand_ty.maxInt(arena.allocator(), target);
7339 if (try range_set.spans(min_int, max_int, operand_ty)) {7397 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...@@ -7437,11 +7495,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7437 block,7495 block,
7438 src,7496 src,
7439 "else prong required when switching on type '{}'",7497 "else prong required when switching on type '{}'",
7440 .{operand_ty},7498 .{operand_ty.fmt(target)},
7441 );7499 );
7442 }7500 }
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 });
7445 defer seen_values.deinit();7506 defer seen_values.deinit();
74467507
7447 var extra_index: usize = special.end;7508 var extra_index: usize = special.end;
...@@ -7505,7 +7566,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7505,7 +7566,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7505 .ComptimeFloat,7566 .ComptimeFloat,
7506 .Float,7567 .Float,
7507 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{7568 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
7508 operand_ty,7569 operand_ty.fmt(target),
7509 }),7570 }),
7510 }7571 }
75117572
...@@ -7555,7 +7616,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7555,7 +7616,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7555 const item = sema.resolveInst(item_ref);7616 const item = sema.resolveInst(item_ref);
7556 // Validation above ensured these will succeed.7617 // Validation above ensured these will succeed.
7557 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;7618 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)) {
7559 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7620 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7560 }7621 }
7561 }7622 }
...@@ -7577,7 +7638,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7577,7 +7638,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7577 const item = sema.resolveInst(item_ref);7638 const item = sema.resolveInst(item_ref);
7578 // Validation above ensured these will succeed.7639 // Validation above ensured these will succeed.
7579 const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable;7640 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)) {
7581 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7642 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7582 }7643 }
7583 }7644 }
...@@ -7592,8 +7653,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -7592,8 +7653,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
7592 // Validation above ensured these will succeed.7653 // Validation above ensured these will succeed.
7593 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;7654 const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable;
7594 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;7655 const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable;
7595 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty) and7656 if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, target) and
7596 Value.compare(operand_val, .lte, last_tv.val, operand_ty))7657 Value.compare(operand_val, .lte, last_tv.val, operand_ty, target))
7597 {7658 {
7598 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);7659 return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
7599 }7660 }
...@@ -7907,14 +7968,15 @@ fn validateSwitchItemEnum(...@@ -7907,14 +7968,15 @@ fn validateSwitchItemEnum(
7907 switch_prong_src: Module.SwitchProngSrc,7968 switch_prong_src: Module.SwitchProngSrc,
7908) CompileError!void {7969) CompileError!void {
7909 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);7970 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 {
7911 const msg = msg: {7973 const msg = msg: {
7912 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);7974 const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none);
7913 const msg = try sema.errMsg(7975 const msg = try sema.errMsg(
7914 block,7976 block,
7915 src,7977 src,
7916 "enum '{}' has no tag with value '{}'",7978 "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) },
7918 );7980 );
7919 errdefer msg.destroy(sema.gpa);7981 errdefer msg.destroy(sema.gpa);
7920 try sema.mod.errNoteNonLazy(7982 try sema.mod.errNoteNonLazy(
...@@ -8030,12 +8092,13 @@ fn validateSwitchNoRange(...@@ -8030,12 +8092,13 @@ fn validateSwitchNoRange(
8030 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };8092 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
8031 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };8093 const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };
80328094
8095 const target = sema.mod.getTarget();
8033 const msg = msg: {8096 const msg = msg: {
8034 const msg = try sema.errMsg(8097 const msg = try sema.errMsg(
8035 block,8098 block,
8036 operand_src,8099 operand_src,
8037 "ranges not allowed when switching on type '{}'",8100 "ranges not allowed when switching on type '{}'",
8038 .{operand_ty},8101 .{operand_ty.fmt(target)},
8039 );8102 );
8040 errdefer msg.destroy(sema.gpa);8103 errdefer msg.destroy(sema.gpa);
8041 try sema.errNote(8104 try sema.errNote(
...@@ -8058,6 +8121,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8058,6 +8121,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8058 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);8121 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
8059 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);8122 const field_name = try sema.resolveConstString(block, name_src, extra.rhs);
8060 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);8123 const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty);
8124 const target = sema.mod.getTarget();
80618125
8062 const has_field = hf: {8126 const has_field = hf: {
8063 if (ty.isSlice()) {8127 if (ty.isSlice()) {
...@@ -8080,7 +8144,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8080,7 +8144,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8080 .Enum => ty.enumFields().contains(field_name),8144 .Enum => ty.enumFields().contains(field_name),
8081 .Array => mem.eql(u8, field_name, "len"),8145 .Array => mem.eql(u8, field_name, "len"),
8082 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{8146 else => return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
8083 ty,8147 ty.fmt(target),
8084 }),8148 }),
8085 };8149 };
8086 };8150 };
...@@ -8227,25 +8291,25 @@ fn zirShl(...@@ -8227,25 +8291,25 @@ fn zirShl(
82278291
8228 const val = switch (air_tag) {8292 const val = switch (air_tag) {
8229 .shl_exact => val: {8293 .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);
8231 if (scalar_ty.zigTypeTag() == .ComptimeInt) {8295 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
8232 break :val shifted;8296 break :val shifted;
8233 }8297 }
8234 const int_info = scalar_ty.intInfo(target);8298 const int_info = scalar_ty.intInfo(target);
8235 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits);8299 const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target);
8236 if (truncated.compare(.eq, shifted, lhs_ty)) {8300 if (truncated.compare(.eq, shifted, lhs_ty, target)) {
8237 break :val shifted;8301 break :val shifted;
8238 }8302 }
8239 return sema.addConstUndef(lhs_ty);8303 return sema.addConstUndef(lhs_ty);
8240 },8304 },
82418305
8242 .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt)8306 .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)
8244 else8308 else
8245 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target),8309 try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target),
82468310
8247 .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt)8311 .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)
8249 else8313 else
8250 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target),8314 try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target),
82518315
...@@ -8296,6 +8360,7 @@ fn zirShr(...@@ -8296,6 +8360,7 @@ fn zirShr(
8296 const lhs_ty = sema.typeOf(lhs);8360 const lhs_ty = sema.typeOf(lhs);
8297 const rhs_ty = sema.typeOf(rhs);8361 const rhs_ty = sema.typeOf(rhs);
8298 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);8362 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
8363 const target = sema.mod.getTarget();
82998364
8300 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {8365 const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: {
8301 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {8366 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -8308,12 +8373,12 @@ fn zirShr(...@@ -8308,12 +8373,12 @@ fn zirShr(
8308 }8373 }
8309 if (air_tag == .shr_exact) {8374 if (air_tag == .shr_exact) {
8310 // Detect if any ones would be shifted out.8375 // 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);
8312 if (!truncated.compareWithZero(.eq)) {8377 if (!truncated.compareWithZero(.eq)) {
8313 return sema.addConstUndef(lhs_ty);8378 return sema.addConstUndef(lhs_ty);
8314 }8379 }
8315 }8380 }
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);
8317 return sema.addConstant(lhs_ty, val);8382 return sema.addConstant(lhs_ty, val);
8318 } else {8383 } else {
8319 // Even if lhs is not comptime known, we can still deduce certain things based8384 // Even if lhs is not comptime known, we can still deduce certain things based
...@@ -8359,6 +8424,7 @@ fn zirBitwise(...@@ -8359,6 +8424,7 @@ fn zirBitwise(
8359 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);8424 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
83608425
8361 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;8426 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
8427 const target = sema.mod.getTarget();
83628428
8363 if (!is_int) {8429 if (!is_int) {
8364 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });8430 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(...@@ -8367,9 +8433,9 @@ fn zirBitwise(
8367 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {8433 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
8368 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {8434 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
8369 const result_val = switch (air_tag) {8435 const result_val = switch (air_tag) {
8370 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena),8436 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
8371 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena),8437 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
8372 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena),8438 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
8373 else => unreachable,8439 else => unreachable,
8374 };8440 };
8375 return sema.addConstant(resolved_type, result_val);8441 return sema.addConstant(resolved_type, result_val);
...@@ -8391,13 +8457,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -8391,13 +8457,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
8391 const operand = sema.resolveInst(inst_data.operand);8457 const operand = sema.resolveInst(inst_data.operand);
8392 const operand_type = sema.typeOf(operand);8458 const operand_type = sema.typeOf(operand);
8393 const scalar_type = operand_type.scalarType();8459 const scalar_type = operand_type.scalarType();
8460 const target = sema.mod.getTarget();
83948461
8395 if (scalar_type.zigTypeTag() != .Int) {8462 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 });
8397 }8466 }
83988467
8399 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {8468 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
8400 const target = sema.mod.getTarget();
8401 if (val.isUndef()) {8469 if (val.isUndef()) {
8402 return sema.addConstUndef(operand_type);8470 return sema.addConstUndef(operand_type);
8403 } else if (operand_type.zigTypeTag() == .Vector) {8471 } else if (operand_type.zigTypeTag() == .Vector) {
...@@ -8513,19 +8581,22 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8513,19 +8581,22 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8513 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };8581 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
8514 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };8582 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
85158583
8584 const target = sema.mod.getTarget();
8516 const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse8585 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)});
8518 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse8587 const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse
8519 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty});8588 return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty.fmt(target)});
8520 if (!lhs_info.elem_type.eql(rhs_info.elem_type)) {8589 if (!lhs_info.elem_type.eql(rhs_info.elem_type, target)) {
8521 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty });8590 return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{
8591 lhs_info.elem_type.fmt(target), rhs_ty.fmt(target),
8592 });
8522 }8593 }
85238594
8524 // When there is a sentinel mismatch, no sentinel on the result. The type system8595 // When there is a sentinel mismatch, no sentinel on the result. The type system
8525 // will catch this if it is a problem.8596 // will catch this if it is a problem.
8526 var res_sent: ?Value = null;8597 var res_sent: ?Value = null;
8527 if (rhs_info.sentinel != null and lhs_info.sentinel != null) {8598 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)) {
8529 res_sent = lhs_info.sentinel.?;8600 res_sent = lhs_info.sentinel.?;
8530 }8601 }
8531 }8602 }
...@@ -8586,6 +8657,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8586,6 +8657,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
85868657
8587fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {8658fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo {
8588 const t = sema.typeOf(inst);8659 const t = sema.typeOf(inst);
8660 const target = sema.mod.getTarget();
8589 return switch (t.zigTypeTag()) {8661 return switch (t.zigTypeTag()) {
8590 .Array => t.arrayInfo(),8662 .Array => t.arrayInfo(),
8591 .Pointer => blk: {8663 .Pointer => blk: {
...@@ -8595,7 +8667,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R...@@ -8595,7 +8667,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.R
8595 return Type.ArrayInfo{8667 return Type.ArrayInfo{
8596 .elem_type = t.childType(),8668 .elem_type = t.childType(),
8597 .sentinel = t.sentinel(),8669 .sentinel = t.sentinel(),
8598 .len = val.sliceLen(),8670 .len = val.sliceLen(target),
8599 };8671 };
8600 }8672 }
8601 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;8673 if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null;
...@@ -8691,9 +8763,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -8691,9 +8763,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
8691 if (lhs_ty.isTuple()) {8763 if (lhs_ty.isTuple()) {
8692 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);8764 return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
8693 }8765 }
8766 const target = sema.mod.getTarget();
86948767
8695 const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse8768 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
8698 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch8771 const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch
8699 return sema.fail(block, rhs_src, "operation results in overflow", .{});8772 return sema.fail(block, rhs_src, "operation results in overflow", .{});
...@@ -8771,8 +8844,9 @@ fn zirNegate(...@@ -8771,8 +8844,9 @@ fn zirNegate(
8771 const rhs_ty = sema.typeOf(rhs);8844 const rhs_ty = sema.typeOf(rhs);
8772 const rhs_scalar_ty = rhs_ty.scalarType();8845 const rhs_scalar_ty = rhs_ty.scalarType();
87738846
8847 const target = sema.mod.getTarget();
8774 if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) {8848 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)});
8776 }8850 }
87778851
8778 const lhs = if (rhs_ty.zigTypeTag() == .Vector)8852 const lhs = if (rhs_ty.zigTypeTag() == .Vector)
...@@ -8824,15 +8898,14 @@ fn zirOverflowArithmetic(...@@ -8824,15 +8898,14 @@ fn zirOverflowArithmetic(
8824 const ptr = sema.resolveInst(extra.ptr);8898 const ptr = sema.resolveInst(extra.ptr);
88258899
8826 const lhs_ty = sema.typeOf(lhs);8900 const lhs_ty = sema.typeOf(lhs);
8901 const target = sema.mod.getTarget();
88278902
8828 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.8903 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.
8829 const dest_ty = lhs_ty;8904 const dest_ty = lhs_ty;
8830 if (dest_ty.zigTypeTag() != .Int) {8905 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)});
8832 }8907 }
88338908
8834 const target = sema.mod.getTarget();
8835
8836 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);8909 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs);
8837 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);8910 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs);
88388911
...@@ -8894,7 +8967,7 @@ fn zirOverflowArithmetic(...@@ -8894,7 +8967,7 @@ fn zirOverflowArithmetic(
8894 if (!lhs_val.isUndef()) {8967 if (!lhs_val.isUndef()) {
8895 if (lhs_val.compareWithZero(.eq)) {8968 if (lhs_val.compareWithZero(.eq)) {
8896 break :result .{ .overflowed = .no, .wrapped = lhs };8969 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)) {
8898 break :result .{ .overflowed = .no, .wrapped = rhs };8971 break :result .{ .overflowed = .no, .wrapped = rhs };
8899 }8972 }
8900 }8973 }
...@@ -8904,7 +8977,7 @@ fn zirOverflowArithmetic(...@@ -8904,7 +8977,7 @@ fn zirOverflowArithmetic(
8904 if (!rhs_val.isUndef()) {8977 if (!rhs_val.isUndef()) {
8905 if (rhs_val.compareWithZero(.eq)) {8978 if (rhs_val.compareWithZero(.eq)) {
8906 break :result .{ .overflowed = .no, .wrapped = rhs };8979 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)) {
8908 break :result .{ .overflowed = .no, .wrapped = lhs };8981 break :result .{ .overflowed = .no, .wrapped = lhs };
8909 }8982 }
8910 }8983 }
...@@ -9079,7 +9152,7 @@ fn analyzeArithmetic(...@@ -9079,7 +9152,7 @@ fn analyzeArithmetic(
9079 if (is_int) {9152 if (is_int) {
9080 return sema.addConstant(9153 return sema.addConstant(
9081 resolved_type,9154 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),
9083 );9156 );
9084 } else {9157 } else {
9085 return sema.addConstant(9158 return sema.addConstant(
...@@ -9132,7 +9205,7 @@ fn analyzeArithmetic(...@@ -9132,7 +9205,7 @@ fn analyzeArithmetic(
9132 }9205 }
9133 if (maybe_lhs_val) |lhs_val| {9206 if (maybe_lhs_val) |lhs_val| {
9134 const val = if (scalar_tag == .ComptimeInt)9207 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)
9136 else9209 else
9137 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target);9210 try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target);
91389211
...@@ -9172,7 +9245,7 @@ fn analyzeArithmetic(...@@ -9172,7 +9245,7 @@ fn analyzeArithmetic(
9172 if (is_int) {9245 if (is_int) {
9173 return sema.addConstant(9246 return sema.addConstant(
9174 resolved_type,9247 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),
9176 );9249 );
9177 } else {9250 } else {
9178 return sema.addConstant(9251 return sema.addConstant(
...@@ -9225,7 +9298,7 @@ fn analyzeArithmetic(...@@ -9225,7 +9298,7 @@ fn analyzeArithmetic(
9225 }9298 }
9226 if (maybe_rhs_val) |rhs_val| {9299 if (maybe_rhs_val) |rhs_val| {
9227 const val = if (scalar_tag == .ComptimeInt)9300 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)
9229 else9302 else
9230 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target);9303 try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target);
92319304
...@@ -9275,7 +9348,7 @@ fn analyzeArithmetic(...@@ -9275,7 +9348,7 @@ fn analyzeArithmetic(
9275 if (lhs_val.isUndef()) {9348 if (lhs_val.isUndef()) {
9276 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9349 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9277 if (maybe_rhs_val) |rhs_val| {9350 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)) {
9279 return sema.addConstUndef(resolved_type);9352 return sema.addConstUndef(resolved_type);
9280 }9353 }
9281 }9354 }
...@@ -9288,7 +9361,7 @@ fn analyzeArithmetic(...@@ -9288,7 +9361,7 @@ fn analyzeArithmetic(
9288 if (is_int) {9361 if (is_int) {
9289 return sema.addConstant(9362 return sema.addConstant(
9290 resolved_type,9363 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),
9292 );9365 );
9293 } else {9366 } else {
9294 return sema.addConstant(9367 return sema.addConstant(
...@@ -9350,7 +9423,7 @@ fn analyzeArithmetic(...@@ -9350,7 +9423,7 @@ fn analyzeArithmetic(
9350 if (lhs_val.isUndef()) {9423 if (lhs_val.isUndef()) {
9351 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9424 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9352 if (maybe_rhs_val) |rhs_val| {9425 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)) {
9354 return sema.addConstUndef(resolved_type);9427 return sema.addConstUndef(resolved_type);
9355 }9428 }
9356 }9429 }
...@@ -9363,7 +9436,7 @@ fn analyzeArithmetic(...@@ -9363,7 +9436,7 @@ fn analyzeArithmetic(
9363 if (is_int) {9436 if (is_int) {
9364 return sema.addConstant(9437 return sema.addConstant(
9365 resolved_type,9438 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),
9367 );9440 );
9368 } else {9441 } else {
9369 return sema.addConstant(9442 return sema.addConstant(
...@@ -9413,7 +9486,7 @@ fn analyzeArithmetic(...@@ -9413,7 +9486,7 @@ fn analyzeArithmetic(
9413 if (lhs_val.isUndef()) {9486 if (lhs_val.isUndef()) {
9414 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {9487 if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) {
9415 if (maybe_rhs_val) |rhs_val| {9488 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)) {
9417 return sema.addConstUndef(resolved_type);9490 return sema.addConstUndef(resolved_type);
9418 }9491 }
9419 }9492 }
...@@ -9426,7 +9499,7 @@ fn analyzeArithmetic(...@@ -9426,7 +9499,7 @@ fn analyzeArithmetic(
9426 if (is_int) {9499 if (is_int) {
9427 return sema.addConstant(9500 return sema.addConstant(
9428 resolved_type,9501 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),
9430 );9503 );
9431 } else {9504 } else {
9432 return sema.addConstant(9505 return sema.addConstant(
...@@ -9477,7 +9550,7 @@ fn analyzeArithmetic(...@@ -9477,7 +9550,7 @@ fn analyzeArithmetic(
9477 // TODO: emit compile error if there is a remainder9550 // TODO: emit compile error if there is a remainder
9478 return sema.addConstant(9551 return sema.addConstant(
9479 resolved_type,9552 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),
9481 );9554 );
9482 } else {9555 } else {
9483 // TODO: emit compile error if there is a remainder9556 // TODO: emit compile error if there is a remainder
...@@ -9503,7 +9576,7 @@ fn analyzeArithmetic(...@@ -9503,7 +9576,7 @@ fn analyzeArithmetic(
9503 if (lhs_val.compareWithZero(.eq)) {9576 if (lhs_val.compareWithZero(.eq)) {
9504 return sema.addConstant(resolved_type, Value.zero);9577 return sema.addConstant(resolved_type, Value.zero);
9505 }9578 }
9506 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9579 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9507 return casted_rhs;9580 return casted_rhs;
9508 }9581 }
9509 }9582 }
...@@ -9519,7 +9592,7 @@ fn analyzeArithmetic(...@@ -9519,7 +9592,7 @@ fn analyzeArithmetic(
9519 if (rhs_val.compareWithZero(.eq)) {9592 if (rhs_val.compareWithZero(.eq)) {
9520 return sema.addConstant(resolved_type, Value.zero);9593 return sema.addConstant(resolved_type, Value.zero);
9521 }9594 }
9522 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9595 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9523 return casted_lhs;9596 return casted_lhs;
9524 }9597 }
9525 if (maybe_lhs_val) |lhs_val| {9598 if (maybe_lhs_val) |lhs_val| {
...@@ -9533,7 +9606,7 @@ fn analyzeArithmetic(...@@ -9533,7 +9606,7 @@ fn analyzeArithmetic(
9533 if (is_int) {9606 if (is_int) {
9534 return sema.addConstant(9607 return sema.addConstant(
9535 resolved_type,9608 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),
9537 );9610 );
9538 } else {9611 } else {
9539 return sema.addConstant(9612 return sema.addConstant(
...@@ -9554,7 +9627,7 @@ fn analyzeArithmetic(...@@ -9554,7 +9627,7 @@ fn analyzeArithmetic(
9554 if (lhs_val.compareWithZero(.eq)) {9627 if (lhs_val.compareWithZero(.eq)) {
9555 return sema.addConstant(resolved_type, Value.zero);9628 return sema.addConstant(resolved_type, Value.zero);
9556 }9629 }
9557 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9630 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9558 return casted_rhs;9631 return casted_rhs;
9559 }9632 }
9560 }9633 }
...@@ -9566,7 +9639,7 @@ fn analyzeArithmetic(...@@ -9566,7 +9639,7 @@ fn analyzeArithmetic(
9566 if (rhs_val.compareWithZero(.eq)) {9639 if (rhs_val.compareWithZero(.eq)) {
9567 return sema.addConstant(resolved_type, Value.zero);9640 return sema.addConstant(resolved_type, Value.zero);
9568 }9641 }
9569 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9642 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9570 return casted_lhs;9643 return casted_lhs;
9571 }9644 }
9572 if (maybe_lhs_val) |lhs_val| {9645 if (maybe_lhs_val) |lhs_val| {
...@@ -9590,7 +9663,7 @@ fn analyzeArithmetic(...@@ -9590,7 +9663,7 @@ fn analyzeArithmetic(
9590 if (lhs_val.compareWithZero(.eq)) {9663 if (lhs_val.compareWithZero(.eq)) {
9591 return sema.addConstant(resolved_type, Value.zero);9664 return sema.addConstant(resolved_type, Value.zero);
9592 }9665 }
9593 if (lhs_val.compare(.eq, Value.one, lhs_ty)) {9666 if (lhs_val.compare(.eq, Value.one, lhs_ty, target)) {
9594 return casted_rhs;9667 return casted_rhs;
9595 }9668 }
9596 }9669 }
...@@ -9602,7 +9675,7 @@ fn analyzeArithmetic(...@@ -9602,7 +9675,7 @@ fn analyzeArithmetic(
9602 if (rhs_val.compareWithZero(.eq)) {9675 if (rhs_val.compareWithZero(.eq)) {
9603 return sema.addConstant(resolved_type, Value.zero);9676 return sema.addConstant(resolved_type, Value.zero);
9604 }9677 }
9605 if (rhs_val.compare(.eq, Value.one, rhs_ty)) {9678 if (rhs_val.compare(.eq, Value.one, rhs_ty, target)) {
9606 return casted_lhs;9679 return casted_lhs;
9607 }9680 }
9608 if (maybe_lhs_val) |lhs_val| {9681 if (maybe_lhs_val) |lhs_val| {
...@@ -9611,7 +9684,7 @@ fn analyzeArithmetic(...@@ -9611,7 +9684,7 @@ fn analyzeArithmetic(
9611 }9684 }
96129685
9613 const val = if (scalar_tag == .ComptimeInt)9686 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)
9615 else9688 else
9616 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target);9689 try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target);
96179690
...@@ -9652,7 +9725,7 @@ fn analyzeArithmetic(...@@ -9652,7 +9725,7 @@ fn analyzeArithmetic(
9652 return sema.failWithDivideByZero(block, rhs_src);9725 return sema.failWithDivideByZero(block, rhs_src);
9653 }9726 }
9654 if (maybe_lhs_val) |lhs_val| {9727 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);
9656 // If this answer could possibly be different by doing `intMod`,9729 // If this answer could possibly be different by doing `intMod`,
9657 // we must emit a compile error. Otherwise, it's OK.9730 // we must emit a compile error. Otherwise, it's OK.
9658 if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and9731 if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and
...@@ -9731,7 +9804,7 @@ fn analyzeArithmetic(...@@ -9731,7 +9804,7 @@ fn analyzeArithmetic(
9731 if (maybe_lhs_val) |lhs_val| {9804 if (maybe_lhs_val) |lhs_val| {
9732 return sema.addConstant(9805 return sema.addConstant(
9733 resolved_type,9806 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),
9735 );9808 );
9736 }9809 }
9737 break :rs .{ .src = lhs_src, .air_tag = .rem };9810 break :rs .{ .src = lhs_src, .air_tag = .rem };
...@@ -9788,7 +9861,7 @@ fn analyzeArithmetic(...@@ -9788,7 +9861,7 @@ fn analyzeArithmetic(
9788 if (maybe_lhs_val) |lhs_val| {9861 if (maybe_lhs_val) |lhs_val| {
9789 return sema.addConstant(9862 return sema.addConstant(
9790 resolved_type,9863 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),
9792 );9865 );
9793 }9866 }
9794 break :rs .{ .src = lhs_src, .air_tag = .mod };9867 break :rs .{ .src = lhs_src, .air_tag = .mod };
...@@ -9839,6 +9912,7 @@ fn analyzePtrArithmetic(...@@ -9839,6 +9912,7 @@ fn analyzePtrArithmetic(
9839 // coerce to isize instead of usize.9912 // coerce to isize instead of usize.
9840 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);9913 const offset = try sema.coerce(block, Type.usize, uncasted_offset, offset_src);
9841 // TODO adjust the return type according to alignment and other factors9914 // TODO adjust the return type according to alignment and other factors
9915 const target = sema.mod.getTarget();
9842 const runtime_src = rs: {9916 const runtime_src = rs: {
9843 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {9917 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| {
9844 if (try sema.resolveMaybeUndefVal(block, offset_src, offset)) |offset_val| {9918 if (try sema.resolveMaybeUndefVal(block, offset_src, offset)) |offset_val| {
...@@ -9849,11 +9923,10 @@ fn analyzePtrArithmetic(...@@ -9849,11 +9923,10 @@ fn analyzePtrArithmetic(
9849 return sema.addConstUndef(new_ptr_ty);9923 return sema.addConstUndef(new_ptr_ty);
9850 }9924 }
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));
9853 // TODO I tried to put this check earlier but it the LLVM backend generate invalid instructinons9927 // TODO I tried to put this check earlier but it the LLVM backend generate invalid instructinons
9854 if (offset_int == 0) return ptr;9928 if (offset_int == 0) return ptr;
9855 if (ptr_val.getUnsignedInt()) |addr| {9929 if (try ptr_val.getUnsignedIntAdvanced(target, sema.kit(block, ptr_src))) |addr| {
9856 const target = sema.mod.getTarget();
9857 const ptr_child_ty = ptr_ty.childType();9930 const ptr_child_ty = ptr_ty.childType();
9858 const elem_ty = if (ptr_ty.isSinglePointer() and ptr_child_ty.zigTypeTag() == .Array)9931 const elem_ty = if (ptr_ty.isSinglePointer() and ptr_child_ty.zigTypeTag() == .Array)
9859 ptr_child_ty.childType()9932 ptr_child_ty.childType()
...@@ -9872,7 +9945,7 @@ fn analyzePtrArithmetic(...@@ -9872,7 +9945,7 @@ fn analyzePtrArithmetic(
9872 if (air_tag == .ptr_sub) {9945 if (air_tag == .ptr_sub) {
9873 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});9946 return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
9874 }9947 }
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);
9876 return sema.addConstant(new_ptr_ty, new_ptr_val);9949 return sema.addConstant(new_ptr_ty, new_ptr_val);
9877 } else break :rs offset_src;9950 } else break :rs offset_src;
9878 } else break :rs ptr_src;9951 } else break :rs ptr_src;
...@@ -10035,6 +10108,7 @@ fn zirCmpEq(...@@ -10035,6 +10108,7 @@ fn zirCmpEq(
10035 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };10108 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
10036 const lhs = sema.resolveInst(extra.lhs);10109 const lhs = sema.resolveInst(extra.lhs);
10037 const rhs = sema.resolveInst(extra.rhs);10110 const rhs = sema.resolveInst(extra.rhs);
10111 const target = sema.mod.getTarget();
1003810112
10039 const lhs_ty = sema.typeOf(lhs);10113 const lhs_ty = sema.typeOf(lhs);
10040 const rhs_ty = sema.typeOf(rhs);10114 const rhs_ty = sema.typeOf(rhs);
...@@ -10059,7 +10133,7 @@ fn zirCmpEq(...@@ -10059,7 +10133,7 @@ fn zirCmpEq(
1005910133
10060 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {10134 if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
10061 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;10135 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)});
10063 }10137 }
1006410138
10065 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {10139 if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) {
...@@ -10099,7 +10173,7 @@ fn zirCmpEq(...@@ -10099,7 +10173,7 @@ fn zirCmpEq(
10099 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {10173 if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
10100 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);10174 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
10101 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);10175 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)) {
10103 return Air.Inst.Ref.bool_true;10177 return Air.Inst.Ref.bool_true;
10104 } else {10178 } else {
10105 return Air.Inst.Ref.bool_false;10179 return Air.Inst.Ref.bool_false;
...@@ -10176,9 +10250,10 @@ fn analyzeCmp(...@@ -10176,9 +10250,10 @@ fn analyzeCmp(
10176 }10250 }
10177 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };10251 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
10178 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });10252 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
10253 const target = sema.mod.getTarget();
10179 if (!resolved_type.isSelfComparable(is_equality_cmp)) {10254 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
10180 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{10255 return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{
10181 @tagName(op), resolved_type,10256 @tagName(op), resolved_type.fmt(target),
10182 });10257 });
10183 }10258 }
10184 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);10259 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -10196,6 +10271,7 @@ fn cmpSelf(...@@ -10196,6 +10271,7 @@ fn cmpSelf(
10196 rhs_src: LazySrcLoc,10271 rhs_src: LazySrcLoc,
10197) CompileError!Air.Inst.Ref {10272) CompileError!Air.Inst.Ref {
10198 const resolved_type = sema.typeOf(casted_lhs);10273 const resolved_type = sema.typeOf(casted_lhs);
10274 const target = sema.mod.getTarget();
10199 const runtime_src: LazySrcLoc = src: {10275 const runtime_src: LazySrcLoc = src: {
10200 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {10276 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
10201 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);10277 if (lhs_val.isUndef()) return sema.addConstUndef(Type.bool);
...@@ -10204,11 +10280,11 @@ fn cmpSelf(...@@ -10204,11 +10280,11 @@ fn cmpSelf(
1020410280
10205 if (resolved_type.zigTypeTag() == .Vector) {10281 if (resolved_type.zigTypeTag() == .Vector) {
10206 const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool");10282 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);
10208 return sema.addConstant(result_ty, cmp_val);10284 return sema.addConstant(result_ty, cmp_val);
10209 }10285 }
1021010286
10211 if (lhs_val.compare(op, rhs_val, resolved_type)) {10287 if (lhs_val.compare(op, rhs_val, resolved_type, target)) {
10212 return Air.Inst.Ref.bool_true;10288 return Air.Inst.Ref.bool_true;
10213 } else {10289 } else {
10214 return Air.Inst.Ref.bool_false;10290 return Air.Inst.Ref.bool_false;
...@@ -10276,7 +10352,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -10276,7 +10352,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
10276 .Null,10352 .Null,
10277 .BoundFn,10353 .BoundFn,
10278 .Opaque,10354 .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
10281 .Type,10357 .Type,
10282 .EnumLiteral,10358 .EnumLiteral,
...@@ -11365,11 +11441,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi...@@ -11365,11 +11441,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
11365 },11441 },
11366 else => {},11442 else => {},
11367 }11443 }
11444 const target = sema.mod.getTarget();
11368 return sema.fail(11445 return sema.fail(
11369 block,11446 block,
11370 src,11447 src,
11371 "bit shifting operation expected integer type, found '{}'",11448 "bit shifting operation expected integer type, found '{}'",
11372 .{operand},11449 .{operand.fmt(target)},
11373 );11450 );
11374}11451}
1137511452
...@@ -11786,6 +11863,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -11786,6 +11863,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
11786 const elem_ty_src: LazySrcLoc = .unneeded;11863 const elem_ty_src: LazySrcLoc = .unneeded;
11787 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;11864 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
11788 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);11865 const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
11866 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
11867 const target = sema.mod.getTarget();
1178911868
11790 var extra_i = extra.end;11869 var extra_i = extra.end;
1179111870
...@@ -11795,10 +11874,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -11795,10 +11874,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
11795 break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val;11874 break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val;
11796 } else null;11875 } else null;
1179711876
11798 const abi_align = if (inst_data.flags.has_align) blk: {11877 const abi_align: u32 = if (inst_data.flags.has_align) blk: {
11799 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);11878 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
11800 extra_i += 1;11879 extra_i += 1;
11801 const abi_align = try sema.resolveInt(block, .unneeded, ref, Type.u32);11880 const coerced = try sema.coerce(block, Type.u32, sema.resolveInst(ref), src);
11881 const val = try sema.resolveConstValue(block, src, coerced);
11882 // Check if this happens to be the lazy alignment of our element type, in
11883 // which case we can make this 0 without resolving it.
11884 if (val.castTag(.lazy_align)) |payload| {
11885 if (payload.data.eql(unresolved_elem_ty, target)) {
11886 break :blk 0;
11887 }
11888 }
11889 const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
11802 break :blk @intCast(u32, abi_align);11890 break :blk @intCast(u32, abi_align);
11803 } else 0;11891 } else 0;
1180411892
...@@ -11826,7 +11914,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -11826,7 +11914,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
11826 return sema.fail(block, src, "bit offset starts after end of host integer", .{});11914 return sema.fail(block, src, "bit offset starts after end of host integer", .{});
11827 }11915 }
1182811916
11829 const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
11830 const elem_ty = if (abi_align == 0)11917 const elem_ty = if (abi_align == 0)
11831 unresolved_elem_ty11918 unresolved_elem_ty
11832 else t: {11919 else t: {
...@@ -11834,7 +11921,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -11834,7 +11921,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
11834 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);11921 try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
11835 break :t elem_ty;11922 break :t elem_ty;
11836 };11923 };
11837 const target = sema.mod.getTarget();
11838 const ty = try Type.ptr(sema.arena, target, .{11924 const ty = try Type.ptr(sema.arena, target, .{
11839 .pointee_type = elem_ty,11925 .pointee_type = elem_ty,
11840 .sentinel = sentinel,11926 .sentinel = sentinel,
...@@ -12414,6 +12500,7 @@ fn fieldType(...@@ -12414,6 +12500,7 @@ fn fieldType(
12414 ty_src: LazySrcLoc,12500 ty_src: LazySrcLoc,
12415) CompileError!Air.Inst.Ref {12501) CompileError!Air.Inst.Ref {
12416 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);12502 const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
12503 const target = sema.mod.getTarget();
12417 switch (resolved_ty.zigTypeTag()) {12504 switch (resolved_ty.zigTypeTag()) {
12418 .Struct => {12505 .Struct => {
12419 const struct_obj = resolved_ty.castTag(.@"struct").?.data;12506 const struct_obj = resolved_ty.castTag(.@"struct").?.data;
...@@ -12428,7 +12515,7 @@ fn fieldType(...@@ -12428,7 +12515,7 @@ fn fieldType(
12428 return sema.addType(field.ty);12515 return sema.addType(field.ty);
12429 },12516 },
12430 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{12517 else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
12431 resolved_ty,12518 resolved_ty.fmt(target),
12432 }),12519 }),
12433 }12520 }
12434}12521}
...@@ -12459,11 +12546,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12459,11 +12546,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12459 const inst_data = sema.code.instructions.items(.data)[inst].un_node;12546 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
12460 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12547 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12461 const ty = try sema.resolveType(block, operand_src, inst_data.operand);12548 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);
12464 const target = sema.mod.getTarget();12549 const target = sema.mod.getTarget();
12465 const abi_align = resolved_ty.abiAlignment(target);12550 return sema.addConstant(
12466 return sema.addIntUnsigned(Type.comptime_int, abi_align);12551 Type.comptime_int,
12552 try ty.lazyAbiAlignment(target, sema.arena),
12553 );
12467}12554}
1246812555
12469fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12556fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -12509,6 +12596,7 @@ fn zirUnaryMath(...@@ -12509,6 +12596,7 @@ fn zirUnaryMath(
12509 const operand = sema.resolveInst(inst_data.operand);12596 const operand = sema.resolveInst(inst_data.operand);
12510 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12597 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12511 const operand_ty = sema.typeOf(operand);12598 const operand_ty = sema.typeOf(operand);
12599 const target = sema.mod.getTarget();
1251212600
12513 switch (operand_ty.zigTypeTag()) {12601 switch (operand_ty.zigTypeTag()) {
12514 .ComptimeFloat, .Float => {},12602 .ComptimeFloat, .Float => {},
...@@ -12516,13 +12604,12 @@ fn zirUnaryMath(...@@ -12516,13 +12604,12 @@ fn zirUnaryMath(
12516 const scalar_ty = operand_ty.scalarType();12604 const scalar_ty = operand_ty.scalarType();
12517 switch (scalar_ty.zigTypeTag()) {12605 switch (scalar_ty.zigTypeTag()) {
12518 .ComptimeFloat, .Float => {},12606 .ComptimeFloat, .Float => {},
12519 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty}),12607 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{scalar_ty.fmt(target)}),
12520 }12608 }
12521 },12609 },
12522 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty}),12610 else => return sema.fail(block, operand_src, "expected vector of floats or float type, found '{}'", .{operand_ty.fmt(target)}),
12523 }12611 }
1252412612
12525 const target = sema.mod.getTarget();
12526 switch (operand_ty.zigTypeTag()) {12613 switch (operand_ty.zigTypeTag()) {
12527 .Vector => {12614 .Vector => {
12528 const scalar_ty = operand_ty.scalarType();12615 const scalar_ty = operand_ty.scalarType();
...@@ -12568,6 +12655,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12568,6 +12655,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12568 const src = inst_data.src();12655 const src = inst_data.src();
12569 const operand = sema.resolveInst(inst_data.operand);12656 const operand = sema.resolveInst(inst_data.operand);
12570 const operand_ty = sema.typeOf(operand);12657 const operand_ty = sema.typeOf(operand);
12658 const target = sema.mod.getTarget();
1257112659
12572 try sema.resolveTypeLayout(block, operand_src, operand_ty);12660 try sema.resolveTypeLayout(block, operand_src, operand_ty);
12573 const enum_ty = switch (operand_ty.zigTypeTag()) {12661 const enum_ty = switch (operand_ty.zigTypeTag()) {
...@@ -12590,13 +12678,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -12590,13 +12678,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12590 return sema.failWithOwnedErrorMsg(block, msg);12678 return sema.failWithOwnedErrorMsg(block, msg);
12591 },12679 },
12592 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{12680 else => return sema.fail(block, operand_src, "expected enum or union; found {}", .{
12593 operand_ty,12681 operand_ty.fmt(target),
12594 }),12682 }),
12595 };12683 };
12596 const enum_decl = enum_ty.getOwnerDecl();12684 const enum_decl = enum_ty.getOwnerDecl();
12597 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);12685 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
12598 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {12686 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
12599 const field_index = enum_ty.enumTagFieldIndex(val) orelse {12687 const field_index = enum_ty.enumTagFieldIndex(val, target) orelse {
12600 const msg = msg: {12688 const msg = msg: {
12601 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{12689 const msg = try sema.errMsg(block, src, "no field with value {} in enum '{s}'", .{
12602 casted_operand, enum_decl.name,12690 casted_operand, enum_decl.name,
...@@ -12626,8 +12714,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12626,8 +12714,8 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12626 const val = try sema.resolveConstValue(block, operand_src, type_info);12714 const val = try sema.resolveConstValue(block, operand_src, type_info);
12627 const union_val = val.cast(Value.Payload.Union).?.data;12715 const union_val = val.cast(Value.Payload.Union).?.data;
12628 const tag_ty = type_info_ty.unionTagType().?;12716 const tag_ty = type_info_ty.unionTagType().?;
12629 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag).?;
12630 const target = sema.mod.getTarget();12717 const target = sema.mod.getTarget();
12718 const tag_index = tag_ty.enumTagFieldIndex(union_val.tag, target).?;
12631 switch (@intToEnum(std.builtin.TypeId, tag_index)) {12719 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
12632 .Type => return Air.Inst.Ref.type_type,12720 .Type => return Air.Inst.Ref.type_type,
12633 .Void => return Air.Inst.Ref.void_type,12721 .Void => return Air.Inst.Ref.void_type,
...@@ -12646,7 +12734,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12646,7 +12734,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12646 const bits_val = struct_val[1];12734 const bits_val = struct_val[1];
1264712735
12648 const signedness = signedness_val.toEnum(std.builtin.Signedness);12736 const signedness = signedness_val.toEnum(std.builtin.Signedness);
12649 const bits = @intCast(u16, bits_val.toUnsignedInt());12737 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
12650 const ty = switch (signedness) {12738 const ty = switch (signedness) {
12651 .signed => try Type.Tag.int_signed.create(sema.arena, bits),12739 .signed => try Type.Tag.int_signed.create(sema.arena, bits),
12652 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),12740 .unsigned => try Type.Tag.int_unsigned.create(sema.arena, bits),
...@@ -12659,7 +12747,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12659,7 +12747,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12659 const len_val = struct_val[0];12747 const len_val = struct_val[0];
12660 const child_val = struct_val[1];12748 const child_val = struct_val[1];
1266112749
12662 const len = len_val.toUnsignedInt();12750 const len = len_val.toUnsignedInt(target);
12663 var buffer: Value.ToTypeBuffer = undefined;12751 var buffer: Value.ToTypeBuffer = undefined;
12664 const child_ty = child_val.toType(&buffer);12752 const child_ty = child_val.toType(&buffer);
1266512753
...@@ -12672,7 +12760,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12672,7 +12760,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12672 // bits: comptime_int,12760 // bits: comptime_int,
12673 const bits_val = struct_val[0];12761 const bits_val = struct_val[0];
1267412762
12675 const bits = @intCast(u16, bits_val.toUnsignedInt());12763 const bits = @intCast(u16, bits_val.toUnsignedInt(target));
12676 const ty = switch (bits) {12764 const ty = switch (bits) {
12677 16 => Type.@"f16",12765 16 => Type.@"f16",
12678 32 => Type.@"f32",12766 32 => Type.@"f32",
...@@ -12717,7 +12805,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12717,7 +12805,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12717 .size = ptr_size,12805 .size = ptr_size,
12718 .mutable = !is_const_val.toBool(),12806 .mutable = !is_const_val.toBool(),
12719 .@"volatile" = is_volatile_val.toBool(),12807 .@"volatile" = is_volatile_val.toBool(),
12720 .@"align" = @intCast(u16, alignment_val.toUnsignedInt()), // TODO: Validate this value.12808 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
12721 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),12809 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
12722 .pointee_type = try child_ty.copy(sema.arena),12810 .pointee_type = try child_ty.copy(sema.arena),
12723 .@"allowzero" = is_allowzero_val.toBool(),12811 .@"allowzero" = is_allowzero_val.toBool(),
...@@ -12735,7 +12823,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12735,7 +12823,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12735 // sentinel: ?*const anyopaque,12823 // sentinel: ?*const anyopaque,
12736 const sentinel_val = struct_val[2];12824 const sentinel_val = struct_val[2];
1273712825
12738 const len = len_val.toUnsignedInt();12826 const len = len_val.toUnsignedInt(target);
12739 var buffer: Value.ToTypeBuffer = undefined;12827 var buffer: Value.ToTypeBuffer = undefined;
12740 const child_ty = try child_val.toType(&buffer).copy(sema.arena);12828 const child_ty = try child_val.toType(&buffer).copy(sema.arena);
12741 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {12829 const sentinel = if (sentinel_val.castTag(.opt_payload)) |p| blk: {
...@@ -12746,7 +12834,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12746,7 +12834,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12746 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;12834 break :blk (try sema.pointerDeref(block, src, p.data, ptr_ty)).?;
12747 } else null;12835 } else null;
1274812836
12749 const ty = try Type.array(sema.arena, len, sentinel, child_ty);12837 const ty = try Type.array(sema.arena, len, sentinel, child_ty, target);
12750 return sema.addType(ty);12838 return sema.addType(ty);
12751 },12839 },
12752 .Optional => {12840 .Optional => {
...@@ -12796,7 +12884,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12796,7 +12884,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12796 const name_val = struct_val[0];12884 const name_val = struct_val[0];
1279712885
12798 names.putAssumeCapacityNoClobber(12886 names.putAssumeCapacityNoClobber(
12799 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),12887 try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
12800 {},12888 {},
12801 );12889 );
12802 }12890 }
...@@ -12817,7 +12905,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12817,7 +12905,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12817 const is_tuple_val = struct_val[3];12905 const is_tuple_val = struct_val[3];
1281812906
12819 // Decls12907 // Decls
12820 if (decls_val.sliceLen() > 0) {12908 if (decls_val.sliceLen(target) > 0) {
12821 return sema.fail(block, src, "reified structs must have no decls", .{});12909 return sema.fail(block, src, "reified structs must have no decls", .{});
12822 }12910 }
1282312911
...@@ -12847,7 +12935,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12847,7 +12935,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12847 }12935 }
1284812936
12849 // Decls12937 // Decls
12850 if (decls_val.sliceLen() > 0) {12938 if (decls_val.sliceLen(target) > 0) {
12851 return sema.fail(block, src, "reified enums must have no decls", .{});12939 return sema.fail(block, src, "reified enums must have no decls", .{});
12852 }12940 }
1285312941
...@@ -12898,11 +12986,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12898,11 +12986,12 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12898 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);12986 enum_obj.tag_ty = try tag_type_val.toType(&buffer).copy(new_decl_arena_allocator);
1289912987
12900 // Fields12988 // Fields
12901 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());12989 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
12902 if (fields_len > 0) {12990 if (fields_len > 0) {
12903 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);12991 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
12904 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{12992 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
12905 .ty = enum_obj.tag_ty,12993 .ty = enum_obj.tag_ty,
12994 .target = target,
12906 });12995 });
1290712996
12908 var i: usize = 0;12997 var i: usize = 0;
...@@ -12918,6 +13007,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12918,6 +13007,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12918 const field_name = try name_val.toAllocatedBytes(13007 const field_name = try name_val.toAllocatedBytes(
12919 Type.initTag(.const_slice_u8),13008 Type.initTag(.const_slice_u8),
12920 new_decl_arena_allocator,13009 new_decl_arena_allocator,
13010 target,
12921 );13011 );
1292213012
12923 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);13013 const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -12929,6 +13019,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12929,6 +13019,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12929 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);13019 const copied_tag_val = try value_val.copy(new_decl_arena_allocator);
12930 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{13020 enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{
12931 .ty = enum_obj.tag_ty,13021 .ty = enum_obj.tag_ty,
13022 .target = target,
12932 });13023 });
12933 }13024 }
12934 }13025 }
...@@ -12942,7 +13033,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12942,7 +13033,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12942 const decls_val = struct_val[0];13033 const decls_val = struct_val[0];
1294313034
12944 // Decls13035 // Decls
12945 if (decls_val.sliceLen() > 0) {13036 if (decls_val.sliceLen(target) > 0) {
12946 return sema.fail(block, src, "reified opaque must have no decls", .{});13037 return sema.fail(block, src, "reified opaque must have no decls", .{});
12947 }13038 }
1294813039
...@@ -12993,7 +13084,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -12993,7 +13084,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
12993 const decls_val = struct_val[3];13084 const decls_val = struct_val[3];
1299413085
12995 // Decls13086 // Decls
12996 if (decls_val.sliceLen() > 0) {13087 if (decls_val.sliceLen(target) > 0) {
12997 return sema.fail(block, src, "reified unions must have no decls", .{});13088 return sema.fail(block, src, "reified unions must have no decls", .{});
12998 }13089 }
1299913090
...@@ -13033,7 +13124,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13033,7 +13124,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13033 };13124 };
1303413125
13035 // Tag type13126 // Tag type
13036 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13127 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13037 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {13128 union_obj.tag_ty = if (tag_type_val.optionalValue()) |payload_val| blk: {
13038 var buffer: Value.ToTypeBuffer = undefined;13129 var buffer: Value.ToTypeBuffer = undefined;
13039 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);13130 break :blk try payload_val.toType(&buffer).copy(new_decl_arena_allocator);
...@@ -13058,6 +13149,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13058,6 +13149,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13058 const field_name = try name_val.toAllocatedBytes(13149 const field_name = try name_val.toAllocatedBytes(
13059 Type.initTag(.const_slice_u8),13150 Type.initTag(.const_slice_u8),
13060 new_decl_arena_allocator,13151 new_decl_arena_allocator,
13152 target,
13061 );13153 );
1306213154
13063 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);13155 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13069,7 +13161,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -13069,7 +13161,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
13069 var buffer: Value.ToTypeBuffer = undefined;13161 var buffer: Value.ToTypeBuffer = undefined;
13070 gop.value_ptr.* = .{13162 gop.value_ptr.* = .{
13071 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),13163 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13072 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),13164 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
13073 };13165 };
13074 }13166 }
13075 }13167 }
...@@ -13089,7 +13181,9 @@ fn reifyTuple(...@@ -13089,7 +13181,9 @@ fn reifyTuple(
13089 src: LazySrcLoc,13181 src: LazySrcLoc,
13090 fields_val: Value,13182 fields_val: Value,
13091) CompileError!Air.Inst.Ref {13183) CompileError!Air.Inst.Ref {
13092 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13184 const target = sema.mod.getTarget();
13185
13186 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13093 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));13187 if (fields_len == 0) return sema.addType(Type.initTag(.empty_struct_literal));
1309413188
13095 const types = try sema.arena.alloc(Type, fields_len);13189 const types = try sema.arena.alloc(Type, fields_len);
...@@ -13114,6 +13208,7 @@ fn reifyTuple(...@@ -13114,6 +13208,7 @@ fn reifyTuple(
13114 const field_name = try name_val.toAllocatedBytes(13208 const field_name = try name_val.toAllocatedBytes(
13115 Type.initTag(.const_slice_u8),13209 Type.initTag(.const_slice_u8),
13116 sema.arena,13210 sema.arena,
13211 target,
13117 );13212 );
1311813213
13119 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {13214 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
...@@ -13197,8 +13292,10 @@ fn reifyStruct(...@@ -13197,8 +13292,10 @@ fn reifyStruct(
13197 },13292 },
13198 };13293 };
1319913294
13295 const target = sema.mod.getTarget();
13296
13200 // Fields13297 // Fields
13201 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen());13298 const fields_len = try sema.usizeCast(block, src, fields_val.sliceLen(target));
13202 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);13299 try struct_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
13203 var i: usize = 0;13300 var i: usize = 0;
13204 while (i < fields_len) : (i += 1) {13301 while (i < fields_len) : (i += 1) {
...@@ -13219,6 +13316,7 @@ fn reifyStruct(...@@ -13219,6 +13316,7 @@ fn reifyStruct(
13219 const field_name = try name_val.toAllocatedBytes(13316 const field_name = try name_val.toAllocatedBytes(
13220 Type.initTag(.const_slice_u8),13317 Type.initTag(.const_slice_u8),
13221 new_decl_arena_allocator,13318 new_decl_arena_allocator,
13319 target,
13222 );13320 );
1322313321
13224 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);13322 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
...@@ -13238,7 +13336,7 @@ fn reifyStruct(...@@ -13238,7 +13336,7 @@ fn reifyStruct(
13238 var buffer: Value.ToTypeBuffer = undefined;13336 var buffer: Value.ToTypeBuffer = undefined;
13239 gop.value_ptr.* = .{13337 gop.value_ptr.* = .{
13240 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),13338 .ty = try field_type_val.toType(&buffer).copy(new_decl_arena_allocator),
13241 .abi_align = @intCast(u32, alignment_val.toUnsignedInt()),13339 .abi_align = @intCast(u32, alignment_val.toUnsignedInt(target)),
13242 .default_val = default_val,13340 .default_val = default_val,
13243 .is_comptime = is_comptime_val.toBool(),13341 .is_comptime = is_comptime_val.toBool(),
13244 .offset = undefined,13342 .offset = undefined,
...@@ -13257,7 +13355,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13257,7 +13355,8 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13257 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);13355 var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded);
13258 defer anon_decl.deinit();13356 defer anon_decl.deinit();
1325913357
13260 const bytes = try ty.nameAllocArena(anon_decl.arena());13358 const target = sema.mod.getTarget();
13359 const bytes = try ty.nameAllocArena(anon_decl.arena(), target);
1326113360
13262 const new_decl = try anon_decl.finish(13361 const new_decl = try anon_decl.finish(
13263 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),13362 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
...@@ -13296,7 +13395,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13296,7 +13395,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13296 const target = sema.mod.getTarget();13395 const target = sema.mod.getTarget();
13297 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {13396 const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) {
13298 error.FloatCannotFit => {13397 error.FloatCannotFit => {
13299 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });13398 return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{
13399 std.math.floor(val.toFloat(f64)),
13400 dest_ty.fmt(target),
13401 });
13300 },13402 },
13301 else => |e| return e,13403 else => |e| return e,
13302 };13404 };
...@@ -13344,13 +13446,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13344,13 +13446,14 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13344 try sema.checkPtrType(block, type_src, type_res);13446 try sema.checkPtrType(block, type_src, type_res);
13345 try sema.resolveTypeLayout(block, src, type_res.elemType2());13447 try sema.resolveTypeLayout(block, src, type_res.elemType2());
13346 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());13448 const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
13449 const target = sema.mod.getTarget();
1334713450
13348 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {13451 if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
13349 const addr = val.toUnsignedInt();13452 const addr = val.toUnsignedInt(target);
13350 if (!type_res.isAllowzeroPtr() and addr == 0)13453 if (!type_res.isAllowzeroPtr() and addr == 0)
13351 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res});13454 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res.fmt(target)});
13352 if (addr != 0 and addr % ptr_align != 0)13455 if (addr != 0 and addr % ptr_align != 0)
13353 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res});13456 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res.fmt(target)});
1335413457
13355 const val_payload = try sema.arena.create(Value.Payload.U64);13458 const val_payload = try sema.arena.create(Value.Payload.U64);
13356 val_payload.* = .{13459 val_payload.* = .{
...@@ -13394,6 +13497,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13394,6 +13497,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13394 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);13497 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
13395 const operand = sema.resolveInst(extra.rhs);13498 const operand = sema.resolveInst(extra.rhs);
13396 const operand_ty = sema.typeOf(operand);13499 const operand_ty = sema.typeOf(operand);
13500 const target = sema.mod.getTarget();
13397 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);13501 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
13398 try sema.checkErrorSetType(block, operand_src, operand_ty);13502 try sema.checkErrorSetType(block, operand_src, operand_ty);
1339913503
...@@ -13407,7 +13511,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -13407,7 +13511,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
13407 block,13511 block,
13408 src,13512 src,
13409 "error.{s} not a member of error set '{}'",13513 "error.{s} not a member of error set '{}'",
13410 .{ error_name, dest_ty },13514 .{ error_name, dest_ty.fmt(target) },
13411 );13515 );
13412 }13516 }
13413 }13517 }
...@@ -13502,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13502,7 +13606,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1350213606
13503 if (operand_info.signedness != dest_info.signedness) {13607 if (operand_info.signedness != dest_info.signedness) {
13504 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{13608 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
13505 @tagName(dest_info.signedness), operand_ty,13609 @tagName(dest_info.signedness), operand_ty.fmt(target),
13506 });13610 });
13507 }13611 }
13508 if (operand_info.bits < dest_info.bits) {13612 if (operand_info.bits < dest_info.bits) {
...@@ -13511,7 +13615,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13511,7 +13615,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13511 block,13615 block,
13512 src,13616 src,
13513 "destination type '{}' has more bits than source type '{}'",13617 "destination type '{}' has more bits than source type '{}'",
13514 .{ dest_ty, operand_ty },13618 .{ dest_ty.fmt(target), operand_ty.fmt(target) },
13515 );13619 );
13516 errdefer msg.destroy(sema.gpa);13620 errdefer msg.destroy(sema.gpa);
13517 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{13621 try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{
...@@ -13531,14 +13635,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13531,14 +13635,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13531 if (!is_vector) {13635 if (!is_vector) {
13532 return sema.addConstant(13636 return sema.addConstant(
13533 dest_ty,13637 dest_ty,
13534 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits),13638 try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, target),
13535 );13639 );
13536 }13640 }
13537 var elem_buf: Value.ElemValueBuffer = undefined;13641 var elem_buf: Value.ElemValueBuffer = undefined;
13538 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());13642 const elems = try sema.arena.alloc(Value, operand_ty.vectorLen());
13539 for (elems) |*elem, i| {13643 for (elems) |*elem, i| {
13540 const elem_val = val.elemValueBuffer(i, &elem_buf);13644 const elem_val = val.elemValueBuffer(i, &elem_buf);
13541 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits);13645 elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, target);
13542 }13646 }
13543 return sema.addConstant(13647 return sema.addConstant(
13544 dest_ty,13648 dest_ty,
...@@ -13653,7 +13757,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13653,7 +13757,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13653 block,13757 block,
13654 ty_src,13758 ty_src,
13655 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",13759 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
13656 .{ scalar_ty, bits },13760 .{ scalar_ty.fmt(target), bits },
13657 );13761 );
13658 }13762 }
1365913763
...@@ -13765,6 +13869,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13765,6 +13869,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1376513869
13766 const ty = try sema.resolveType(block, lhs_src, extra.lhs);13870 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
13767 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);13871 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
13872 const target = sema.mod.getTarget();
1376813873
13769 try sema.resolveTypeLayout(block, lhs_src, ty);13874 try sema.resolveTypeLayout(block, lhs_src, ty);
13770 if (ty.tag() != .@"struct") {13875 if (ty.tag() != .@"struct") {
...@@ -13772,7 +13877,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13772,7 +13877,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13772 block,13877 block,
13773 lhs_src,13878 lhs_src,
13774 "expected struct type, found '{}'",13879 "expected struct type, found '{}'",
13775 .{ty},13880 .{ty.fmt(target)},
13776 );13881 );
13777 }13882 }
1377813883
...@@ -13782,11 +13887,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13782,11 +13887,10 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13782 block,13887 block,
13783 rhs_src,13888 rhs_src,
13784 "struct '{}' has no field '{s}'",13889 "struct '{}' has no field '{s}'",
13785 .{ ty, field_name },13890 .{ ty.fmt(target), field_name },
13786 );13891 );
13787 };13892 };
1378813893
13789 const target = sema.mod.getTarget();
13790 switch (ty.containerLayout()) {13894 switch (ty.containerLayout()) {
13791 .Packed => {13895 .Packed => {
13792 var bit_sum: u64 = 0;13896 var bit_sum: u64 = 0;
...@@ -13809,18 +13913,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -13809,18 +13913,20 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
13809}13913}
1381013914
13811fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {13915fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
13916 const target = sema.mod.getTarget();
13812 switch (ty.zigTypeTag()) {13917 switch (ty.zigTypeTag()) {
13813 .Struct, .Enum, .Union, .Opaque => return,13918 .Struct, .Enum, .Union, .Opaque => return,
13814 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty}),13919 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(target)}),
13815 }13920 }
13816}13921}
1381713922
13818/// Returns `true` if the type was a comptime_int.13923/// Returns `true` if the type was a comptime_int.
13819fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {13924fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
13925 const target = sema.mod.getTarget();
13820 switch (try ty.zigTypeTagOrPoison()) {13926 switch (try ty.zigTypeTagOrPoison()) {
13821 .ComptimeInt => return true,13927 .ComptimeInt => return true,
13822 .Int => return false,13928 .Int => return false,
13823 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}),13929 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(target)}),
13824 }13930 }
13825}13931}
1382613932
...@@ -13830,6 +13936,7 @@ fn checkPtrOperand(...@@ -13830,6 +13936,7 @@ fn checkPtrOperand(
13830 ty_src: LazySrcLoc,13936 ty_src: LazySrcLoc,
13831 ty: Type,13937 ty: Type,
13832) CompileError!void {13938) CompileError!void {
13939 const target = sema.mod.getTarget();
13833 switch (ty.zigTypeTag()) {13940 switch (ty.zigTypeTag()) {
13834 .Pointer => return,13941 .Pointer => return,
13835 .Fn => {13942 .Fn => {
...@@ -13838,7 +13945,7 @@ fn checkPtrOperand(...@@ -13838,7 +13945,7 @@ fn checkPtrOperand(
13838 block,13945 block,
13839 ty_src,13946 ty_src,
13840 "expected pointer, found {}",13947 "expected pointer, found {}",
13841 .{ty},13948 .{ty.fmt(target)},
13842 );13949 );
13843 errdefer msg.destroy(sema.gpa);13950 errdefer msg.destroy(sema.gpa);
1384413951
...@@ -13851,7 +13958,7 @@ fn checkPtrOperand(...@@ -13851,7 +13958,7 @@ fn checkPtrOperand(
13851 .Optional => if (ty.isPtrLikeOptional()) return,13958 .Optional => if (ty.isPtrLikeOptional()) return,
13852 else => {},13959 else => {},
13853 }13960 }
13854 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});13961 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
13855}13962}
1385613963
13857fn checkPtrType(13964fn checkPtrType(
...@@ -13860,6 +13967,7 @@ fn checkPtrType(...@@ -13860,6 +13967,7 @@ fn checkPtrType(
13860 ty_src: LazySrcLoc,13967 ty_src: LazySrcLoc,
13861 ty: Type,13968 ty: Type,
13862) CompileError!void {13969) CompileError!void {
13970 const target = sema.mod.getTarget();
13863 switch (ty.zigTypeTag()) {13971 switch (ty.zigTypeTag()) {
13864 .Pointer => return,13972 .Pointer => return,
13865 .Fn => {13973 .Fn => {
...@@ -13868,7 +13976,7 @@ fn checkPtrType(...@@ -13868,7 +13976,7 @@ fn checkPtrType(
13868 block,13976 block,
13869 ty_src,13977 ty_src,
13870 "expected pointer type, found '{}'",13978 "expected pointer type, found '{}'",
13871 .{ty},13979 .{ty.fmt(target)},
13872 );13980 );
13873 errdefer msg.destroy(sema.gpa);13981 errdefer msg.destroy(sema.gpa);
1387413982
...@@ -13881,7 +13989,7 @@ fn checkPtrType(...@@ -13881,7 +13989,7 @@ fn checkPtrType(
13881 .Optional => if (ty.isPtrLikeOptional()) return,13989 .Optional => if (ty.isPtrLikeOptional()) return,
13882 else => {},13990 else => {},
13883 }13991 }
13884 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});13992 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(target)});
13885}13993}
1388613994
13887fn checkVectorElemType(13995fn checkVectorElemType(
...@@ -13894,7 +14002,8 @@ fn checkVectorElemType(...@@ -13894,7 +14002,8 @@ fn checkVectorElemType(
13894 .Int, .Float, .Bool => return,14002 .Int, .Float, .Bool => return,
13895 else => if (ty.isPtrAtRuntime()) return,14003 else => if (ty.isPtrAtRuntime()) return,
13896 }14004 }
13897 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty});14005 const target = sema.mod.getTarget();
14006 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(target)});
13898}14007}
1389914008
13900fn checkFloatType(14009fn checkFloatType(
...@@ -13903,9 +14012,10 @@ fn checkFloatType(...@@ -13903,9 +14012,10 @@ fn checkFloatType(
13903 ty_src: LazySrcLoc,14012 ty_src: LazySrcLoc,
13904 ty: Type,14013 ty: Type,
13905) CompileError!void {14014) CompileError!void {
14015 const target = sema.mod.getTarget();
13906 switch (ty.zigTypeTag()) {14016 switch (ty.zigTypeTag()) {
13907 .ComptimeInt, .ComptimeFloat, .Float => {},14017 .ComptimeInt, .ComptimeFloat, .Float => {},
13908 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty}),14018 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(target)}),
13909 }14019 }
13910}14020}
1391114021
...@@ -13915,13 +14025,14 @@ fn checkNumericType(...@@ -13915,13 +14025,14 @@ fn checkNumericType(
13915 ty_src: LazySrcLoc,14025 ty_src: LazySrcLoc,
13916 ty: Type,14026 ty: Type,
13917) CompileError!void {14027) CompileError!void {
14028 const target = sema.mod.getTarget();
13918 switch (ty.zigTypeTag()) {14029 switch (ty.zigTypeTag()) {
13919 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14030 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
13920 .Vector => switch (ty.childType().zigTypeTag()) {14031 .Vector => switch (ty.childType().zigTypeTag()) {
13921 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},14032 .ComptimeFloat, .Float, .ComptimeInt, .Int => {},
13922 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),14033 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
13923 },14034 },
13924 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty}),14035 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(target)}),
13925 }14036 }
13926}14037}
1392714038
...@@ -13957,7 +14068,7 @@ fn checkAtomicOperandType(...@@ -13957,7 +14068,7 @@ fn checkAtomicOperandType(
13957 block,14068 block,
13958 ty_src,14069 ty_src,
13959 "expected bool, integer, float, enum, or pointer type; found {}",14070 "expected bool, integer, float, enum, or pointer type; found {}",
13960 .{ty},14071 .{ty.fmt(target)},
13961 );14072 );
13962 },14073 },
13963 };14074 };
...@@ -14021,6 +14132,7 @@ fn checkIntOrVector(...@@ -14021,6 +14132,7 @@ fn checkIntOrVector(
14021 operand_src: LazySrcLoc,14132 operand_src: LazySrcLoc,
14022) CompileError!Type {14133) CompileError!Type {
14023 const operand_ty = sema.typeOf(operand);14134 const operand_ty = sema.typeOf(operand);
14135 const target = sema.mod.getTarget();
14024 switch (try operand_ty.zigTypeTagOrPoison()) {14136 switch (try operand_ty.zigTypeTagOrPoison()) {
14025 .Int => return operand_ty,14137 .Int => return operand_ty,
14026 .Vector => {14138 .Vector => {
...@@ -14028,12 +14140,12 @@ fn checkIntOrVector(...@@ -14028,12 +14140,12 @@ fn checkIntOrVector(
14028 switch (try elem_ty.zigTypeTagOrPoison()) {14140 switch (try elem_ty.zigTypeTagOrPoison()) {
14029 .Int => return elem_ty,14141 .Int => return elem_ty,
14030 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14142 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14031 elem_ty,14143 elem_ty.fmt(target),
14032 }),14144 }),
14033 }14145 }
14034 },14146 },
14035 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14147 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14036 operand_ty,14148 operand_ty.fmt(target),
14037 }),14149 }),
14038 }14150 }
14039}14151}
...@@ -14045,6 +14157,7 @@ fn checkIntOrVectorAllowComptime(...@@ -14045,6 +14157,7 @@ fn checkIntOrVectorAllowComptime(
14045 operand_src: LazySrcLoc,14157 operand_src: LazySrcLoc,
14046) CompileError!Type {14158) CompileError!Type {
14047 const operand_ty = sema.typeOf(operand);14159 const operand_ty = sema.typeOf(operand);
14160 const target = sema.mod.getTarget();
14048 switch (try operand_ty.zigTypeTagOrPoison()) {14161 switch (try operand_ty.zigTypeTagOrPoison()) {
14049 .Int, .ComptimeInt => return operand_ty,14162 .Int, .ComptimeInt => return operand_ty,
14050 .Vector => {14163 .Vector => {
...@@ -14052,20 +14165,21 @@ fn checkIntOrVectorAllowComptime(...@@ -14052,20 +14165,21 @@ fn checkIntOrVectorAllowComptime(
14052 switch (try elem_ty.zigTypeTagOrPoison()) {14165 switch (try elem_ty.zigTypeTagOrPoison()) {
14053 .Int, .ComptimeInt => return elem_ty,14166 .Int, .ComptimeInt => return elem_ty,
14054 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{14167 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
14055 elem_ty,14168 elem_ty.fmt(target),
14056 }),14169 }),
14057 }14170 }
14058 },14171 },
14059 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{14172 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
14060 operand_ty,14173 operand_ty.fmt(target),
14061 }),14174 }),
14062 }14175 }
14063}14176}
1406414177
14065fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {14178fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
14179 const target = sema.mod.getTarget();
14066 switch (ty.zigTypeTag()) {14180 switch (ty.zigTypeTag()) {
14067 .ErrorSet => return,14181 .ErrorSet => return,
14068 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),14182 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty.fmt(target)}),
14069 }14183 }
14070}14184}
1407114185
...@@ -14138,9 +14252,10 @@ fn checkVectorizableBinaryOperands(...@@ -14138,9 +14252,10 @@ fn checkVectorizableBinaryOperands(
14138 return sema.failWithOwnedErrorMsg(block, msg);14252 return sema.failWithOwnedErrorMsg(block, msg);
14139 }14253 }
14140 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {14254 } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
14255 const target = sema.mod.getTarget();
14141 const msg = msg: {14256 const msg = msg: {
14142 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{14257 const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{
14143 lhs_ty, rhs_ty,14258 lhs_ty.fmt(target), rhs_ty.fmt(target),
14144 });14259 });
14145 errdefer msg.destroy(sema.gpa);14260 errdefer msg.destroy(sema.gpa);
14146 if (lhs_zig_ty_tag == .Vector) {14261 if (lhs_zig_ty_tag == .Vector) {
...@@ -14179,8 +14294,9 @@ fn resolveExportOptions(...@@ -14179,8 +14294,9 @@ fn resolveExportOptions(
14179 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});14294 return sema.fail(block, src, "TODO: implement exporting with linksection", .{});
14180 }14295 }
14181 const name_ty = Type.initTag(.const_slice_u8);14296 const name_ty = Type.initTag(.const_slice_u8);
14297 const target = sema.mod.getTarget();
14182 return std.builtin.ExportOptions{14298 return std.builtin.ExportOptions{
14183 .name = try name_val.toAllocatedBytes(name_ty, sema.arena),14299 .name = try name_val.toAllocatedBytes(name_ty, sema.arena, target),
14184 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),14300 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
14185 .section = null, // TODO14301 .section = null, // TODO
14186 };14302 };
...@@ -14239,12 +14355,13 @@ fn zirCmpxchg(...@@ -14239,12 +14355,13 @@ fn zirCmpxchg(
14239 const ptr_ty = sema.typeOf(ptr);14355 const ptr_ty = sema.typeOf(ptr);
14240 const elem_ty = ptr_ty.elemType();14356 const elem_ty = ptr_ty.elemType();
14241 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);14357 try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty);
14358 const target = sema.mod.getTarget();
14242 if (elem_ty.zigTypeTag() == .Float) {14359 if (elem_ty.zigTypeTag() == .Float) {
14243 return sema.fail(14360 return sema.fail(
14244 block,14361 block,
14245 elem_ty_src,14362 elem_ty_src,
14246 "expected bool, integer, enum, or pointer type; found '{}'",14363 "expected bool, integer, enum, or pointer type; found '{}'",
14247 .{elem_ty},14364 .{elem_ty.fmt(target)},
14248 );14365 );
14249 }14366 }
14250 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);14367 const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src);
...@@ -14281,7 +14398,7 @@ fn zirCmpxchg(...@@ -14281,7 +14398,7 @@ fn zirCmpxchg(
14281 return sema.addConstUndef(result_ty);14398 return sema.addConstUndef(result_ty);
14282 }14399 }
14283 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;14400 const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src;
14284 const result_val = if (stored_val.eql(expected_val, elem_ty)) blk: {14401 const result_val = if (stored_val.eql(expected_val, elem_ty, target)) blk: {
14285 try sema.storePtr(block, src, ptr, new_value);14402 try sema.storePtr(block, src, ptr, new_value);
14286 break :blk Value.@"null";14403 break :blk Value.@"null";
14287 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);14404 } else try Value.Tag.opt_payload.create(sema.arena, stored_val);
...@@ -14343,9 +14460,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14343,9 +14460,10 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14343 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");14460 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp");
14344 const operand = sema.resolveInst(extra.rhs);14461 const operand = sema.resolveInst(extra.rhs);
14345 const operand_ty = sema.typeOf(operand);14462 const operand_ty = sema.typeOf(operand);
14463 const target = sema.mod.getTarget();
1434614464
14347 if (operand_ty.zigTypeTag() != .Vector) {14465 if (operand_ty.zigTypeTag() != .Vector) {
14348 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty});14466 return sema.fail(block, operand_src, "expected vector, found {}", .{operand_ty.fmt(target)});
14349 }14467 }
1435014468
14351 const scalar_ty = operand_ty.childType();14469 const scalar_ty = operand_ty.childType();
...@@ -14355,13 +14473,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14355,13 +14473,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14355 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {14473 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag()) {
14356 .Int, .Bool => {},14474 .Int, .Bool => {},
14357 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{14475 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found {}", .{
14358 @tagName(operation), operand_ty,14476 @tagName(operation), operand_ty.fmt(target),
14359 }),14477 }),
14360 },14478 },
14361 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {14479 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag()) {
14362 .Int, .Float => {},14480 .Int, .Float => {},
14363 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{14481 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found {}", .{
14364 @tagName(operation), operand_ty,14482 @tagName(operation), operand_ty.fmt(target),
14365 }),14483 }),
14366 },14484 },
14367 }14485 }
...@@ -14376,18 +14494,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14376,18 +14494,17 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14376 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {14494 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
14377 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);14495 if (operand_val.isUndef()) return sema.addConstUndef(scalar_ty);
1437814496
14379 const target = sema.mod.getTarget();
14380 var accum: Value = try operand_val.elemValue(sema.arena, 0);14497 var accum: Value = try operand_val.elemValue(sema.arena, 0);
14381 var elem_buf: Value.ElemValueBuffer = undefined;14498 var elem_buf: Value.ElemValueBuffer = undefined;
14382 var i: u32 = 1;14499 var i: u32 = 1;
14383 while (i < vec_len) : (i += 1) {14500 while (i < vec_len) : (i += 1) {
14384 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);14501 const elem_val = operand_val.elemValueBuffer(i, &elem_buf);
14385 switch (operation) {14502 switch (operation) {
14386 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena),14503 .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena, target),
14387 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena),14504 .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena, target),
14388 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena),14505 .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target),
14389 .Min => accum = accum.numberMin(elem_val),14506 .Min => accum = accum.numberMin(elem_val, target),
14390 .Max => accum = accum.numberMax(elem_val),14507 .Max => accum = accum.numberMax(elem_val, target),
14391 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),14508 .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target),
14392 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),14509 .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target),
14393 }14510 }
...@@ -14417,10 +14534,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -14417,10 +14534,11 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
14417 var b = sema.resolveInst(extra.b);14534 var b = sema.resolveInst(extra.b);
14418 var mask = sema.resolveInst(extra.mask);14535 var mask = sema.resolveInst(extra.mask);
14419 var mask_ty = sema.typeOf(mask);14536 var mask_ty = sema.typeOf(mask);
14537 const target = sema.mod.getTarget();
1442014538
14421 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {14539 const mask_len = switch (sema.typeOf(mask).zigTypeTag()) {
14422 .Array, .Vector => sema.typeOf(mask).arrayLen(),14540 .Array, .Vector => sema.typeOf(mask).arrayLen(),
14423 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask)}),14541 else => return sema.fail(block, mask_src, "expected vector or array, found {}", .{sema.typeOf(mask).fmt(target)}),
14424 };14542 };
14425 mask_ty = try Type.Tag.vector.create(sema.arena, .{14543 mask_ty = try Type.Tag.vector.create(sema.arena, .{
14426 .len = mask_len,14544 .len = mask_len,
...@@ -14452,20 +14570,21 @@ fn analyzeShuffle(...@@ -14452,20 +14570,21 @@ fn analyzeShuffle(
14452 .elem_type = elem_ty,14570 .elem_type = elem_ty,
14453 });14571 });
1445414572
14573 const target = sema.mod.getTarget();
14455 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {14574 var maybe_a_len = switch (sema.typeOf(a).zigTypeTag()) {
14456 .Array, .Vector => sema.typeOf(a).arrayLen(),14575 .Array, .Vector => sema.typeOf(a).arrayLen(),
14457 .Undefined => null,14576 .Undefined => null,
14458 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{14577 else => return sema.fail(block, a_src, "expected vector or array with element type {}, found {}", .{
14459 elem_ty,14578 elem_ty.fmt(target),
14460 sema.typeOf(a),14579 sema.typeOf(a).fmt(target),
14461 }),14580 }),
14462 };14581 };
14463 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {14582 var maybe_b_len = switch (sema.typeOf(b).zigTypeTag()) {
14464 .Array, .Vector => sema.typeOf(b).arrayLen(),14583 .Array, .Vector => sema.typeOf(b).arrayLen(),
14465 .Undefined => null,14584 .Undefined => null,
14466 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{14585 else => return sema.fail(block, b_src, "expected vector or array with element type {}, found {}", .{
14467 elem_ty,14586 elem_ty.fmt(target),
14468 sema.typeOf(b),14587 sema.typeOf(b).fmt(target),
14469 }),14588 }),
14470 };14589 };
14471 if (maybe_a_len == null and maybe_b_len == null) {14590 if (maybe_a_len == null and maybe_b_len == null) {
...@@ -14513,7 +14632,7 @@ fn analyzeShuffle(...@@ -14513,7 +14632,7 @@ fn analyzeShuffle(
1451314632
14514 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{14633 try sema.errNote(block, operand_info[chosen][1], msg, "selected index {d} out of bounds of {}", .{
14515 unsigned,14634 unsigned,
14516 operand_info[chosen][2],14635 operand_info[chosen][2].fmt(target),
14517 });14636 });
1451814637
14519 if (chosen == 1) {14638 if (chosen == 1) {
...@@ -14704,12 +14823,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -14704,12 +14823,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
14704 .Xchg => operand_val,14823 .Xchg => operand_val,
14705 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),14824 .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),
14706 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),14825 .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),
14707 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena),14826 .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena, target),
14708 .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),14827 .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),
14709 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena),14828 .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena, target),
14710 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena),14829 .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena, target),
14711 .Max => stored_val.numberMax (operand_val),14830 .Max => stored_val.numberMax (operand_val, target),
14712 .Min => stored_val.numberMin (operand_val),14831 .Min => stored_val.numberMin (operand_val, target),
14713 // zig fmt: on14832 // zig fmt: on
14714 };14833 };
14715 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);14834 try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty);
...@@ -14788,7 +14907,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14788,7 +14907,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1478814907
14789 switch (ty.zigTypeTag()) {14908 switch (ty.zigTypeTag()) {
14790 .ComptimeFloat, .Float, .Vector => {},14909 .ComptimeFloat, .Float, .Vector => {},
14791 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}),14910 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(target)}),
14792 }14911 }
1479314912
14794 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {14913 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
...@@ -14814,7 +14933,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -14814,7 +14933,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
14814 const scalar_ty = ty.scalarType();14933 const scalar_ty = ty.scalarType();
14815 switch (scalar_ty.zigTypeTag()) {14934 switch (scalar_ty.zigTypeTag()) {
14816 .ComptimeFloat, .Float => {},14935 .ComptimeFloat, .Float => {},
14817 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty}),14936 else => return sema.fail(block, src, "expected vector of floats, found vector of '{}'", .{scalar_ty.fmt(target)}),
14818 }14937 }
1481914938
14820 const vec_len = ty.vectorLen();14939 const vec_len = ty.vectorLen();
...@@ -14906,9 +15025,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -14906,9 +15025,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
14906 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);15025 break :modifier modifier_val.toEnum(std.builtin.CallOptions.Modifier);
14907 };15026 };
1490815027
15028 const target = sema.mod.getTarget();
14909 const args_ty = sema.typeOf(args);15029 const args_ty = sema.typeOf(args);
14910 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {15030 if (!args_ty.isTuple() and args_ty.tag() != .empty_struct_literal) {
14911 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty});15031 return sema.fail(block, args_src, "expected a tuple, found {}", .{args_ty.fmt(target)});
14912 }15032 }
1491315033
14914 var resolved_args: []Air.Inst.Ref = undefined;15034 var resolved_args: []Air.Inst.Ref = undefined;
...@@ -14945,9 +15065,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14945,9 +15065,10 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14945 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);15065 const field_name = try sema.resolveConstString(block, name_src, extra.field_name);
14946 const field_ptr = sema.resolveInst(extra.field_ptr);15066 const field_ptr = sema.resolveInst(extra.field_ptr);
14947 const field_ptr_ty = sema.typeOf(field_ptr);15067 const field_ptr_ty = sema.typeOf(field_ptr);
15068 const target = sema.mod.getTarget();
1494815069
14949 if (struct_ty.zigTypeTag() != .Struct) {15070 if (struct_ty.zigTypeTag() != .Struct) {
14950 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty});15071 return sema.fail(block, ty_src, "expected struct type, found '{}'", .{struct_ty.fmt(target)});
14951 }15072 }
14952 try sema.resolveTypeLayout(block, ty_src, struct_ty);15073 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1495315074
...@@ -14956,7 +15077,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14956,7 +15077,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14956 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);15077 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
1495715078
14958 if (field_ptr_ty.zigTypeTag() != .Pointer) {15079 if (field_ptr_ty.zigTypeTag() != .Pointer) {
14959 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty});15080 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(target)});
14960 }15081 }
14961 const field = struct_obj.fields.values()[field_index];15082 const field = struct_obj.fields.values()[field_index];
14962 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;15083 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
...@@ -14973,7 +15094,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -14973,7 +15094,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
14973 ptr_ty_data.@"align" = field.abi_align;15094 ptr_ty_data.@"align" = field.abi_align;
14974 }15095 }
1497515096
14976 const target = sema.mod.getTarget();
14977 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);15097 const actual_field_ptr_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
14978 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);15098 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, ptr_src);
1497915099
...@@ -15042,8 +15162,9 @@ fn analyzeMinMax(...@@ -15042,8 +15162,9 @@ fn analyzeMinMax(
15042 .max => Value.numberMax,15162 .max => Value.numberMax,
15043 else => unreachable,15163 else => unreachable,
15044 };15164 };
15165 const target = sema.mod.getTarget();
15045 const vec_len = simd_op.len orelse {15166 const vec_len = simd_op.len orelse {
15046 const result_val = opFunc(lhs_val, rhs_val);15167 const result_val = opFunc(lhs_val, rhs_val, target);
15047 return sema.addConstant(simd_op.result_ty, result_val);15168 return sema.addConstant(simd_op.result_ty, result_val);
15048 };15169 };
15049 var lhs_buf: Value.ElemValueBuffer = undefined;15170 var lhs_buf: Value.ElemValueBuffer = undefined;
...@@ -15052,7 +15173,7 @@ fn analyzeMinMax(...@@ -15052,7 +15173,7 @@ fn analyzeMinMax(
15052 for (elems) |*elem, i| {15173 for (elems) |*elem, i| {
15053 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);15174 const lhs_elem_val = lhs_val.elemValueBuffer(i, &lhs_buf);
15054 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);15175 const rhs_elem_val = rhs_val.elemValueBuffer(i, &rhs_buf);
15055 elem.* = opFunc(lhs_elem_val, rhs_elem_val);15176 elem.* = opFunc(lhs_elem_val, rhs_elem_val, target);
15056 }15177 }
15057 return sema.addConstant(15178 return sema.addConstant(
15058 simd_op.result_ty,15179 simd_op.result_ty,
...@@ -15078,17 +15199,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15078,17 +15199,17 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15078 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15199 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15079 const dest_ptr = sema.resolveInst(extra.dest);15200 const dest_ptr = sema.resolveInst(extra.dest);
15080 const dest_ptr_ty = sema.typeOf(dest_ptr);15201 const dest_ptr_ty = sema.typeOf(dest_ptr);
15202 const target = sema.mod.getTarget();
1508115203
15082 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15204 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15083 if (dest_ptr_ty.isConstPtr()) {15205 if (dest_ptr_ty.isConstPtr()) {
15084 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});15206 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
15085 }15207 }
1508615208
15087 const uncasted_src_ptr = sema.resolveInst(extra.source);15209 const uncasted_src_ptr = sema.resolveInst(extra.source);
15088 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);15210 const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr);
15089 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);15211 try sema.checkPtrOperand(block, src_src, uncasted_src_ptr_ty);
15090 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;15212 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
15091 const target = sema.mod.getTarget();
15092 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{15213 const wanted_src_ptr_ty = try Type.ptr(sema.arena, target, .{
15093 .pointee_type = dest_ptr_ty.elemType2(),15214 .pointee_type = dest_ptr_ty.elemType2(),
15094 .@"align" = src_ptr_info.@"align",15215 .@"align" = src_ptr_info.@"align",
...@@ -15136,9 +15257,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -15136,9 +15257,10 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
15136 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };15257 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
15137 const dest_ptr = sema.resolveInst(extra.dest);15258 const dest_ptr = sema.resolveInst(extra.dest);
15138 const dest_ptr_ty = sema.typeOf(dest_ptr);15259 const dest_ptr_ty = sema.typeOf(dest_ptr);
15260 const target = sema.mod.getTarget();
15139 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);15261 try sema.checkPtrOperand(block, dest_src, dest_ptr_ty);
15140 if (dest_ptr_ty.isConstPtr()) {15262 if (dest_ptr_ty.isConstPtr()) {
15141 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty});15263 return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty.fmt(target)});
15142 }15264 }
15143 const elem_ty = dest_ptr_ty.elemType2();15265 const elem_ty = dest_ptr_ty.elemType2();
15144 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);15266 const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src);
...@@ -15452,6 +15574,7 @@ fn zirPrefetch(...@@ -15452,6 +15574,7 @@ fn zirPrefetch(
15452 const ptr = sema.resolveInst(extra.lhs);15574 const ptr = sema.resolveInst(extra.lhs);
15453 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));15575 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
15454 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);15576 const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);
15577 const target = sema.mod.getTarget();
1545515578
15456 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);15579 const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
15457 const rw_val = try sema.resolveConstValue(block, opts_src, rw);15580 const rw_val = try sema.resolveConstValue(block, opts_src, rw);
...@@ -15459,7 +15582,7 @@ fn zirPrefetch(...@@ -15459,7 +15582,7 @@ fn zirPrefetch(
1545915582
15460 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);15583 const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
15461 const locality_val = try sema.resolveConstValue(block, opts_src, locality);15584 const locality_val = try sema.resolveConstValue(block, opts_src, locality);
15462 const locality_int = @intCast(u2, locality_val.toUnsignedInt());15585 const locality_int = @intCast(u2, locality_val.toUnsignedInt(target));
1546315586
15464 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);15587 const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
15465 const cache_val = try sema.resolveConstValue(block, opts_src, cache);15588 const cache_val = try sema.resolveConstValue(block, opts_src, cache);
...@@ -15492,6 +15615,7 @@ fn zirBuiltinExtern(...@@ -15492,6 +15615,7 @@ fn zirBuiltinExtern(
1549215615
15493 var ty = try sema.resolveType(block, ty_src, extra.lhs);15616 var ty = try sema.resolveType(block, ty_src, extra.lhs);
15494 const options_inst = sema.resolveInst(extra.rhs);15617 const options_inst = sema.resolveInst(extra.rhs);
15618 const target = sema.mod.getTarget();
1549515619
15496 const options = options: {15620 const options = options: {
15497 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");15621 const extern_options_ty = try sema.getBuiltinType(block, options_src, "ExternOptions");
...@@ -15512,11 +15636,11 @@ fn zirBuiltinExtern(...@@ -15512,11 +15636,11 @@ fn zirBuiltinExtern(
15512 var library_name: ?[]const u8 = null;15636 var library_name: ?[]const u8 = null;
15513 if (!library_name_val.isNull()) {15637 if (!library_name_val.isNull()) {
15514 const payload = library_name_val.castTag(.opt_payload).?.data;15638 const payload = library_name_val.castTag(.opt_payload).?.data;
15515 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena);15639 library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target);
15516 }15640 }
1551715641
15518 break :options std.builtin.ExternOptions{15642 break :options std.builtin.ExternOptions{
15519 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),15643 .name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, target),
15520 .library_name = library_name,15644 .library_name = library_name,
15521 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),15645 .linkage = linkage_val.toEnum(std.builtin.GlobalLinkage),
15522 .is_thread_local = is_thread_local_val.toBool(),15646 .is_thread_local = is_thread_local_val.toBool(),
...@@ -15609,8 +15733,9 @@ fn validateVarType(...@@ -15609,8 +15733,9 @@ fn validateVarType(
15609) CompileError!void {15733) CompileError!void {
15610 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;15734 if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
1561115735
15736 const target = sema.mod.getTarget();
15612 const msg = msg: {15737 const msg = msg: {
15613 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty});15738 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(target)});
15614 errdefer msg.destroy(sema.gpa);15739 errdefer msg.destroy(sema.gpa);
1561515740
15616 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);15741 try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty);
...@@ -15685,6 +15810,7 @@ fn explainWhyTypeIsComptime(...@@ -15685,6 +15810,7 @@ fn explainWhyTypeIsComptime(
15685 ty: Type,15810 ty: Type,
15686) CompileError!void {15811) CompileError!void {
15687 const mod = sema.mod;15812 const mod = sema.mod;
15813 const target = mod.getTarget();
15688 switch (ty.zigTypeTag()) {15814 switch (ty.zigTypeTag()) {
15689 .Bool,15815 .Bool,
15690 .Int,15816 .Int,
...@@ -15698,7 +15824,7 @@ fn explainWhyTypeIsComptime(...@@ -15698,7 +15824,7 @@ fn explainWhyTypeIsComptime(
1569815824
15699 .Fn => {15825 .Fn => {
15700 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{15826 try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
15701 ty,15827 ty.fmt(target),
15702 });15828 });
15703 },15829 },
1570415830
...@@ -15941,6 +16067,8 @@ fn fieldVal(...@@ -15941,6 +16067,8 @@ fn fieldVal(
15941 else16067 else
15942 object_ty;16068 object_ty;
1594316069
16070 const target = sema.mod.getTarget();
16071
15944 switch (inner_ty.zigTypeTag()) {16072 switch (inner_ty.zigTypeTag()) {
15945 .Array => {16073 .Array => {
15946 if (mem.eql(u8, field_name, "len")) {16074 if (mem.eql(u8, field_name, "len")) {
...@@ -15953,7 +16081,7 @@ fn fieldVal(...@@ -15953,7 +16081,7 @@ fn fieldVal(
15953 block,16081 block,
15954 field_name_src,16082 field_name_src,
15955 "no member named '{s}' in '{}'",16083 "no member named '{s}' in '{}'",
15956 .{ field_name, object_ty },16084 .{ field_name, object_ty.fmt(target) },
15957 );16085 );
15958 }16086 }
15959 },16087 },
...@@ -15977,7 +16105,7 @@ fn fieldVal(...@@ -15977,7 +16105,7 @@ fn fieldVal(
15977 block,16105 block,
15978 field_name_src,16106 field_name_src,
15979 "no member named '{s}' in '{}'",16107 "no member named '{s}' in '{}'",
15980 .{ field_name, object_ty },16108 .{ field_name, object_ty.fmt(target) },
15981 );16109 );
15982 }16110 }
15983 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {16111 } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
...@@ -15991,7 +16119,7 @@ fn fieldVal(...@@ -15991,7 +16119,7 @@ fn fieldVal(
15991 block,16119 block,
15992 field_name_src,16120 field_name_src,
15993 "no member named '{s}' in '{}'",16121 "no member named '{s}' in '{}'",
15994 .{ field_name, ptr_info.pointee_type },16122 .{ field_name, ptr_info.pointee_type.fmt(target) },
15995 );16123 );
15996 }16124 }
15997 }16125 }
...@@ -16013,7 +16141,7 @@ fn fieldVal(...@@ -16013,7 +16141,7 @@ fn fieldVal(
16013 break :blk entry.key_ptr.*;16141 break :blk entry.key_ptr.*;
16014 }16142 }
16015 return sema.fail(block, src, "no error named '{s}' in '{}'", .{16143 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16016 field_name, child_type,16144 field_name, child_type.fmt(target),
16017 });16145 });
16018 } else (try sema.mod.getErrorValue(field_name)).key;16146 } else (try sema.mod.getErrorValue(field_name)).key;
1601916147
...@@ -16067,10 +16195,10 @@ fn fieldVal(...@@ -16067,10 +16195,10 @@ fn fieldVal(
16067 else => unreachable,16195 else => unreachable,
16068 };16196 };
16069 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{16197 return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{
16070 kw_name, child_type, field_name,16198 kw_name, child_type.fmt(target), field_name,
16071 });16199 });
16072 },16200 },
16073 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),16201 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
16074 }16202 }
16075 },16203 },
16076 .Struct => if (is_pointer_to) {16204 .Struct => if (is_pointer_to) {
...@@ -16089,7 +16217,7 @@ fn fieldVal(...@@ -16089,7 +16217,7 @@ fn fieldVal(
16089 },16217 },
16090 else => {},16218 else => {},
16091 }16219 }
16092 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty});16220 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(target)});
16093}16221}
1609416222
16095fn fieldPtr(16223fn fieldPtr(
...@@ -16103,11 +16231,12 @@ fn fieldPtr(...@@ -16103,11 +16231,12 @@ fn fieldPtr(
16103 // When editing this function, note that there is corresponding logic to be edited16231 // When editing this function, note that there is corresponding logic to be edited
16104 // in `fieldVal`. This function takes a pointer and returns a pointer.16232 // in `fieldVal`. This function takes a pointer and returns a pointer.
1610516233
16234 const target = sema.mod.getTarget();
16106 const object_ptr_src = src; // TODO better source location16235 const object_ptr_src = src; // TODO better source location
16107 const object_ptr_ty = sema.typeOf(object_ptr);16236 const object_ptr_ty = sema.typeOf(object_ptr);
16108 const object_ty = switch (object_ptr_ty.zigTypeTag()) {16237 const object_ty = switch (object_ptr_ty.zigTypeTag()) {
16109 .Pointer => object_ptr_ty.elemType(),16238 .Pointer => object_ptr_ty.elemType(),
16110 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}),16239 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(target)}),
16111 };16240 };
1611216241
16113 // Zig allows dereferencing a single pointer during field lookup. Note that16242 // Zig allows dereferencing a single pointer during field lookup. Note that
...@@ -16120,8 +16249,6 @@ fn fieldPtr(...@@ -16120,8 +16249,6 @@ fn fieldPtr(
16120 else16249 else
16121 object_ty;16250 object_ty;
1612216251
16123 const target = sema.mod.getTarget();
16124
16125 switch (inner_ty.zigTypeTag()) {16252 switch (inner_ty.zigTypeTag()) {
16126 .Array => {16253 .Array => {
16127 if (mem.eql(u8, field_name, "len")) {16254 if (mem.eql(u8, field_name, "len")) {
...@@ -16137,7 +16264,7 @@ fn fieldPtr(...@@ -16137,7 +16264,7 @@ fn fieldPtr(
16137 block,16264 block,
16138 field_name_src,16265 field_name_src,
16139 "no member named '{s}' in '{}'",16266 "no member named '{s}' in '{}'",
16140 .{ field_name, object_ty },16267 .{ field_name, object_ty.fmt(target) },
16141 );16268 );
16142 }16269 }
16143 },16270 },
...@@ -16177,7 +16304,7 @@ fn fieldPtr(...@@ -16177,7 +16304,7 @@ fn fieldPtr(
1617716304
16178 return sema.analyzeDeclRef(try anon_decl.finish(16305 return sema.analyzeDeclRef(try anon_decl.finish(
16179 Type.usize,16306 Type.usize,
16180 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),16307 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(target)),
16181 0, // default alignment16308 0, // default alignment
16182 ));16309 ));
16183 }16310 }
...@@ -16195,7 +16322,7 @@ fn fieldPtr(...@@ -16195,7 +16322,7 @@ fn fieldPtr(
16195 block,16322 block,
16196 field_name_src,16323 field_name_src,
16197 "no member named '{s}' in '{}'",16324 "no member named '{s}' in '{}'",
16198 .{ field_name, object_ty },16325 .{ field_name, object_ty.fmt(target) },
16199 );16326 );
16200 }16327 }
16201 },16328 },
...@@ -16219,7 +16346,7 @@ fn fieldPtr(...@@ -16219,7 +16346,7 @@ fn fieldPtr(
16219 break :blk entry.key_ptr.*;16346 break :blk entry.key_ptr.*;
16220 }16347 }
16221 return sema.fail(block, src, "no error named '{s}' in '{}'", .{16348 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
16222 field_name, child_type,16349 field_name, child_type.fmt(target),
16223 });16350 });
16224 } else (try sema.mod.getErrorValue(field_name)).key;16351 } else (try sema.mod.getErrorValue(field_name)).key;
1622516352
...@@ -16277,7 +16404,7 @@ fn fieldPtr(...@@ -16277,7 +16404,7 @@ fn fieldPtr(
16277 }16404 }
16278 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);16405 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
16279 },16406 },
16280 else => return sema.fail(block, src, "type '{}' has no members", .{child_type}),16407 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(target)}),
16281 }16408 }
16282 },16409 },
16283 .Struct => {16410 .Struct => {
...@@ -16296,7 +16423,7 @@ fn fieldPtr(...@@ -16296,7 +16423,7 @@ fn fieldPtr(
16296 },16423 },
16297 else => {},16424 else => {},
16298 }16425 }
16299 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty, object_ptr_ty, field_name });16426 return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(target), object_ptr_ty.fmt(target), field_name });
16300}16427}
1630116428
16302fn fieldCallBind(16429fn fieldCallBind(
...@@ -16310,12 +16437,13 @@ fn fieldCallBind(...@@ -16310,12 +16437,13 @@ fn fieldCallBind(
16310 // When editing this function, note that there is corresponding logic to be edited16437 // When editing this function, note that there is corresponding logic to be edited
16311 // in `fieldVal`. This function takes a pointer and returns a pointer.16438 // in `fieldVal`. This function takes a pointer and returns a pointer.
1631216439
16440 const target = sema.mod.getTarget();
16313 const raw_ptr_src = src; // TODO better source location16441 const raw_ptr_src = src; // TODO better source location
16314 const raw_ptr_ty = sema.typeOf(raw_ptr);16442 const raw_ptr_ty = sema.typeOf(raw_ptr);
16315 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)16443 const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One)
16316 raw_ptr_ty.childType()16444 raw_ptr_ty.childType()
16317 else16445 else
16318 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty});16446 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(target)});
1631916447
16320 // Optionally dereference a second pointer to get the concrete type.16448 // Optionally dereference a second pointer to get the concrete type.
16321 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;16449 const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One;
...@@ -16375,7 +16503,7 @@ fn fieldCallBind(...@@ -16375,7 +16503,7 @@ fn fieldCallBind(
16375 first_param_type.zigTypeTag() == .Pointer and16503 first_param_type.zigTypeTag() == .Pointer and
16376 (first_param_type.ptrSize() == .One or16504 (first_param_type.ptrSize() == .One or
16377 first_param_type.ptrSize() == .C) and16505 first_param_type.ptrSize() == .C) and
16378 first_param_type.childType().eql(concrete_ty)))16506 first_param_type.childType().eql(concrete_ty, target)))
16379 {16507 {
16380 // zig fmt: on16508 // zig fmt: on
16381 // TODO: bound fn calls on rvalues should probably16509 // TODO: bound fn calls on rvalues should probably
...@@ -16386,7 +16514,7 @@ fn fieldCallBind(...@@ -16386,7 +16514,7 @@ fn fieldCallBind(
16386 .arg0_inst = object_ptr,16514 .arg0_inst = object_ptr,
16387 });16515 });
16388 return sema.addConstant(ty, value);16516 return sema.addConstant(ty, value);
16389 } else if (first_param_type.eql(concrete_ty)) {16517 } else if (first_param_type.eql(concrete_ty, target)) {
16390 var deref = try sema.analyzeLoad(block, src, object_ptr, src);16518 var deref = try sema.analyzeLoad(block, src, object_ptr, src);
16391 const ty = Type.Tag.bound_fn.init();16519 const ty = Type.Tag.bound_fn.init();
16392 const value = try Value.Tag.bound_fn.create(arena, .{16520 const value = try Value.Tag.bound_fn.create(arena, .{
...@@ -16402,7 +16530,7 @@ fn fieldCallBind(...@@ -16402,7 +16530,7 @@ fn fieldCallBind(
16402 else => {},16530 else => {},
16403 }16531 }
1640416532
16405 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name });16533 return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty.fmt(target), field_name });
16406}16534}
1640716535
16408fn finishFieldCallBind(16536fn finishFieldCallBind(
...@@ -16540,10 +16668,11 @@ fn structFieldPtrByIndex(...@@ -16540,10 +16668,11 @@ fn structFieldPtrByIndex(
16540 .@"addrspace" = struct_ptr_ty_info.@"addrspace",16668 .@"addrspace" = struct_ptr_ty_info.@"addrspace",
16541 };16669 };
1654216670
16671 const target = sema.mod.getTarget();
16672
16543 // TODO handle when the struct pointer is overaligned, we should return a potentially16673 // TODO handle when the struct pointer is overaligned, we should return a potentially
16544 // over-aligned field pointer too.16674 // over-aligned field pointer too.
16545 if (struct_obj.layout == .Packed) {16675 if (struct_obj.layout == .Packed) {
16546 const target = sema.mod.getTarget();
16547 comptime assert(Type.packed_struct_layout_version == 2);16676 comptime assert(Type.packed_struct_layout_version == 2);
1654816677
16549 var running_bits: u16 = 0;16678 var running_bits: u16 = 0;
...@@ -16567,7 +16696,6 @@ fn structFieldPtrByIndex(...@@ -16567,7 +16696,6 @@ fn structFieldPtrByIndex(
16567 ptr_ty_data.@"align" = field.abi_align;16696 ptr_ty_data.@"align" = field.abi_align;
16568 }16697 }
1656916698
16570 const target = sema.mod.getTarget();
16571 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);16699 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1657216700
16573 if (field.is_comptime) {16701 if (field.is_comptime) {
...@@ -16667,14 +16795,15 @@ fn tupleFieldIndex(...@@ -16667,14 +16795,15 @@ fn tupleFieldIndex(
16667 field_name: []const u8,16795 field_name: []const u8,
16668 field_name_src: LazySrcLoc,16796 field_name_src: LazySrcLoc,
16669) CompileError!u32 {16797) CompileError!u32 {
16798 const target = sema.mod.getTarget();
16670 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {16799 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch |err| {
16671 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{16800 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}': {s}", .{
16672 tuple_ty, field_name, @errorName(err),16801 tuple_ty.fmt(target), field_name, @errorName(err),
16673 });16802 });
16674 };16803 };
16675 if (field_index >= tuple_ty.structFieldCount()) {16804 if (field_index >= tuple_ty.structFieldCount()) {
16676 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{16805 return sema.fail(block, field_name_src, "tuple {} has no such field '{s}'", .{
16677 tuple_ty, field_name,16806 tuple_ty.fmt(target), field_name,
16678 });16807 });
16679 }16808 }
16680 return field_index;16809 return field_index;
...@@ -16749,7 +16878,7 @@ fn unionFieldPtr(...@@ -16749,7 +16878,7 @@ fn unionFieldPtr(
16749 // .data = field_index,16878 // .data = field_index,
16750 //};16879 //};
16751 //const field_tag = Value.initPayload(&field_tag_buf.base);16880 //const field_tag = Value.initPayload(&field_tag_buf.base);
16752 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);16881 //const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
16753 //if (!tag_matches) {16882 //if (!tag_matches) {
16754 // // TODO enhance this saying which one was active16883 // // TODO enhance this saying which one was active
16755 // // and which one was accessed, and showing where the union was declared.16884 // // and which one was accessed, and showing where the union was declared.
...@@ -16798,7 +16927,8 @@ fn unionFieldVal(...@@ -16798,7 +16927,8 @@ fn unionFieldVal(
16798 .data = field_index,16927 .data = field_index,
16799 };16928 };
16800 const field_tag = Value.initPayload(&field_tag_buf.base);16929 const field_tag = Value.initPayload(&field_tag_buf.base);
16801 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);16930 const target = sema.mod.getTarget();
16931 const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, target);
16802 switch (union_obj.layout) {16932 switch (union_obj.layout) {
16803 .Auto => {16933 .Auto => {
16804 if (tag_matches) {16934 if (tag_matches) {
...@@ -16813,7 +16943,7 @@ fn unionFieldVal(...@@ -16813,7 +16943,7 @@ fn unionFieldVal(
16813 if (tag_matches) {16943 if (tag_matches) {
16814 return sema.addConstant(field.ty, tag_and_val.val);16944 return sema.addConstant(field.ty, tag_and_val.val);
16815 } else {16945 } else {
16816 const old_ty = union_ty.unionFieldType(tag_and_val.tag);16946 const old_ty = union_ty.unionFieldType(tag_and_val.tag, target);
16817 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);16947 const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0);
16818 return sema.addConstant(field.ty, new_val);16948 return sema.addConstant(field.ty, new_val);
16819 }16949 }
...@@ -16835,19 +16965,19 @@ fn elemPtr(...@@ -16835,19 +16965,19 @@ fn elemPtr(
16835) CompileError!Air.Inst.Ref {16965) CompileError!Air.Inst.Ref {
16836 const indexable_ptr_src = src; // TODO better source location16966 const indexable_ptr_src = src; // TODO better source location
16837 const indexable_ptr_ty = sema.typeOf(indexable_ptr);16967 const indexable_ptr_ty = sema.typeOf(indexable_ptr);
16968 const target = sema.mod.getTarget();
16838 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {16969 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag()) {
16839 .Pointer => indexable_ptr_ty.elemType(),16970 .Pointer => indexable_ptr_ty.elemType(),
16840 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty}),16971 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(target)}),
16841 };16972 };
16842 if (!indexable_ty.isIndexable()) {16973 if (!indexable_ty.isIndexable()) {
16843 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});16974 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
16844 }16975 }
1684516976
16846 switch (indexable_ty.zigTypeTag()) {16977 switch (indexable_ty.zigTypeTag()) {
16847 .Pointer => {16978 .Pointer => {
16848 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.16979 // In all below cases, we have to deref the ptr operand to get the actual indexable pointer.
16849 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);16980 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
16850 const target = sema.mod.getTarget();
16851 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);16981 const result_ty = try indexable_ty.elemPtrType(sema.arena, target);
16852 switch (indexable_ty.ptrSize()) {16982 switch (indexable_ty.ptrSize()) {
16853 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),16983 .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index),
...@@ -16858,8 +16988,8 @@ fn elemPtr(...@@ -16858,8 +16988,8 @@ fn elemPtr(
16858 const runtime_src = rs: {16988 const runtime_src = rs: {
16859 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;16989 const ptr_val = maybe_ptr_val orelse break :rs indexable_ptr_src;
16860 const index_val = maybe_index_val orelse break :rs elem_index_src;16990 const index_val = maybe_index_val orelse break :rs elem_index_src;
16861 const index = @intCast(usize, index_val.toUnsignedInt());16991 const index = @intCast(usize, index_val.toUnsignedInt(target));
16862 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index);16992 const elem_ptr = try ptr_val.elemPtr(indexable_ty, sema.arena, index, target);
16863 return sema.addConstant(result_ty, elem_ptr);16993 return sema.addConstant(result_ty, elem_ptr);
16864 };16994 };
1686516995
...@@ -16876,7 +17006,7 @@ fn elemPtr(...@@ -16876,7 +17006,7 @@ fn elemPtr(
16876 .Struct => {17006 .Struct => {
16877 // Tuple field access.17007 // Tuple field access.
16878 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);17008 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16879 const index = @intCast(u32, index_val.toUnsignedInt());17009 const index = @intCast(u32, index_val.toUnsignedInt(target));
16880 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);17010 return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index);
16881 },17011 },
16882 else => unreachable,17012 else => unreachable,
...@@ -16893,9 +17023,10 @@ fn elemVal(...@@ -16893,9 +17023,10 @@ fn elemVal(
16893) CompileError!Air.Inst.Ref {17023) CompileError!Air.Inst.Ref {
16894 const indexable_src = src; // TODO better source location17024 const indexable_src = src; // TODO better source location
16895 const indexable_ty = sema.typeOf(indexable);17025 const indexable_ty = sema.typeOf(indexable);
17026 const target = sema.mod.getTarget();
1689617027
16897 if (!indexable_ty.isIndexable()) {17028 if (!indexable_ty.isIndexable()) {
16898 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty});17029 return sema.fail(block, src, "element access of non-indexable type '{}'", .{indexable_ty.fmt(target)});
16899 }17030 }
1690017031
16901 // TODO in case of a vector of pointers, we need to detect whether the element17032 // TODO in case of a vector of pointers, we need to detect whether the element
...@@ -16912,7 +17043,7 @@ fn elemVal(...@@ -16912,7 +17043,7 @@ fn elemVal(
16912 const runtime_src = rs: {17043 const runtime_src = rs: {
16913 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;17044 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
16914 const index_val = maybe_index_val orelse break :rs elem_index_src;17045 const index_val = maybe_index_val orelse break :rs elem_index_src;
16915 const index = @intCast(usize, index_val.toUnsignedInt());17046 const index = @intCast(usize, index_val.toUnsignedInt(target));
16916 const elem_ty = indexable_ty.elemType2();17047 const elem_ty = indexable_ty.elemType2();
1691717048
16918 var payload: Value.Payload.ElemPtr = .{ .data = .{17049 var payload: Value.Payload.ElemPtr = .{ .data = .{
...@@ -16945,7 +17076,7 @@ fn elemVal(...@@ -16945,7 +17076,7 @@ fn elemVal(
16945 .Struct => {17076 .Struct => {
16946 // Tuple field access.17077 // Tuple field access.
16947 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);17078 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
16948 const index = @intCast(u32, index_val.toUnsignedInt());17079 const index = @intCast(u32, index_val.toUnsignedInt(target));
16949 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);17080 return tupleField(sema, block, indexable_src, indexable, elem_index_src, index);
16950 },17081 },
16951 else => unreachable,17082 else => unreachable,
...@@ -17056,9 +17187,10 @@ fn elemValArray(...@@ -17056,9 +17187,10 @@ fn elemValArray(
17056 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);17187 const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);
17057 // index must be defined since it can access out of bounds17188 // index must be defined since it can access out of bounds
17058 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17189 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17190 const target = sema.mod.getTarget();
1705917191
17060 if (maybe_index_val) |index_val| {17192 if (maybe_index_val) |index_val| {
17061 const index = @intCast(usize, index_val.toUnsignedInt());17193 const index = @intCast(usize, index_val.toUnsignedInt(target));
17062 if (index >= array_len_s) {17194 if (index >= array_len_s) {
17063 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";17195 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
17064 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });17196 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -17069,7 +17201,7 @@ fn elemValArray(...@@ -17069,7 +17201,7 @@ fn elemValArray(
17069 return sema.addConstUndef(elem_ty);17201 return sema.addConstUndef(elem_ty);
17070 }17202 }
17071 if (maybe_index_val) |index_val| {17203 if (maybe_index_val) |index_val| {
17072 const index = @intCast(usize, index_val.toUnsignedInt());17204 const index = @intCast(usize, index_val.toUnsignedInt(target));
17073 const elem_val = try array_val.elemValue(sema.arena, index);17205 const elem_val = try array_val.elemValue(sema.arena, index);
17074 return sema.addConstant(elem_ty, elem_val);17206 return sema.addConstant(elem_ty, elem_val);
17075 }17207 }
...@@ -17114,7 +17246,7 @@ fn elemPtrArray(...@@ -17114,7 +17246,7 @@ fn elemPtrArray(
17114 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17246 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
1711517247
17116 if (maybe_index_val) |index_val| {17248 if (maybe_index_val) |index_val| {
17117 const index = @intCast(usize, index_val.toUnsignedInt());17249 const index = @intCast(usize, index_val.toUnsignedInt(target));
17118 if (index >= array_len_s) {17250 if (index >= array_len_s) {
17119 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";17251 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
17120 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });17252 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -17125,8 +17257,8 @@ fn elemPtrArray(...@@ -17125,8 +17257,8 @@ fn elemPtrArray(
17125 return sema.addConstUndef(elem_ptr_ty);17257 return sema.addConstUndef(elem_ptr_ty);
17126 }17258 }
17127 if (maybe_index_val) |index_val| {17259 if (maybe_index_val) |index_val| {
17128 const index = @intCast(usize, index_val.toUnsignedInt());17260 const index = @intCast(usize, index_val.toUnsignedInt(target));
17129 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index);17261 const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, index, target);
17130 return sema.addConstant(elem_ptr_ty, elem_ptr);17262 return sema.addConstant(elem_ptr_ty, elem_ptr);
17131 }17263 }
17132 }17264 }
...@@ -17162,16 +17294,17 @@ fn elemValSlice(...@@ -17162,16 +17294,17 @@ fn elemValSlice(
17162 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);17294 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
17163 // index must be defined since it can index out of bounds17295 // index must be defined since it can index out of bounds
17164 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);17296 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
17297 const target = sema.mod.getTarget();
1716517298
17166 if (maybe_slice_val) |slice_val| {17299 if (maybe_slice_val) |slice_val| {
17167 runtime_src = elem_index_src;17300 runtime_src = elem_index_src;
17168 const slice_len = slice_val.sliceLen();17301 const slice_len = slice_val.sliceLen(target);
17169 const slice_len_s = slice_len + @boolToInt(slice_sent);17302 const slice_len_s = slice_len + @boolToInt(slice_sent);
17170 if (slice_len_s == 0) {17303 if (slice_len_s == 0) {
17171 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});17304 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
17172 }17305 }
17173 if (maybe_index_val) |index_val| {17306 if (maybe_index_val) |index_val| {
17174 const index = @intCast(usize, index_val.toUnsignedInt());17307 const index = @intCast(usize, index_val.toUnsignedInt(target));
17175 if (index >= slice_len_s) {17308 if (index >= slice_len_s) {
17176 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";17309 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
17177 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });17310 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
...@@ -17192,7 +17325,7 @@ fn elemValSlice(...@@ -17192,7 +17325,7 @@ fn elemValSlice(
17192 try sema.requireRuntimeBlock(block, runtime_src);17325 try sema.requireRuntimeBlock(block, runtime_src);
17193 if (block.wantSafety()) {17326 if (block.wantSafety()) {
17194 const len_inst = if (maybe_slice_val) |slice_val|17327 const len_inst = if (maybe_slice_val) |slice_val|
17195 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen())17328 try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target))
17196 else17329 else
17197 try block.addTyOp(.slice_len, Type.usize, slice);17330 try block.addTyOp(.slice_len, Type.usize, slice);
17198 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;17331 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -17223,18 +17356,18 @@ fn elemPtrSlice(...@@ -17223,18 +17356,18 @@ fn elemPtrSlice(
17223 if (slice_val.isUndef()) {17356 if (slice_val.isUndef()) {
17224 return sema.addConstUndef(elem_ptr_ty);17357 return sema.addConstUndef(elem_ptr_ty);
17225 }17358 }
17226 const slice_len = slice_val.sliceLen();17359 const slice_len = slice_val.sliceLen(target);
17227 const slice_len_s = slice_len + @boolToInt(slice_sent);17360 const slice_len_s = slice_len + @boolToInt(slice_sent);
17228 if (slice_len_s == 0) {17361 if (slice_len_s == 0) {
17229 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});17362 return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
17230 }17363 }
17231 if (maybe_index_val) |index_val| {17364 if (maybe_index_val) |index_val| {
17232 const index = @intCast(usize, index_val.toUnsignedInt());17365 const index = @intCast(usize, index_val.toUnsignedInt(target));
17233 if (index >= slice_len_s) {17366 if (index >= slice_len_s) {
17234 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";17367 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
17235 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });17368 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
17236 }17369 }
17237 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index);17370 const elem_ptr_val = try slice_val.elemPtr(slice_ty, sema.arena, index, target);
17238 return sema.addConstant(elem_ptr_ty, elem_ptr_val);17371 return sema.addConstant(elem_ptr_ty, elem_ptr_val);
17239 }17372 }
17240 }17373 }
...@@ -17245,7 +17378,7 @@ fn elemPtrSlice(...@@ -17245,7 +17378,7 @@ fn elemPtrSlice(
17245 const len_inst = len: {17378 const len_inst = len: {
17246 if (maybe_undef_slice_val) |slice_val|17379 if (maybe_undef_slice_val) |slice_val|
17247 if (!slice_val.isUndef())17380 if (!slice_val.isUndef())
17248 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen());17381 break :len try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
17249 break :len try block.addTyOp(.slice_len, Type.usize, slice);17382 break :len try block.addTyOp(.slice_len, Type.usize, slice);
17250 };17383 };
17251 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;17384 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -17270,12 +17403,12 @@ fn coerce(...@@ -17270,12 +17403,12 @@ fn coerce(
17270 const dest_ty_src = inst_src; // TODO better source location17403 const dest_ty_src = inst_src; // TODO better source location
17271 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);17404 const dest_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty_unresolved);
17272 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));17405 const inst_ty = try sema.resolveTypeFields(block, inst_src, sema.typeOf(inst));
17406 const target = sema.mod.getTarget();
17273 // If the types are the same, we can return the operand.17407 // If the types are the same, we can return the operand.
17274 if (dest_ty.eql(inst_ty))17408 if (dest_ty.eql(inst_ty, target))
17275 return inst;17409 return inst;
1727617410
17277 const arena = sema.arena;17411 const arena = sema.arena;
17278 const target = sema.mod.getTarget();
17279 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);17412 const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst);
1728017413
17281 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);17414 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);
...@@ -17379,7 +17512,7 @@ fn coerce(...@@ -17379,7 +17512,7 @@ fn coerce(
17379 // *[N:s]T to [*]T17512 // *[N:s]T to [*]T
17380 if (dest_info.sentinel) |dst_sentinel| {17513 if (dest_info.sentinel) |dst_sentinel| {
17381 if (array_ty.sentinel()) |src_sentinel| {17514 if (array_ty.sentinel()) |src_sentinel| {
17382 if (src_sentinel.eql(dst_sentinel, dst_elem_type)) {17515 if (src_sentinel.eql(dst_sentinel, dst_elem_type, target)) {
17383 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);17516 return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
17384 }17517 }
17385 }17518 }
...@@ -17448,7 +17581,7 @@ fn coerce(...@@ -17448,7 +17581,7 @@ fn coerce(
17448 }17581 }
17449 if (inst_info.size == .Slice) {17582 if (inst_info.size == .Slice) {
17450 if (dest_info.sentinel == null or inst_info.sentinel == null or17583 if (dest_info.sentinel == null or inst_info.sentinel == null or
17451 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))17584 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
17452 break :p;17585 break :p;
1745317586
17454 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);17587 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -17515,7 +17648,7 @@ fn coerce(...@@ -17515,7 +17648,7 @@ fn coerce(
17515 }17648 }
1751617649
17517 if (dest_info.sentinel == null or inst_info.sentinel == null or17650 if (dest_info.sentinel == null or inst_info.sentinel == null or
17518 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type))17651 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, target))
17519 break :p;17652 break :p;
1752017653
17521 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);17654 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -17528,11 +17661,11 @@ fn coerce(...@@ -17528,11 +17661,11 @@ fn coerce(
17528 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;17661 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :float;
1752917662
17530 if (val.floatHasFraction()) {17663 if (val.floatHasFraction()) {
17531 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty });17664 return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty, target), dest_ty.fmt(target) });
17532 }17665 }
17533 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {17666 const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) {
17534 error.FloatCannotFit => {17667 error.FloatCannotFit => {
17535 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty });17668 return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty.fmt(target) });
17536 },17669 },
17537 else => |e| return e,17670 else => |e| return e,
17538 };17671 };
...@@ -17542,7 +17675,7 @@ fn coerce(...@@ -17542,7 +17675,7 @@ fn coerce(
17542 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {17675 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
17543 // comptime known integer to other number17676 // comptime known integer to other number
17544 if (!val.intFitsInType(dest_ty, target)) {17677 if (!val.intFitsInType(dest_ty, target)) {
17545 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty, val.fmtValue(inst_ty) });17678 return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) });
17546 }17679 }
17547 return try sema.addConstant(dest_ty, val);17680 return try sema.addConstant(dest_ty, val);
17548 }17681 }
...@@ -17572,12 +17705,12 @@ fn coerce(...@@ -17572,12 +17705,12 @@ fn coerce(
17572 .Float => {17705 .Float => {
17573 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {17706 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {
17574 const result_val = try val.floatCast(sema.arena, dest_ty, target);17707 const result_val = try val.floatCast(sema.arena, dest_ty, target);
17575 if (!val.eql(result_val, dest_ty)) {17708 if (!val.eql(result_val, dest_ty, target)) {
17576 return sema.fail(17709 return sema.fail(
17577 block,17710 block,
17578 inst_src,17711 inst_src,
17579 "type {} cannot represent float value {}",17712 "type {} cannot represent float value {}",
17580 .{ dest_ty, val.fmtValue(inst_ty) },17713 .{ dest_ty.fmt(target), val.fmtValue(inst_ty, target) },
17581 );17714 );
17582 }17715 }
17583 return try sema.addConstant(dest_ty, result_val);17716 return try sema.addConstant(dest_ty, result_val);
...@@ -17596,12 +17729,12 @@ fn coerce(...@@ -17596,12 +17729,12 @@ fn coerce(
17596 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);17729 const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target);
17597 // TODO implement this compile error17730 // TODO implement this compile error
17598 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);17731 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
17599 //if (!int_again_val.eql(val, inst_ty)) {17732 //if (!int_again_val.eql(val, inst_ty, target)) {
17600 // return sema.fail(17733 // return sema.fail(
17601 // block,17734 // block,
17602 // inst_src,17735 // inst_src,
17603 // "type {} cannot represent integer value {}",17736 // "type {} cannot represent integer value {}",
17604 // .{ dest_ty, val },17737 // .{ dest_ty.fmt(target), val },
17605 // );17738 // );
17606 //}17739 //}
17607 return try sema.addConstant(dest_ty, result_val);17740 return try sema.addConstant(dest_ty, result_val);
...@@ -17622,7 +17755,7 @@ fn coerce(...@@ -17622,7 +17755,7 @@ fn coerce(
17622 block,17755 block,
17623 inst_src,17756 inst_src,
17624 "enum '{}' has no field named '{s}'",17757 "enum '{}' has no field named '{s}'",
17625 .{ dest_ty, bytes },17758 .{ dest_ty.fmt(target), bytes },
17626 );17759 );
17627 errdefer msg.destroy(sema.gpa);17760 errdefer msg.destroy(sema.gpa);
17628 try sema.mod.errNoteNonLazy(17761 try sema.mod.errNoteNonLazy(
...@@ -17643,7 +17776,7 @@ fn coerce(...@@ -17643,7 +17776,7 @@ fn coerce(
17643 .Union => blk: {17776 .Union => blk: {
17644 // union to its own tag type17777 // union to its own tag type
17645 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;17778 const union_tag_ty = inst_ty.unionTagType() orelse break :blk;
17646 if (union_tag_ty.eql(dest_ty)) {17779 if (union_tag_ty.eql(dest_ty, target)) {
17647 return sema.unionToTag(block, dest_ty, inst, inst_src);17780 return sema.unionToTag(block, dest_ty, inst, inst_src);
17648 }17781 }
17649 },17782 },
...@@ -17743,7 +17876,7 @@ fn coerce(...@@ -17743,7 +17876,7 @@ fn coerce(
17743 return sema.addConstUndef(dest_ty);17876 return sema.addConstUndef(dest_ty);
17744 }17877 }
1774517878
17746 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty });17879 return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty.fmt(target), inst_ty.fmt(target) });
17747}17880}
1774817881
17749const InMemoryCoercionResult = enum {17882const InMemoryCoercionResult = enum {
...@@ -17772,7 +17905,7 @@ fn coerceInMemoryAllowed(...@@ -17772,7 +17905,7 @@ fn coerceInMemoryAllowed(
17772 dest_src: LazySrcLoc,17905 dest_src: LazySrcLoc,
17773 src_src: LazySrcLoc,17906 src_src: LazySrcLoc,
17774) CompileError!InMemoryCoercionResult {17907) CompileError!InMemoryCoercionResult {
17775 if (dest_ty.eql(src_ty))17908 if (dest_ty.eql(src_ty, target))
17776 return .ok;17909 return .ok;
1777717910
17778 // Pointers / Pointer-like Optionals17911 // Pointers / Pointer-like Optionals
...@@ -17823,7 +17956,7 @@ fn coerceInMemoryAllowed(...@@ -17823,7 +17956,7 @@ fn coerceInMemoryAllowed(
17823 }17956 }
17824 const ok_sent = dest_info.sentinel == null or17957 const ok_sent = dest_info.sentinel == null or
17825 (src_info.sentinel != null and17958 (src_info.sentinel != null and
17826 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type));17959 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.elem_type, target));
17827 if (!ok_sent) {17960 if (!ok_sent) {
17828 return .no_match;17961 return .no_match;
17829 }17962 }
...@@ -18050,7 +18183,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18050,7 +18183,7 @@ fn coerceInMemoryAllowedPtrs(
1805018183
18051 const ok_sent = dest_info.sentinel == null or src_info.size == .C or18184 const ok_sent = dest_info.sentinel == null or src_info.size == .C or
18052 (src_info.sentinel != null and18185 (src_info.sentinel != null and
18053 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type));18186 dest_info.sentinel.?.eql(src_info.sentinel.?, dest_info.pointee_type, target));
18054 if (!ok_sent) {18187 if (!ok_sent) {
18055 return .no_match;18188 return .no_match;
18056 }18189 }
...@@ -18091,7 +18224,7 @@ fn coerceInMemoryAllowedPtrs(...@@ -18091,7 +18224,7 @@ fn coerceInMemoryAllowedPtrs(
18091 // resolved and we compare the alignment numerically.18224 // resolved and we compare the alignment numerically.
18092 alignment: {18225 alignment: {
18093 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and18226 if (src_info.@"align" == 0 and dest_info.@"align" == 0 and
18094 dest_info.pointee_type.eql(src_info.pointee_type))18227 dest_info.pointee_type.eql(src_info.pointee_type, target))
18095 {18228 {
18096 break :alignment;18229 break :alignment;
18097 }18230 }
...@@ -18246,7 +18379,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -18246,7 +18379,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
18246 // We have a pointer-to-array and a pointer-to-vector. If the elements and18379 // We have a pointer-to-array and a pointer-to-vector. If the elements and
18247 // lengths match, return the result.18380 // lengths match, return the result.
18248 const vector_ty = sema.typeOf(prev_ptr).childType();18381 const vector_ty = sema.typeOf(prev_ptr).childType();
18249 if (array_ty.childType().eql(vector_ty.childType()) and18382 const target = sema.mod.getTarget();
18383 if (array_ty.childType().eql(vector_ty.childType(), target) and
18250 array_ty.arrayLen() == vector_ty.vectorLen())18384 array_ty.arrayLen() == vector_ty.vectorLen())
18251 {18385 {
18252 return prev_ptr;18386 return prev_ptr;
...@@ -18265,15 +18399,15 @@ fn storePtrVal(...@@ -18265,15 +18399,15 @@ fn storePtrVal(
18265 operand_val: Value,18399 operand_val: Value,
18266 operand_ty: Type,18400 operand_ty: Type,
18267) !void {18401) !void {
18268 var kit = try beginComptimePtrMutation(sema, block, src, ptr_val);18402 var mut_kit = try beginComptimePtrMutation(sema, block, src, ptr_val);
18269 try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut);18403 try sema.checkComptimeVarStore(block, src, mut_kit.decl_ref_mut);
1827018404
18271 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty, 0);18405 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
1827218406
18273 const arena = kit.beginArena(sema.gpa);18407 const arena = mut_kit.beginArena(sema.gpa);
18274 defer kit.finishArena();18408 defer mut_kit.finishArena();
1827518409
18276 kit.val.* = try bitcasted_val.copy(arena);18410 mut_kit.val.* = try bitcasted_val.copy(arena);
18277}18411}
1827818412
18279const ComptimePtrMutationKit = struct {18413const ComptimePtrMutationKit = struct {
...@@ -18668,10 +18802,10 @@ fn beginComptimePtrLoad(...@@ -18668,10 +18802,10 @@ fn beginComptimePtrLoad(
18668 if (maybe_array_ty) |load_ty| {18802 if (maybe_array_ty) |load_ty| {
18669 // It's possible that we're loading a [N]T, in which case we'd like to slice18803 // It's possible that we're loading a [N]T, in which case we'd like to slice
18670 // the pointee array directly from our parent array.18804 // the pointee array directly from our parent array.
18671 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty)) {18805 if (load_ty.isArrayLike() and load_ty.childType().eql(elem_ty, target)) {
18672 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());18806 const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel());
18673 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{18807 deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{
18674 .ty = try Type.array(sema.arena, N, null, elem_ty),18808 .ty = try Type.array(sema.arena, N, null, elem_ty, target),
18675 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),18809 .val = try array_tv.val.sliceArray(sema.arena, elem_ptr.index, elem_ptr.index + N),
18676 } else null;18810 } else null;
18677 break :blk deref;18811 break :blk deref;
...@@ -18807,11 +18941,11 @@ pub fn bitCastVal(...@@ -18807,11 +18941,11 @@ pub fn bitCastVal(
18807 new_ty: Type,18941 new_ty: Type,
18808 buffer_offset: usize,18942 buffer_offset: usize,
18809) !Value {18943) !Value {
18810 if (old_ty.eql(new_ty)) return val;18944 const target = sema.mod.getTarget();
18945 if (old_ty.eql(new_ty, target)) return val;
1881118946
18812 // For types with well-defined memory layouts, we serialize them a byte buffer,18947 // For types with well-defined memory layouts, we serialize them a byte buffer,
18813 // then deserialize to the new type.18948 // then deserialize to the new type.
18814 const target = sema.mod.getTarget();
18815 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));18949 const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
18816 const buffer = try sema.gpa.alloc(u8, abi_size);18950 const buffer = try sema.gpa.alloc(u8, abi_size);
18817 defer sema.gpa.free(buffer);18951 defer sema.gpa.free(buffer);
...@@ -18864,11 +18998,12 @@ fn coerceEnumToUnion(...@@ -18864,11 +18998,12 @@ fn coerceEnumToUnion(
18864 inst_src: LazySrcLoc,18998 inst_src: LazySrcLoc,
18865) !Air.Inst.Ref {18999) !Air.Inst.Ref {
18866 const inst_ty = sema.typeOf(inst);19000 const inst_ty = sema.typeOf(inst);
19001 const target = sema.mod.getTarget();
1886719002
18868 const tag_ty = union_ty.unionTagType() orelse {19003 const tag_ty = union_ty.unionTagType() orelse {
18869 const msg = msg: {19004 const msg = msg: {
18870 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19005 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
18871 union_ty, inst_ty,19006 union_ty.fmt(target), inst_ty.fmt(target),
18872 });19007 });
18873 errdefer msg.destroy(sema.gpa);19008 errdefer msg.destroy(sema.gpa);
18874 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});19009 try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
...@@ -18881,10 +19016,10 @@ fn coerceEnumToUnion(...@@ -18881,10 +19016,10 @@ fn coerceEnumToUnion(
18881 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);19016 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
18882 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {19017 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
18883 const union_obj = union_ty.cast(Type.Payload.Union).?.data;19018 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
18884 const field_index = union_obj.tag_ty.enumTagFieldIndex(val) orelse {19019 const field_index = union_obj.tag_ty.enumTagFieldIndex(val, target) orelse {
18885 const msg = msg: {19020 const msg = msg: {
18886 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{19021 const msg = try sema.errMsg(block, inst_src, "union {} has no tag with value {}", .{
18887 union_ty, val.fmtValue(tag_ty),19022 union_ty.fmt(target), val.fmtValue(tag_ty, target),
18888 });19023 });
18889 errdefer msg.destroy(sema.gpa);19024 errdefer msg.destroy(sema.gpa);
18890 try sema.addDeclaredHereNote(msg, union_ty);19025 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -18899,7 +19034,7 @@ fn coerceEnumToUnion(...@@ -18899,7 +19034,7 @@ fn coerceEnumToUnion(
18899 // also instead of 'union declared here' make it 'field "foo" declared here'.19034 // also instead of 'union declared here' make it 'field "foo" declared here'.
18900 const msg = msg: {19035 const msg = msg: {
18901 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{19036 const msg = try sema.errMsg(block, inst_src, "coercion to union {} must initialize {} field", .{
18902 union_ty, field_ty,19037 union_ty.fmt(target), field_ty.fmt(target),
18903 });19038 });
18904 errdefer msg.destroy(sema.gpa);19039 errdefer msg.destroy(sema.gpa);
18905 try sema.addDeclaredHereNote(msg, union_ty);19040 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -18919,7 +19054,7 @@ fn coerceEnumToUnion(...@@ -18919,7 +19054,7 @@ fn coerceEnumToUnion(
18919 if (tag_ty.isNonexhaustiveEnum()) {19054 if (tag_ty.isNonexhaustiveEnum()) {
18920 const msg = msg: {19055 const msg = msg: {
18921 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{19056 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} from non-exhaustive enum", .{
18922 union_ty,19057 union_ty.fmt(target),
18923 });19058 });
18924 errdefer msg.destroy(sema.gpa);19059 errdefer msg.destroy(sema.gpa);
18925 try sema.addDeclaredHereNote(msg, tag_ty);19060 try sema.addDeclaredHereNote(msg, tag_ty);
...@@ -18937,7 +19072,7 @@ fn coerceEnumToUnion(...@@ -18937,7 +19072,7 @@ fn coerceEnumToUnion(
18937 // instead of the "union declared here" hint19072 // instead of the "union declared here" hint
18938 const msg = msg: {19073 const msg = msg: {
18939 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{19074 const msg = try sema.errMsg(block, inst_src, "runtime coercion to union {} which has non-void fields", .{
18940 union_ty,19075 union_ty.fmt(target),
18941 });19076 });
18942 errdefer msg.destroy(sema.gpa);19077 errdefer msg.destroy(sema.gpa);
18943 try sema.addDeclaredHereNote(msg, union_ty);19078 try sema.addDeclaredHereNote(msg, union_ty);
...@@ -19020,11 +19155,12 @@ fn coerceArrayLike(...@@ -19020,11 +19155,12 @@ fn coerceArrayLike(
19020 const inst_ty = sema.typeOf(inst);19155 const inst_ty = sema.typeOf(inst);
19021 const inst_len = inst_ty.arrayLen();19156 const inst_len = inst_ty.arrayLen();
19022 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());19157 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19158 const target = sema.mod.getTarget();
1902319159
19024 if (dest_len != inst_len) {19160 if (dest_len != inst_len) {
19025 const msg = msg: {19161 const msg = msg: {
19026 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19162 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19027 dest_ty, inst_ty,19163 dest_ty.fmt(target), inst_ty.fmt(target),
19028 });19164 });
19029 errdefer msg.destroy(sema.gpa);19165 errdefer msg.destroy(sema.gpa);
19030 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19166 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -19034,7 +19170,6 @@ fn coerceArrayLike(...@@ -19034,7 +19170,6 @@ fn coerceArrayLike(
19034 return sema.failWithOwnedErrorMsg(block, msg);19170 return sema.failWithOwnedErrorMsg(block, msg);
19035 }19171 }
1903619172
19037 const target = sema.mod.getTarget();
19038 const dest_elem_ty = dest_ty.childType();19173 const dest_elem_ty = dest_ty.childType();
19039 const inst_elem_ty = inst_ty.childType();19174 const inst_elem_ty = inst_ty.childType();
19040 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);19175 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src);
...@@ -19092,11 +19227,12 @@ fn coerceTupleToArray(...@@ -19092,11 +19227,12 @@ fn coerceTupleToArray(
19092 const inst_ty = sema.typeOf(inst);19227 const inst_ty = sema.typeOf(inst);
19093 const inst_len = inst_ty.arrayLen();19228 const inst_len = inst_ty.arrayLen();
19094 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());19229 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen());
19230 const target = sema.mod.getTarget();
1909519231
19096 if (dest_len != inst_len) {19232 if (dest_len != inst_len) {
19097 const msg = msg: {19233 const msg = msg: {
19098 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{19234 const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{
19099 dest_ty, inst_ty,19235 dest_ty.fmt(target), inst_ty.fmt(target),
19100 });19236 });
19101 errdefer msg.destroy(sema.gpa);19237 errdefer msg.destroy(sema.gpa);
19102 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});19238 try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
...@@ -19149,7 +19285,8 @@ fn coerceTupleToSlicePtrs(...@@ -19149,7 +19285,8 @@ fn coerceTupleToSlicePtrs(
19149 const tuple_ty = sema.typeOf(ptr_tuple).childType();19285 const tuple_ty = sema.typeOf(ptr_tuple).childType();
19150 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);19286 const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
19151 const slice_info = slice_ty.ptrInfo().data;19287 const slice_info = slice_ty.ptrInfo().data;
19152 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type);19288 const target = sema.mod.getTarget();
19289 const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, target);
19153 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);19290 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
19154 if (slice_info.@"align" != 0) {19291 if (slice_info.@"align" != 0) {
19155 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});19292 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
...@@ -19398,10 +19535,11 @@ fn analyzeLoad(...@@ -19398,10 +19535,11 @@ fn analyzeLoad(
19398 ptr: Air.Inst.Ref,19535 ptr: Air.Inst.Ref,
19399 ptr_src: LazySrcLoc,19536 ptr_src: LazySrcLoc,
19400) CompileError!Air.Inst.Ref {19537) CompileError!Air.Inst.Ref {
19538 const target = sema.mod.getTarget();
19401 const ptr_ty = sema.typeOf(ptr);19539 const ptr_ty = sema.typeOf(ptr);
19402 const elem_ty = switch (ptr_ty.zigTypeTag()) {19540 const elem_ty = switch (ptr_ty.zigTypeTag()) {
19403 .Pointer => ptr_ty.childType(),19541 .Pointer => ptr_ty.childType(),
19404 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),19542 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(target)}),
19405 };19543 };
19406 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {19544 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
19407 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {19545 if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| {
...@@ -19440,7 +19578,8 @@ fn analyzeSliceLen(...@@ -19440,7 +19578,8 @@ fn analyzeSliceLen(
19440 if (slice_val.isUndef()) {19578 if (slice_val.isUndef()) {
19441 return sema.addConstUndef(Type.usize);19579 return sema.addConstUndef(Type.usize);
19442 }19580 }
19443 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen());19581 const target = sema.mod.getTarget();
19582 return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(target));
19444 }19583 }
19445 try sema.requireRuntimeBlock(block, src);19584 try sema.requireRuntimeBlock(block, src);
19446 return block.addTyOp(.slice_len, Type.usize, slice_inst);19585 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -19522,9 +19661,10 @@ fn analyzeSlice(...@@ -19522,9 +19661,10 @@ fn analyzeSlice(
19522 // Slice expressions can operate on a variable whose type is an array. This requires19661 // Slice expressions can operate on a variable whose type is an array. This requires
19523 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.19662 // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer.
19524 const ptr_ptr_ty = sema.typeOf(ptr_ptr);19663 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
19664 const target = sema.mod.getTarget();
19525 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {19665 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag()) {
19526 .Pointer => ptr_ptr_ty.elemType(),19666 .Pointer => ptr_ptr_ty.elemType(),
19527 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty}),19667 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(target)}),
19528 };19668 };
1952919669
19530 var array_ty = ptr_ptr_child_ty;19670 var array_ty = ptr_ptr_child_ty;
...@@ -19564,7 +19704,7 @@ fn analyzeSlice(...@@ -19564,7 +19704,7 @@ fn analyzeSlice(
19564 elem_ty = ptr_ptr_child_ty.childType();19704 elem_ty = ptr_ptr_child_ty.childType();
19565 },19705 },
19566 },19706 },
19567 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty}),19707 else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(target)}),
19568 }19708 }
1956919709
19570 const ptr = if (slice_ty.isSlice())19710 const ptr = if (slice_ty.isSlice())
...@@ -19587,15 +19727,18 @@ fn analyzeSlice(...@@ -19587,15 +19727,18 @@ fn analyzeSlice(
19587 if (!end_is_len) {19727 if (!end_is_len) {
19588 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);19728 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
19589 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {19729 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {
19590 if (end_val.compare(.gt, len_val, Type.usize)) {19730 if (end_val.compare(.gt, len_val, Type.usize, target)) {
19591 return sema.fail(19731 return sema.fail(
19592 block,19732 block,
19593 end_src,19733 end_src,
19594 "end index {} out of bounds for array of length {}",19734 "end index {} out of bounds for array of length {}",
19595 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },19735 .{
19736 end_val.fmtValue(Type.usize, target),
19737 len_val.fmtValue(Type.usize, target),
19738 },
19596 );19739 );
19597 }19740 }
19598 if (end_val.eql(len_val, Type.usize)) {19741 if (end_val.eql(len_val, Type.usize, target)) {
19599 end_is_len = true;19742 end_is_len = true;
19600 }19743 }
19601 }19744 }
...@@ -19610,18 +19753,21 @@ fn analyzeSlice(...@@ -19610,18 +19753,21 @@ fn analyzeSlice(
19610 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {19753 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
19611 var int_payload: Value.Payload.U64 = .{19754 var int_payload: Value.Payload.U64 = .{
19612 .base = .{ .tag = .int_u64 },19755 .base = .{ .tag = .int_u64 },
19613 .data = slice_val.sliceLen(),19756 .data = slice_val.sliceLen(target),
19614 };19757 };
19615 const slice_len_val = Value.initPayload(&int_payload.base);19758 const slice_len_val = Value.initPayload(&int_payload.base);
19616 if (end_val.compare(.gt, slice_len_val, Type.usize)) {19759 if (end_val.compare(.gt, slice_len_val, Type.usize, target)) {
19617 return sema.fail(19760 return sema.fail(
19618 block,19761 block,
19619 end_src,19762 end_src,
19620 "end index {} out of bounds for slice of length {}",19763 "end index {} out of bounds for slice of length {}",
19621 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },19764 .{
19765 end_val.fmtValue(Type.usize, target),
19766 slice_len_val.fmtValue(Type.usize, target),
19767 },
19622 );19768 );
19623 }19769 }
19624 if (end_val.eql(slice_len_val, Type.usize)) {19770 if (end_val.eql(slice_len_val, Type.usize, target)) {
19625 end_is_len = true;19771 end_is_len = true;
19626 }19772 }
19627 }19773 }
...@@ -19654,12 +19800,15 @@ fn analyzeSlice(...@@ -19654,12 +19800,15 @@ fn analyzeSlice(
19654 // requirement: start <= end19800 // requirement: start <= end
19655 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {19801 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {
19656 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {19802 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {
19657 if (start_val.compare(.gt, end_val, Type.usize)) {19803 if (start_val.compare(.gt, end_val, Type.usize, target)) {
19658 return sema.fail(19804 return sema.fail(
19659 block,19805 block,
19660 start_src,19806 start_src,
19661 "start index {} is larger than end index {}",19807 "start index {} is larger than end index {}",
19662 .{ start_val.fmtValue(Type.usize), end_val.fmtValue(Type.usize) },19808 .{
19809 start_val.fmtValue(Type.usize, target),
19810 end_val.fmtValue(Type.usize, target),
19811 },
19663 );19812 );
19664 }19813 }
19665 }19814 }
...@@ -19670,13 +19819,12 @@ fn analyzeSlice(...@@ -19670,13 +19819,12 @@ fn analyzeSlice(
1967019819
19671 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;19820 const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data;
19672 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;19821 const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C;
19673 const target = sema.mod.getTarget();
1967419822
19675 if (opt_new_len_val) |new_len_val| {19823 if (opt_new_len_val) |new_len_val| {
19676 const new_len_int = new_len_val.toUnsignedInt();19824 const new_len_int = new_len_val.toUnsignedInt(target);
1967719825
19678 const return_ty = try Type.ptr(sema.arena, target, .{19826 const return_ty = try Type.ptr(sema.arena, target, .{
19679 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty),19827 .pointee_type = try Type.array(sema.arena, new_len_int, sentinel, elem_ty, target),
19680 .sentinel = null,19828 .sentinel = null,
19681 .@"align" = new_ptr_ty_info.@"align",19829 .@"align" = new_ptr_ty_info.@"align",
19682 .@"addrspace" = new_ptr_ty_info.@"addrspace",19830 .@"addrspace" = new_ptr_ty_info.@"addrspace",
...@@ -19746,6 +19894,7 @@ fn cmpNumeric(...@@ -19746,6 +19894,7 @@ fn cmpNumeric(
1974619894
19747 const lhs_ty_tag = lhs_ty.zigTypeTag();19895 const lhs_ty_tag = lhs_ty.zigTypeTag();
19748 const rhs_ty_tag = rhs_ty.zigTypeTag();19896 const rhs_ty_tag = rhs_ty.zigTypeTag();
19897 const target = sema.mod.getTarget();
1974919898
19750 const runtime_src: LazySrcLoc = src: {19899 const runtime_src: LazySrcLoc = src: {
19751 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {19900 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -19760,7 +19909,7 @@ fn cmpNumeric(...@@ -19760,7 +19909,7 @@ fn cmpNumeric(
19760 return Air.Inst.Ref.bool_false;19909 return Air.Inst.Ref.bool_false;
19761 }19910 }
19762 }19911 }
19763 if (Value.compareHetero(lhs_val, op, rhs_val)) {19912 if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, target, sema.kit(block, src))) {
19764 return Air.Inst.Ref.bool_true;19913 return Air.Inst.Ref.bool_true;
19765 } else {19914 } else {
19766 return Air.Inst.Ref.bool_false;19915 return Air.Inst.Ref.bool_false;
...@@ -19789,7 +19938,6 @@ fn cmpNumeric(...@@ -19789,7 +19938,6 @@ fn cmpNumeric(
19789 .Float, .ComptimeFloat => true,19938 .Float, .ComptimeFloat => true,
19790 else => false,19939 else => false,
19791 };19940 };
19792 const target = sema.mod.getTarget();
19793 if (lhs_is_float and rhs_is_float) {19941 if (lhs_is_float and rhs_is_float) {
19794 // Implicit cast the smaller one to the larger one.19942 // Implicit cast the smaller one to the larger one.
19795 const dest_ty = x: {19943 const dest_ty = x: {
...@@ -19846,7 +19994,7 @@ fn cmpNumeric(...@@ -19846,7 +19994,7 @@ fn cmpNumeric(
19846 }19994 }
19847 if (lhs_is_float) {19995 if (lhs_is_float) {
19848 var bigint_space: Value.BigIntSpace = undefined;19996 var bigint_space: Value.BigIntSpace = undefined;
19849 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);19997 var bigint = try lhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
19850 defer bigint.deinit();19998 defer bigint.deinit();
19851 if (lhs_val.floatHasFraction()) {19999 if (lhs_val.floatHasFraction()) {
19852 switch (op) {20000 switch (op) {
...@@ -19892,7 +20040,7 @@ fn cmpNumeric(...@@ -19892,7 +20040,7 @@ fn cmpNumeric(
19892 }20040 }
19893 if (rhs_is_float) {20041 if (rhs_is_float) {
19894 var bigint_space: Value.BigIntSpace = undefined;20042 var bigint_space: Value.BigIntSpace = undefined;
19895 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);20043 var bigint = try rhs_val.toBigInt(&bigint_space, target).toManaged(sema.gpa);
19896 defer bigint.deinit();20044 defer bigint.deinit();
19897 if (rhs_val.floatHasFraction()) {20045 if (rhs_val.floatHasFraction()) {
19898 switch (op) {20046 switch (op) {
...@@ -19950,6 +20098,7 @@ fn cmpVector(...@@ -19950,6 +20098,7 @@ fn cmpVector(
19950 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);20098 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1995120099
19952 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");20100 const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool");
20101 const target = sema.mod.getTarget();
1995320102
19954 const runtime_src: LazySrcLoc = src: {20103 const runtime_src: LazySrcLoc = src: {
19955 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {20104 if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| {
...@@ -19957,7 +20106,7 @@ fn cmpVector(...@@ -19957,7 +20106,7 @@ fn cmpVector(
19957 if (lhs_val.isUndef() or rhs_val.isUndef()) {20106 if (lhs_val.isUndef() or rhs_val.isUndef()) {
19958 return sema.addConstUndef(result_ty);20107 return sema.addConstUndef(result_ty);
19959 }20108 }
19960 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena);20109 const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, target);
19961 return sema.addConstant(result_ty, cmp_val);20110 return sema.addConstant(result_ty, cmp_val);
19962 } else {20111 } else {
19963 break :src rhs_src;20112 break :src rhs_src;
...@@ -20108,7 +20257,7 @@ fn resolvePeerTypes(...@@ -20108,7 +20257,7 @@ fn resolvePeerTypes(
20108 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();20257 const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison();
20109 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();20258 const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison();
2011020259
20111 if (candidate_ty.eql(chosen_ty))20260 if (candidate_ty.eql(chosen_ty, target))
20112 continue;20261 continue;
2011320262
20114 switch (candidate_ty_tag) {20263 switch (candidate_ty_tag) {
...@@ -20522,14 +20671,17 @@ fn resolvePeerTypes(...@@ -20522,14 +20671,17 @@ fn resolvePeerTypes(
20522 );20671 );
2052320672
20524 const msg = msg: {20673 const msg = msg: {
20525 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty });20674 const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{
20675 chosen_ty.fmt(target),
20676 candidate_ty.fmt(target),
20677 });
20526 errdefer msg.destroy(sema.gpa);20678 errdefer msg.destroy(sema.gpa);
2052720679
20528 if (chosen_src) |src_loc|20680 if (chosen_src) |src_loc|
20529 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty});20681 try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty.fmt(target)});
2053020682
20531 if (candidate_src) |src_loc|20683 if (candidate_src) |src_loc|
20532 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty});20684 try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty.fmt(target)});
2053320685
20534 break :msg msg;20686 break :msg msg;
20535 };20687 };
...@@ -20557,7 +20709,7 @@ fn resolvePeerTypes(...@@ -20557,7 +20709,7 @@ fn resolvePeerTypes(
20557 else20709 else
20558 new_ptr_ty;20710 new_ptr_ty;
20559 const set_ty = err_set_ty orelse return opt_ptr_ty;20711 const set_ty = err_set_ty orelse return opt_ptr_ty;
20560 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20712 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20561 }20713 }
2056220714
20563 if (seen_const) {20715 if (seen_const) {
...@@ -20573,7 +20725,7 @@ fn resolvePeerTypes(...@@ -20573,7 +20725,7 @@ fn resolvePeerTypes(
20573 else20725 else
20574 new_ptr_ty;20726 new_ptr_ty;
20575 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();20727 const set_ty = err_set_ty orelse chosen_ty.errorUnionSet();
20576 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20728 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20577 },20729 },
20578 .Pointer => {20730 .Pointer => {
20579 var info = chosen_ty.ptrInfo();20731 var info = chosen_ty.ptrInfo();
...@@ -20584,7 +20736,7 @@ fn resolvePeerTypes(...@@ -20584,7 +20736,7 @@ fn resolvePeerTypes(
20584 else20736 else
20585 new_ptr_ty;20737 new_ptr_ty;
20586 const set_ty = err_set_ty orelse return opt_ptr_ty;20738 const set_ty = err_set_ty orelse return opt_ptr_ty;
20587 return try Module.errorUnionType(sema.arena, set_ty, opt_ptr_ty);20739 return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, target);
20588 },20740 },
20589 else => return chosen_ty,20741 else => return chosen_ty,
20590 }20742 }
...@@ -20596,16 +20748,16 @@ fn resolvePeerTypes(...@@ -20596,16 +20748,16 @@ fn resolvePeerTypes(
20596 else => try Type.optional(sema.arena, chosen_ty),20748 else => try Type.optional(sema.arena, chosen_ty),
20597 };20749 };
20598 const set_ty = err_set_ty orelse return opt_ty;20750 const set_ty = err_set_ty orelse return opt_ty;
20599 return try Module.errorUnionType(sema.arena, set_ty, opt_ty);20751 return try Type.errorUnion(sema.arena, set_ty, opt_ty, target);
20600 }20752 }
2060120753
20602 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {20754 if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) {
20603 .ErrorSet => return ty,20755 .ErrorSet => return ty,
20604 .ErrorUnion => {20756 .ErrorUnion => {
20605 const payload_ty = chosen_ty.errorUnionPayload();20757 const payload_ty = chosen_ty.errorUnionPayload();
20606 return try Module.errorUnionType(sema.arena, ty, payload_ty);20758 return try Type.errorUnion(sema.arena, ty, payload_ty, target);
20607 },20759 },
20608 else => return try Module.errorUnionType(sema.arena, ty, chosen_ty),20760 else => return try Type.errorUnion(sema.arena, ty, chosen_ty, target),
20609 };20761 };
2061020762
20611 return chosen_ty;20763 return chosen_ty;
...@@ -20624,7 +20776,7 @@ pub fn resolveFnTypes(...@@ -20624,7 +20776,7 @@ pub fn resolveFnTypes(
20624 }20776 }
20625}20777}
2062620778
20627fn resolveTypeLayout(20779pub fn resolveTypeLayout(
20628 sema: *Sema,20780 sema: *Sema,
20629 block: *Block,20781 block: *Block,
20630 src: LazySrcLoc,20782 src: LazySrcLoc,
...@@ -20662,11 +20814,12 @@ fn resolveStructLayout(...@@ -20662,11 +20814,12 @@ fn resolveStructLayout(
20662) CompileError!void {20814) CompileError!void {
20663 const resolved_ty = try sema.resolveTypeFields(block, src, ty);20815 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
20664 if (resolved_ty.castTag(.@"struct")) |payload| {20816 if (resolved_ty.castTag(.@"struct")) |payload| {
20817 const target = sema.mod.getTarget();
20665 const struct_obj = payload.data;20818 const struct_obj = payload.data;
20666 switch (struct_obj.status) {20819 switch (struct_obj.status) {
20667 .none, .have_field_types => {},20820 .none, .have_field_types => {},
20668 .field_types_wip, .layout_wip => {20821 .field_types_wip, .layout_wip => {
20669 return sema.fail(block, src, "struct {} depends on itself", .{ty});20822 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
20670 },20823 },
20671 .have_layout, .fully_resolved_wip, .fully_resolved => return,20824 .have_layout, .fully_resolved_wip, .fully_resolved => return,
20672 }20825 }
...@@ -20694,10 +20847,11 @@ fn resolveUnionLayout(...@@ -20694,10 +20847,11 @@ fn resolveUnionLayout(
20694) CompileError!void {20847) CompileError!void {
20695 const resolved_ty = try sema.resolveTypeFields(block, src, ty);20848 const resolved_ty = try sema.resolveTypeFields(block, src, ty);
20696 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;20849 const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
20850 const target = sema.mod.getTarget();
20697 switch (union_obj.status) {20851 switch (union_obj.status) {
20698 .none, .have_field_types => {},20852 .none, .have_field_types => {},
20699 .field_types_wip, .layout_wip => {20853 .field_types_wip, .layout_wip => {
20700 return sema.fail(block, src, "union {} depends on itself", .{ty});20854 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
20701 },20855 },
20702 .have_layout, .fully_resolved_wip, .fully_resolved => return,20856 .have_layout, .fully_resolved_wip, .fully_resolved => return,
20703 }20857 }
...@@ -20793,7 +20947,7 @@ fn resolveUnionFully(...@@ -20793,7 +20947,7 @@ fn resolveUnionFully(
20793 union_obj.status = .fully_resolved;20947 union_obj.status = .fully_resolved;
20794}20948}
2079520949
20796fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type {20950pub fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type {
20797 switch (ty.tag()) {20951 switch (ty.tag()) {
20798 .@"struct" => {20952 .@"struct" => {
20799 const struct_obj = ty.castTag(.@"struct").?.data;20953 const struct_obj = ty.castTag(.@"struct").?.data;
...@@ -20828,10 +20982,11 @@ fn resolveTypeFieldsStruct(...@@ -20828,10 +20982,11 @@ fn resolveTypeFieldsStruct(
20828 ty: Type,20982 ty: Type,
20829 struct_obj: *Module.Struct,20983 struct_obj: *Module.Struct,
20830) CompileError!void {20984) CompileError!void {
20985 const target = sema.mod.getTarget();
20831 switch (struct_obj.status) {20986 switch (struct_obj.status) {
20832 .none => {},20987 .none => {},
20833 .field_types_wip => {20988 .field_types_wip => {
20834 return sema.fail(block, src, "struct {} depends on itself", .{ty});20989 return sema.fail(block, src, "struct {} depends on itself", .{ty.fmt(target)});
20835 },20990 },
20836 .have_field_types,20991 .have_field_types,
20837 .have_layout,20992 .have_layout,
...@@ -20858,10 +21013,11 @@ fn resolveTypeFieldsUnion(...@@ -20858,10 +21013,11 @@ fn resolveTypeFieldsUnion(
20858 ty: Type,21013 ty: Type,
20859 union_obj: *Module.Union,21014 union_obj: *Module.Union,
20860) CompileError!void {21015) CompileError!void {
21016 const target = sema.mod.getTarget();
20861 switch (union_obj.status) {21017 switch (union_obj.status) {
20862 .none => {},21018 .none => {},
20863 .field_types_wip => {21019 .field_types_wip => {
20864 return sema.fail(block, src, "union {} depends on itself", .{ty});21020 return sema.fail(block, src, "union {} depends on itself", .{ty.fmt(target)});
20865 },21021 },
20866 .have_field_types,21022 .have_field_types,
20867 .have_layout,21023 .have_layout,
...@@ -21218,6 +21374,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -21218,6 +21374,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
21218 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;21374 enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields;
21219 }21375 }
2122021376
21377 const target = sema.mod.getTarget();
21378
21221 const bits_per_field = 4;21379 const bits_per_field = 4;
21222 const fields_per_u32 = 32 / bits_per_field;21380 const fields_per_u32 = 32 / bits_per_field;
21223 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;21381 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
...@@ -21275,16 +21433,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -21275,16 +21433,22 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
21275 // This puts the memory into the union arena, not the enum arena, but21433 // This puts the memory into the union arena, not the enum arena, but
21276 // it is OK since they share the same lifetime.21434 // it is OK since they share the same lifetime.
21277 const copied_val = try val.copy(decl_arena_allocator);21435 const copied_val = try val.copy(decl_arena_allocator);
21278 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });21436 map.putAssumeCapacityContext(copied_val, {}, .{
21437 .ty = int_tag_ty,
21438 .target = target,
21439 });
21279 } else {21440 } else {
21280 const val = if (last_tag_val) |val|21441 const val = if (last_tag_val) |val|
21281 try val.intAdd(Value.one, int_tag_ty, sema.arena)21442 try val.intAdd(Value.one, int_tag_ty, sema.arena, target)
21282 else21443 else
21283 Value.zero;21444 Value.zero;
21284 last_tag_val = val;21445 last_tag_val = val;
2128521446
21286 const copied_val = try val.copy(decl_arena_allocator);21447 const copied_val = try val.copy(decl_arena_allocator);
21287 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });21448 map.putAssumeCapacityContext(copied_val, {}, .{
21449 .ty = int_tag_ty,
21450 .target = target,
21451 });
21288 }21452 }
21289 }21453 }
2129021454
...@@ -21359,7 +21523,10 @@ fn generateUnionTagTypeNumbered(...@@ -21359,7 +21523,10 @@ fn generateUnionTagTypeNumbered(
21359 };21523 };
21360 // Here we pre-allocate the maps using the decl arena.21524 // Here we pre-allocate the maps using the decl arena.
21361 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);21525 try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
21362 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{ .ty = int_ty });21526 try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{
21527 .ty = int_ty,
21528 .target = sema.mod.getTarget(),
21529 });
21363 try new_decl.finalizeNewArena(&new_decl_arena);21530 try new_decl.finalizeNewArena(&new_decl_arena);
21364 return enum_ty;21531 return enum_ty;
21365}21532}
...@@ -21962,7 +22129,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -21962,7 +22129,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
21962 // The type is not in-memory coercible or the direct dereference failed, so it must22129 // The type is not in-memory coercible or the direct dereference failed, so it must
21963 // be bitcast according to the pointer type we are performing the load through.22130 // be bitcast according to the pointer type we are performing the load through.
21964 if (!load_ty.hasWellDefinedLayout())22131 if (!load_ty.hasWellDefinedLayout())
21965 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty});22132 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{load_ty.fmt(target)});
2196622133
21967 const load_sz = try sema.typeAbiSize(block, src, load_ty);22134 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2196822135
...@@ -21977,11 +22144,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -21977,11 +22144,11 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
21977 if (deref.ty_without_well_defined_layout) |bad_ty| {22144 if (deref.ty_without_well_defined_layout) |bad_ty| {
21978 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem22145 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
21979 // is that some type we encountered when de-referencing does not have a well-defined layout.22146 // is that some type we encountered when de-referencing does not have a well-defined layout.
21980 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty});22147 return sema.fail(block, src, "comptime dereference requires {} to have a well-defined layout, but it does not.", .{bad_ty.fmt(target)});
21981 } else {22148 } else {
21982 // If all encountered types had well-defined layouts, the parent is the root decl and it just22149 // If all encountered types had well-defined layouts, the parent is the root decl and it just
21983 // wasn't big enough for the load.22150 // wasn't big enough for the load.
21984 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty, deref.parent.?.tv.ty });22151 return sema.fail(block, src, "dereference of {} exceeds bounds of containing decl of type {}", .{ ptr_ty.fmt(target), deref.parent.?.tv.ty.fmt(target) });
21985 }22152 }
21986}22153}
2198722154
...@@ -22060,7 +22227,9 @@ fn typePtrOrOptionalPtrTy(...@@ -22060,7 +22227,9 @@ fn typePtrOrOptionalPtrTy(
22060/// This function returns false negatives when structs and unions are having their22227/// This function returns false negatives when structs and unions are having their
22061/// field types resolved.22228/// field types resolved.
22062/// TODO assert the return value matches `ty.comptimeOnly`22229/// TODO assert the return value matches `ty.comptimeOnly`
22063fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {22230/// TODO merge these implementations together with the "advanced"/sema_kit pattern seen
22231/// elsewhere in value.zig
22232pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool {
22064 return switch (ty.tag()) {22233 return switch (ty.tag()) {
22065 .u1,22234 .u1,
22066 .u8,22235 .u8,
...@@ -22266,6 +22435,7 @@ fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 {...@@ -22266,6 +22435,7 @@ fn typeAbiSize(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u64 {
22266 return ty.abiSize(target);22435 return ty.abiSize(target);
22267}22436}
2226822437
22438/// TODO merge with Type.abiAlignmentAdvanced
22269fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 {22439fn typeAbiAlignment(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !u32 {
22270 try sema.resolveTypeLayout(block, src, ty);22440 try sema.resolveTypeLayout(block, src, ty);
22271 const target = sema.mod.getTarget();22441 const target = sema.mod.getTarget();
...@@ -22344,7 +22514,12 @@ fn anonStructFieldIndex(...@@ -22344,7 +22514,12 @@ fn anonStructFieldIndex(
22344 return @intCast(u32, i);22514 return @intCast(u32, i);
22345 }22515 }
22346 }22516 }
22517 const target = sema.mod.getTarget();
22347 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{22518 return sema.fail(block, field_src, "anonymous struct {} has no such field '{s}'", .{
22348 struct_ty, field_name,22519 struct_ty.fmt(target), field_name,
22349 });22520 });
22350}22521}
22522
22523fn kit(sema: *Sema, block: *Block, src: LazySrcLoc) Module.WipAnalysis {
22524 return .{ .sema = sema, .block = block, .src = src };
22525}
src/TypedValue.zig+35-22
...@@ -3,6 +3,7 @@ const Type = @import("type.zig").Type;...@@ -3,6 +3,7 @@ const Type = @import("type.zig").Type;
3const Value = @import("value.zig").Value;3const Value = @import("value.zig").Value;
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const TypedValue = @This();5const TypedValue = @This();
6const Target = std.Target;
67
7ty: Type,8ty: Type,
8val: Value,9val: Value,
...@@ -30,13 +31,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {...@@ -30,13 +31,13 @@ pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue {
30 };31 };
31}32}
3233
33pub fn eql(a: TypedValue, b: TypedValue) bool {34pub fn eql(a: TypedValue, b: TypedValue, target: std.Target) bool {
34 if (!a.ty.eql(b.ty)) return false;35 if (!a.ty.eql(b.ty, target)) return false;
35 return a.val.eql(b.val, a.ty);36 return a.val.eql(b.val, a.ty, target);
36}37}
3738
38pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash) void {39pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, target: std.Target) void {
39 return tv.val.hash(tv.ty, hasher);40 return tv.val.hash(tv.ty, hasher, target);
40}41}
4142
42pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {43pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
...@@ -45,21 +46,28 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {...@@ -45,21 +46,28 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
4546
46const max_aggregate_items = 100;47const max_aggregate_items = 100;
4748
48pub fn format(49const FormatContext = struct {
49 tv: TypedValue,50 tv: TypedValue,
51 target: Target,
52};
53
54pub fn format(
55 ctx: FormatContext,
50 comptime fmt: []const u8,56 comptime fmt: []const u8,
51 options: std.fmt.FormatOptions,57 options: std.fmt.FormatOptions,
52 writer: anytype,58 writer: anytype,
53) !void {59) !void {
60 _ = options;
54 comptime std.debug.assert(fmt.len == 0);61 comptime std.debug.assert(fmt.len == 0);
55 return tv.print(options, writer, 3);62 return ctx.tv.print(writer, 3, ctx.target);
56}63}
5764
65/// Prints the Value according to the Type, not according to the Value Tag.
58pub fn print(66pub fn print(
59 tv: TypedValue,67 tv: TypedValue,
60 options: std.fmt.FormatOptions,
61 writer: anytype,68 writer: anytype,
62 level: u8,69 level: u8,
70 target: std.Target,
63) @TypeOf(writer).Error!void {71) @TypeOf(writer).Error!void {
64 var val = tv.val;72 var val = tv.val;
65 var ty = tv.ty;73 var ty = tv.ty;
...@@ -148,7 +156,7 @@ pub fn print(...@@ -148,7 +156,7 @@ pub fn print(
148 try print(.{156 try print(.{
149 .ty = fields[i].ty,157 .ty = fields[i].ty,
150 .val = vals[i],158 .val = vals[i],
151 }, options, writer, level - 1);159 }, writer, level - 1, target);
152 }160 }
153 return writer.writeAll(" }");161 return writer.writeAll(" }");
154 } else {162 } else {
...@@ -162,7 +170,7 @@ pub fn print(...@@ -162,7 +170,7 @@ pub fn print(
162 try print(.{170 try print(.{
163 .ty = elem_ty,171 .ty = elem_ty,
164 .val = vals[i],172 .val = vals[i],
165 }, options, writer, level - 1);173 }, writer, level - 1, target);
166 }174 }
167 return writer.writeAll(" }");175 return writer.writeAll(" }");
168 }176 }
...@@ -177,12 +185,12 @@ pub fn print(...@@ -177,12 +185,12 @@ pub fn print(
177 try print(.{185 try print(.{
178 .ty = ty.unionTagType().?,186 .ty = ty.unionTagType().?,
179 .val = union_val.tag,187 .val = union_val.tag,
180 }, options, writer, level - 1);188 }, writer, level - 1, target);
181 try writer.writeAll(" = ");189 try writer.writeAll(" = ");
182 try print(.{190 try print(.{
183 .ty = ty.unionFieldType(union_val.tag),191 .ty = ty.unionFieldType(union_val.tag, target),
184 .val = union_val.val,192 .val = union_val.val,
185 }, options, writer, level - 1);193 }, writer, level - 1, target);
186194
187 return writer.writeAll(" }");195 return writer.writeAll(" }");
188 },196 },
...@@ -197,7 +205,7 @@ pub fn print(...@@ -197,7 +205,7 @@ pub fn print(
197 },205 },
198 .bool_true => return writer.writeAll("true"),206 .bool_true => return writer.writeAll("true"),
199 .bool_false => return writer.writeAll("false"),207 .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),
201 .int_type => {209 .int_type => {
202 const int_type = val.castTag(.int_type).?.data;210 const int_type = val.castTag(.int_type).?.data;
203 return writer.print("{s}{d}", .{211 return writer.print("{s}{d}", .{
...@@ -205,10 +213,15 @@ pub fn print(...@@ -205,10 +213,15 @@ pub fn print(
205 int_type.bits,213 int_type.bits,
206 });214 });
207 },215 },
208 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", options, writer),216 .int_u64 => return std.fmt.formatIntValue(val.castTag(.int_u64).?.data, "", .{}, writer),
209 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, writer),217 .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", .{}, writer),
210 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),218 .int_big_positive => return writer.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}),
211 .int_big_negative => return writer.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}),219 .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 },
212 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),225 .function => return writer.print("(function '{s}')", .{val.castTag(.function).?.data.owner_decl.name}),
213 .extern_fn => return writer.writeAll("(extern function)"),226 .extern_fn => return writer.writeAll("(extern function)"),
214 .variable => return writer.writeAll("(variable)"),227 .variable => return writer.writeAll("(variable)"),
...@@ -220,7 +233,7 @@ pub fn print(...@@ -220,7 +233,7 @@ pub fn print(
220 return print(.{233 return print(.{
221 .ty = decl.ty,234 .ty = decl.ty,
222 .val = decl.val,235 .val = decl.val,
223 }, options, writer, level - 1);236 }, writer, level - 1, target);
224 },237 },
225 .decl_ref => {238 .decl_ref => {
226 const decl = val.castTag(.decl_ref).?.data;239 const decl = val.castTag(.decl_ref).?.data;
...@@ -230,7 +243,7 @@ pub fn print(...@@ -230,7 +243,7 @@ pub fn print(
230 return print(.{243 return print(.{
231 .ty = decl.ty,244 .ty = decl.ty,
232 .val = decl.val,245 .val = decl.val,
233 }, options, writer, level - 1);246 }, writer, level - 1, target);
234 },247 },
235 .elem_ptr => {248 .elem_ptr => {
236 const elem_ptr = val.castTag(.elem_ptr).?.data;249 const elem_ptr = val.castTag(.elem_ptr).?.data;
...@@ -238,7 +251,7 @@ pub fn print(...@@ -238,7 +251,7 @@ pub fn print(
238 try print(.{251 try print(.{
239 .ty = elem_ptr.elem_ty,252 .ty = elem_ptr.elem_ty,
240 .val = elem_ptr.array_ptr,253 .val = elem_ptr.array_ptr,
241 }, options, writer, level - 1);254 }, writer, level - 1, target);
242 return writer.print("[{}]", .{elem_ptr.index});255 return writer.print("[{}]", .{elem_ptr.index});
243 },256 },
244 .field_ptr => {257 .field_ptr => {
...@@ -247,7 +260,7 @@ pub fn print(...@@ -247,7 +260,7 @@ pub fn print(
247 try print(.{260 try print(.{
248 .ty = field_ptr.container_ty,261 .ty = field_ptr.container_ty,
249 .val = field_ptr.container_ptr,262 .val = field_ptr.container_ptr,
250 }, options, writer, level - 1);263 }, writer, level - 1, target);
251264
252 if (field_ptr.container_ty.zigTypeTag() == .Struct) {265 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
253 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];266 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];
...@@ -275,7 +288,7 @@ pub fn print(...@@ -275,7 +288,7 @@ pub fn print(
275 };288 };
276 while (i < max_aggregate_items) : (i += 1) {289 while (i < max_aggregate_items) : (i += 1) {
277 if (i != 0) try writer.writeAll(", ");290 if (i != 0) try writer.writeAll(", ");
278 try print(elem_tv, options, writer, level - 1);291 try print(elem_tv, writer, level - 1, target);
279 }292 }
280 return writer.writeAll(" }");293 return writer.writeAll(" }");
281 },294 },
...@@ -287,7 +300,7 @@ pub fn print(...@@ -287,7 +300,7 @@ pub fn print(
287 try print(.{300 try print(.{
288 .ty = ty.elemType2(),301 .ty = ty.elemType2(),
289 .val = ty.sentinel().?,302 .val = ty.sentinel().?,
290 }, options, writer, level - 1);303 }, writer, level - 1, target);
291 return writer.writeAll(" }");304 return writer.writeAll(" }");
292 },305 },
293 .slice => return writer.writeAll("(slice)"),306 .slice => return writer.writeAll("(slice)"),
src/arch/aarch64/CodeGen.zig+20-13
...@@ -796,7 +796,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {...@@ -796,7 +796,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
796 const index = dbg_out.dbg_info.items.len;796 const index = dbg_out.dbg_info.items.len;
797 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4797 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 });
800 if (!gop.found_existing) {802 if (!gop.found_existing) {
801 gop.value_ptr.* = .{803 gop.value_ptr.* = .{
802 .off = undefined,804 .off = undefined,
...@@ -835,8 +837,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -835,8 +837,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
835 return self.next_stack_offset;837 return self.next_stack_offset;
836 }838 }
837839
840 const target = self.target.*;
838 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {841 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)});
840 };843 };
841 // TODO swap this for inst.ty.ptrAlign844 // TODO swap this for inst.ty.ptrAlign
842 const abi_align = elem_ty.abiAlignment(self.target.*);845 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -845,8 +848,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -845,8 +848,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
845848
846fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {849fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
847 const elem_ty = self.air.typeOfIndex(inst);850 const elem_ty = self.air.typeOfIndex(inst);
851 const target = self.target.*;
848 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {852 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)});
850 };854 };
851 const abi_align = elem_ty.abiAlignment(self.target.*);855 const abi_align = elem_ty.abiAlignment(self.target.*);
852 if (abi_align > self.stack_align)856 if (abi_align > self.stack_align)
...@@ -1372,6 +1376,7 @@ fn binOp(...@@ -1372,6 +1376,7 @@ fn binOp(
1372 lhs_ty: Type,1376 lhs_ty: Type,
1373 rhs_ty: Type,1377 rhs_ty: Type,
1374) InnerError!MCValue {1378) InnerError!MCValue {
1379 const target = self.target.*;
1375 switch (tag) {1380 switch (tag) {
1376 // Arithmetic operations on integers and floats1381 // Arithmetic operations on integers and floats
1377 .add,1382 .add,
...@@ -1381,7 +1386,7 @@ fn binOp(...@@ -1381,7 +1386,7 @@ fn binOp(
1381 .Float => return self.fail("TODO binary operations on floats", .{}),1386 .Float => return self.fail("TODO binary operations on floats", .{}),
1382 .Vector => return self.fail("TODO binary operations on vectors", .{}),1387 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1383 .Int => {1388 .Int => {
1384 assert(lhs_ty.eql(rhs_ty));1389 assert(lhs_ty.eql(rhs_ty, target));
1385 const int_info = lhs_ty.intInfo(self.target.*);1390 const int_info = lhs_ty.intInfo(self.target.*);
1386 if (int_info.bits <= 64) {1391 if (int_info.bits <= 64) {
1387 // Only say yes if the operation is1392 // Only say yes if the operation is
...@@ -1418,7 +1423,7 @@ fn binOp(...@@ -1418,7 +1423,7 @@ fn binOp(
1418 switch (lhs_ty.zigTypeTag()) {1423 switch (lhs_ty.zigTypeTag()) {
1419 .Vector => return self.fail("TODO binary operations on vectors", .{}),1424 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1420 .Int => {1425 .Int => {
1421 assert(lhs_ty.eql(rhs_ty));1426 assert(lhs_ty.eql(rhs_ty, target));
1422 const int_info = lhs_ty.intInfo(self.target.*);1427 const int_info = lhs_ty.intInfo(self.target.*);
1423 if (int_info.bits <= 64) {1428 if (int_info.bits <= 64) {
1424 // TODO add optimisations for multiplication1429 // TODO add optimisations for multiplication
...@@ -1440,7 +1445,7 @@ fn binOp(...@@ -1440,7 +1445,7 @@ fn binOp(
1440 switch (lhs_ty.zigTypeTag()) {1445 switch (lhs_ty.zigTypeTag()) {
1441 .Vector => return self.fail("TODO binary operations on vectors", .{}),1446 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1442 .Int => {1447 .Int => {
1443 assert(lhs_ty.eql(rhs_ty));1448 assert(lhs_ty.eql(rhs_ty, target));
1444 const int_info = lhs_ty.intInfo(self.target.*);1449 const int_info = lhs_ty.intInfo(self.target.*);
1445 if (int_info.bits <= 64) {1450 if (int_info.bits <= 64) {
1446 // TODO implement bitwise operations with immediates1451 // TODO implement bitwise operations with immediates
...@@ -2348,11 +2353,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -2348,11 +2353,12 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
2348 const ty = self.air.typeOfIndex(inst);2353 const ty = self.air.typeOfIndex(inst);
23492354
2350 const result = self.args[arg_index];2355 const result = self.args[arg_index];
2356 const target = self.target.*;
2351 const mcv = switch (result) {2357 const mcv = switch (result) {
2352 // Copy registers to the stack2358 // Copy registers to the stack
2353 .register => |reg| blk: {2359 .register => |reg| blk: {
2354 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {2360 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)});
2356 };2362 };
2357 const abi_align = ty.abiAlignment(self.target.*);2363 const abi_align = ty.abiAlignment(self.target.*);
2358 const stack_offset = try self.allocMem(inst, abi_size, abi_align);2364 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...@@ -3879,7 +3885,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
3879}3885}
38803886
3881fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {3887fn 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() });
3883 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {3889 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
3884 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});3890 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
3885 };3891 };
...@@ -3907,6 +3913,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3907,6 +3913,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3907 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {3913 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
3908 return self.lowerDeclRef(typed_value, payload.data.decl);3914 return self.lowerDeclRef(typed_value, payload.data.decl);
3909 }3915 }
3916 const target = self.target.*;
39103917
3911 switch (typed_value.ty.zigTypeTag()) {3918 switch (typed_value.ty.zigTypeTag()) {
3912 .Pointer => switch (typed_value.ty.ptrSize()) {3919 .Pointer => switch (typed_value.ty.ptrSize()) {
...@@ -3916,7 +3923,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3916,7 +3923,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3916 else => {3923 else => {
3917 switch (typed_value.val.tag()) {3924 switch (typed_value.val.tag()) {
3918 .int_u64 => {3925 .int_u64 => {
3919 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };3926 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
3920 },3927 },
3921 .slice => {3928 .slice => {
3922 return self.lowerUnnamedConst(typed_value);3929 return self.lowerUnnamedConst(typed_value);
...@@ -3935,7 +3942,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3935,7 +3942,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3935 const signed = typed_value.val.toSignedInt();3942 const signed = typed_value.val.toSignedInt();
3936 break :blk @bitCast(u64, signed);3943 break :blk @bitCast(u64, signed);
3937 },3944 },
3938 .unsigned => typed_value.val.toUnsignedInt(),3945 .unsigned => typed_value.val.toUnsignedInt(target),
3939 };3946 };
39403947
3941 return MCValue{ .immediate = unsigned };3948 return MCValue{ .immediate = unsigned };
...@@ -4004,20 +4011,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4004,20 +4011,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4004 }4011 }
40054012
4006 _ = pl;4013 _ = 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()});
4008 } else {4015 } else {
4009 if (!payload_type.hasRuntimeBits()) {4016 if (!payload_type.hasRuntimeBits()) {
4010 // We use the error type directly as the type.4017 // We use the error type directly as the type.
4011 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });4018 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
4012 }4019 }
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()});
4015 }4022 }
4016 },4023 },
4017 .Struct => {4024 .Struct => {
4018 return self.lowerUnnamedConst(typed_value);4025 return self.lowerUnnamedConst(typed_value);
4019 },4026 },
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()}),
4021 }4028 }
4022}4029}
40234030
src/arch/arm/CodeGen.zig+14-10
...@@ -801,8 +801,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -801,8 +801,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
801 return self.next_stack_offset;801 return self.next_stack_offset;
802 }802 }
803803
804 const target = self.target.*;
804 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {805 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)});
806 };807 };
807 // TODO swap this for inst.ty.ptrAlign808 // TODO swap this for inst.ty.ptrAlign
808 const abi_align = elem_ty.abiAlignment(self.target.*);809 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -811,8 +812,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -811,8 +812,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
811812
812fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {813fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
813 const elem_ty = self.air.typeOfIndex(inst);814 const elem_ty = self.air.typeOfIndex(inst);
815 const target = self.target.*;
814 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {816 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)});
816 };818 };
817 const abi_align = elem_ty.abiAlignment(self.target.*);819 const abi_align = elem_ty.abiAlignment(self.target.*);
818 if (abi_align > self.stack_align)820 if (abi_align > self.stack_align)
...@@ -2195,6 +2197,7 @@ fn binOp(...@@ -2195,6 +2197,7 @@ fn binOp(
2195 lhs_ty: Type,2197 lhs_ty: Type,
2196 rhs_ty: Type,2198 rhs_ty: Type,
2197) InnerError!MCValue {2199) InnerError!MCValue {
2200 const target = self.target.*;
2198 switch (tag) {2201 switch (tag) {
2199 .add,2202 .add,
2200 .sub,2203 .sub,
...@@ -2204,7 +2207,7 @@ fn binOp(...@@ -2204,7 +2207,7 @@ fn binOp(
2204 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2207 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2205 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2208 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2206 .Int => {2209 .Int => {
2207 assert(lhs_ty.eql(rhs_ty));2210 assert(lhs_ty.eql(rhs_ty, target));
2208 const int_info = lhs_ty.intInfo(self.target.*);2211 const int_info = lhs_ty.intInfo(self.target.*);
2209 if (int_info.bits <= 32) {2212 if (int_info.bits <= 32) {
2210 // Only say yes if the operation is2213 // Only say yes if the operation is
...@@ -2245,7 +2248,7 @@ fn binOp(...@@ -2245,7 +2248,7 @@ fn binOp(
2245 .Float => return self.fail("TODO ARM binary operations on floats", .{}),2248 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2246 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2249 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2247 .Int => {2250 .Int => {
2248 assert(lhs_ty.eql(rhs_ty));2251 assert(lhs_ty.eql(rhs_ty, target));
2249 const int_info = lhs_ty.intInfo(self.target.*);2252 const int_info = lhs_ty.intInfo(self.target.*);
2250 if (int_info.bits <= 32) {2253 if (int_info.bits <= 32) {
2251 // TODO add optimisations for multiplication2254 // TODO add optimisations for multiplication
...@@ -2299,7 +2302,7 @@ fn binOp(...@@ -2299,7 +2302,7 @@ fn binOp(
2299 switch (lhs_ty.zigTypeTag()) {2302 switch (lhs_ty.zigTypeTag()) {
2300 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),2303 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2301 .Int => {2304 .Int => {
2302 assert(lhs_ty.eql(rhs_ty));2305 assert(lhs_ty.eql(rhs_ty, target));
2303 const int_info = lhs_ty.intInfo(self.target.*);2306 const int_info = lhs_ty.intInfo(self.target.*);
2304 if (int_info.bits <= 32) {2307 if (int_info.bits <= 32) {
2305 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;2308 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 {...@@ -4376,6 +4379,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4376 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {4379 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
4377 return self.lowerDeclRef(typed_value, payload.data.decl);4380 return self.lowerDeclRef(typed_value, payload.data.decl);
4378 }4381 }
4382 const target = self.target.*;
43794383
4380 switch (typed_value.ty.zigTypeTag()) {4384 switch (typed_value.ty.zigTypeTag()) {
4381 .Array => {4385 .Array => {
...@@ -4388,7 +4392,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4388,7 +4392,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4388 else => {4392 else => {
4389 switch (typed_value.val.tag()) {4393 switch (typed_value.val.tag()) {
4390 .int_u64 => {4394 .int_u64 => {
4391 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt()) };4395 return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) };
4392 },4396 },
4393 .slice => {4397 .slice => {
4394 return self.lowerUnnamedConst(typed_value);4398 return self.lowerUnnamedConst(typed_value);
...@@ -4407,7 +4411,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4407,7 +4411,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4407 const signed = @intCast(i32, typed_value.val.toSignedInt());4411 const signed = @intCast(i32, typed_value.val.toSignedInt());
4408 break :blk @bitCast(u32, signed);4412 break :blk @bitCast(u32, signed);
4409 },4413 },
4410 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt()),4414 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt(target)),
4411 };4415 };
44124416
4413 return MCValue{ .immediate = unsigned };4417 return MCValue{ .immediate = unsigned };
...@@ -4476,20 +4480,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4476,20 +4480,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4476 }4480 }
44774481
4478 _ = pl;4482 _ = 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()});
4480 } else {4484 } else {
4481 if (!payload_type.hasRuntimeBits()) {4485 if (!payload_type.hasRuntimeBits()) {
4482 // We use the error type directly as the type.4486 // We use the error type directly as the type.
4483 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });4487 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
4484 }4488 }
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()});
4487 }4491 }
4488 },4492 },
4489 .Struct => {4493 .Struct => {
4490 return self.lowerUnnamedConst(typed_value);4494 return self.lowerUnnamedConst(typed_value);
4491 },4495 },
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()}),
4493 }4497 }
4494}4498}
44954499
src/arch/arm/Emit.zig+3-2
...@@ -384,7 +384,7 @@ fn addDbgInfoTypeReloc(self: *Emit, ty: Type) !void {...@@ -384,7 +384,7 @@ fn addDbgInfoTypeReloc(self: *Emit, ty: Type) !void {
384 const index = dbg_out.dbg_info.items.len;384 const index = dbg_out.dbg_info.items.len;
385 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4385 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.* });
388 if (!gop.found_existing) {388 if (!gop.found_existing) {
389 gop.value_ptr.* = .{389 gop.value_ptr.* = .{
390 .off = undefined,390 .off = undefined,
...@@ -404,6 +404,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -404,6 +404,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
404 const ty = self.function.air.instructions.items(.data)[inst].ty;404 const ty = self.function.air.instructions.items(.data)[inst].ty;
405 const name = self.function.mod_fn.getParamName(arg_index);405 const name = self.function.mod_fn.getParamName(arg_index);
406 const name_with_null = name.ptr[0 .. name.len + 1];406 const name_with_null = name.ptr[0 .. name.len + 1];
407 const target = self.target.*;
407408
408 switch (mcv) {409 switch (mcv) {
409 .register => |reg| {410 .register => |reg| {
...@@ -429,7 +430,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -429,7 +430,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
429 switch (self.debug_output) {430 switch (self.debug_output) {
430 .dwarf => |dbg_out| {431 .dwarf => |dbg_out| {
431 const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch {432 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)});
433 };434 };
434 const adjusted_stack_offset = switch (mcv) {435 const adjusted_stack_offset = switch (mcv) {
435 .stack_offset => |offset| math.negateCast(offset + abi_size) catch {436 .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 {...@@ -749,7 +749,9 @@ fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
749 const index = dbg_out.dbg_info.items.len;749 const index = dbg_out.dbg_info.items.len;
750 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4750 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 });
753 if (!gop.found_existing) {755 if (!gop.found_existing) {
754 gop.value_ptr.* = .{756 gop.value_ptr.* = .{
755 .off = undefined,757 .off = undefined,
...@@ -781,8 +783,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u...@@ -781,8 +783,9 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u
781/// Use a pointer instruction as the basis for allocating stack memory.783/// Use a pointer instruction as the basis for allocating stack memory.
782fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {784fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
783 const elem_ty = self.air.typeOfIndex(inst).elemType();785 const elem_ty = self.air.typeOfIndex(inst).elemType();
786 const target = self.target.*;
784 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {787 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)});
786 };789 };
787 // TODO swap this for inst.ty.ptrAlign790 // TODO swap this for inst.ty.ptrAlign
788 const abi_align = elem_ty.abiAlignment(self.target.*);791 const abi_align = elem_ty.abiAlignment(self.target.*);
...@@ -791,8 +794,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -791,8 +794,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
791794
792fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {795fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
793 const elem_ty = self.air.typeOfIndex(inst);796 const elem_ty = self.air.typeOfIndex(inst);
797 const target = self.target.*;
794 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {798 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)});
796 };800 };
797 const abi_align = elem_ty.abiAlignment(self.target.*);801 const abi_align = elem_ty.abiAlignment(self.target.*);
798 if (abi_align > self.stack_align)802 if (abi_align > self.stack_align)
...@@ -1048,7 +1052,7 @@ fn binOp(...@@ -1048,7 +1052,7 @@ fn binOp(
1048 .Float => return self.fail("TODO binary operations on floats", .{}),1052 .Float => return self.fail("TODO binary operations on floats", .{}),
1049 .Vector => return self.fail("TODO binary operations on vectors", .{}),1053 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1050 .Int => {1054 .Int => {
1051 assert(lhs_ty.eql(rhs_ty));1055 assert(lhs_ty.eql(rhs_ty, self.target.*));
1052 const int_info = lhs_ty.intInfo(self.target.*);1056 const int_info = lhs_ty.intInfo(self.target.*);
1053 if (int_info.bits <= 64) {1057 if (int_info.bits <= 64) {
1054 // TODO immediate operands1058 // TODO immediate operands
...@@ -1778,7 +1782,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -1778,7 +1782,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1778 if (self.liveness.isUnused(inst))1782 if (self.liveness.isUnused(inst))
1779 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1783 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1780 const ty = self.air.typeOf(bin_op.lhs);1784 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.*));
1782 if (ty.zigTypeTag() == .ErrorSet)1786 if (ty.zigTypeTag() == .ErrorSet)
1783 return self.fail("TODO implement cmp for errors", .{});1787 return self.fail("TODO implement cmp for errors", .{});
17841788
...@@ -2531,6 +2535,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2531,6 +2535,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2531 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {2535 if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
2532 return self.lowerDeclRef(typed_value, payload.data.decl);2536 return self.lowerDeclRef(typed_value, payload.data.decl);
2533 }2537 }
2538 const target = self.target.*;
2534 const ptr_bits = self.target.cpu.arch.ptrBitWidth();2539 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2535 switch (typed_value.ty.zigTypeTag()) {2540 switch (typed_value.ty.zigTypeTag()) {
2536 .Pointer => switch (typed_value.ty.ptrSize()) {2541 .Pointer => switch (typed_value.ty.ptrSize()) {
...@@ -2538,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2538,7 +2543,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2538 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2543 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2539 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);2544 const ptr_type = typed_value.ty.slicePtrFieldType(&buf);
2540 const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val });2545 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);
2542 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean2547 // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean
2543 // the Sema code needs to use anonymous Decls or alloca instructions to store data.2548 // the Sema code needs to use anonymous Decls or alloca instructions to store data.
2544 const ptr_imm = ptr_mcv.memory;2549 const ptr_imm = ptr_mcv.memory;
...@@ -2549,7 +2554,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2549,7 +2554,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2549 },2554 },
2550 else => {2555 else => {
2551 if (typed_value.val.tag() == .int_u64) {2556 if (typed_value.val.tag() == .int_u64) {
2552 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };2557 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
2553 }2558 }
2554 return self.fail("TODO codegen more kinds of const pointers", .{});2559 return self.fail("TODO codegen more kinds of const pointers", .{});
2555 },2560 },
...@@ -2559,7 +2564,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2559,7 +2564,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2559 if (info.bits > ptr_bits or info.signedness == .signed) {2564 if (info.bits > ptr_bits or info.signedness == .signed) {
2560 return self.fail("TODO const int bigger than ptr and signed int", .{});2565 return self.fail("TODO const int bigger than ptr and signed int", .{});
2561 }2566 }
2562 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };2567 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
2563 },2568 },
2564 .Bool => {2569 .Bool => {
2565 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };2570 return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) };
...@@ -2629,9 +2634,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2629,9 +2634,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2629 return self.genTypedValue(.{ .ty = error_type, .val = sub_val });2634 return self.genTypedValue(.{ .ty = error_type, .val = sub_val });
2630 }2635 }
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()});
2633 },2638 },
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()}),
2635 }2640 }
2636}2641}
26372642
src/arch/wasm/CodeGen.zig+21-14
...@@ -1021,7 +1021,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {...@@ -1021,7 +1021,9 @@ fn allocStack(self: *Self, ty: Type) !WValue {
1021 }1021 }
10221022
1023 const abi_size = std.math.cast(u32, ty.abiSize(self.target)) catch {1023 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 });
1025 };1027 };
1026 const abi_align = ty.abiAlignment(self.target);1028 const abi_align = ty.abiAlignment(self.target);
10271029
...@@ -1053,7 +1055,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1053,7 +1055,9 @@ fn allocStackPtr(self: *Self, inst: Air.Inst.Index) !WValue {
10531055
1054 const abi_alignment = ptr_ty.ptrAlignment(self.target);1056 const abi_alignment = ptr_ty.ptrAlignment(self.target);
1055 const abi_size = std.math.cast(u32, pointee_ty.abiSize(self.target)) catch {1057 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 });
1057 };1061 };
1058 if (abi_alignment > self.stack_alignment) {1062 if (abi_alignment > self.stack_alignment) {
1059 self.stack_alignment = abi_alignment;1063 self.stack_alignment = abi_alignment;
...@@ -1750,7 +1754,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {...@@ -1750,7 +1754,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
1750 const operand_ty = self.air.typeOfIndex(inst);1754 const operand_ty = self.air.typeOfIndex(inst);
17511755
1752 if (isByRef(operand_ty, self.target)) {1756 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()});
1754 }1758 }
17551759
1756 try self.emitWValue(lhs);1760 try self.emitWValue(lhs);
...@@ -1918,6 +1922,8 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1918,6 +1922,8 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1918 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);1922 return self.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl);
1919 }1923 }
19201924
1925 const target = self.target;
1926
1921 switch (ty.zigTypeTag()) {1927 switch (ty.zigTypeTag()) {
1922 .Int => {1928 .Int => {
1923 const int_info = ty.intInfo(self.target);1929 const int_info = ty.intInfo(self.target);
...@@ -1929,13 +1935,13 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1929,13 +1935,13 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1929 else => unreachable,1935 else => unreachable,
1930 },1936 },
1931 .unsigned => switch (int_info.bits) {1937 .unsigned => switch (int_info.bits) {
1932 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1938 0...32 => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1933 33...64 => return WValue{ .imm64 = val.toUnsignedInt() },1939 33...64 => return WValue{ .imm64 = val.toUnsignedInt(target) },
1934 else => unreachable,1940 else => unreachable,
1935 },1941 },
1936 }1942 }
1937 },1943 },
1938 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1944 .Bool => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1939 .Float => switch (ty.floatBits(self.target)) {1945 .Float => switch (ty.floatBits(self.target)) {
1940 0...32 => return WValue{ .float32 = val.toFloat(f32) },1946 0...32 => return WValue{ .float32 = val.toFloat(f32) },
1941 33...64 => return WValue{ .float64 = val.toFloat(f64) },1947 33...64 => return WValue{ .float64 = val.toFloat(f64) },
...@@ -1945,7 +1951,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {...@@ -1945,7 +1951,7 @@ fn lowerConstant(self: *Self, val: Value, ty: Type) InnerError!WValue {
1945 .field_ptr, .elem_ptr => {1951 .field_ptr, .elem_ptr => {
1946 return self.lowerParentPtr(val, ty.childType());1952 return self.lowerParentPtr(val, ty.childType());
1947 },1953 },
1948 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt()) },1954 .int_u64, .one => return WValue{ .imm32 = @intCast(u32, val.toUnsignedInt(target)) },
1949 .zero, .null_value => return WValue{ .imm32 = 0 },1955 .zero, .null_value => return WValue{ .imm32 = 0 },
1950 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),1956 else => return self.fail("Wasm TODO: lowerConstant for other const pointer tag {s}", .{val.tag()}),
1951 },1957 },
...@@ -2044,6 +2050,7 @@ fn emitUndefined(self: *Self, ty: Type) InnerError!WValue {...@@ -2044,6 +2050,7 @@ fn emitUndefined(self: *Self, ty: Type) InnerError!WValue {
2044/// It's illegal to provide a value with a type that cannot be represented2050/// It's illegal to provide a value with a type that cannot be represented
2045/// as an integer value.2051/// as an integer value.
2046fn valueAsI32(self: Self, val: Value, ty: Type) i32 {2052fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
2053 const target = self.target;
2047 switch (ty.zigTypeTag()) {2054 switch (ty.zigTypeTag()) {
2048 .Enum => {2055 .Enum => {
2049 if (val.castTag(.enum_field_index)) |field_index| {2056 if (val.castTag(.enum_field_index)) |field_index| {
...@@ -2071,7 +2078,7 @@ fn valueAsI32(self: Self, val: Value, ty: Type) i32 {...@@ -2071,7 +2078,7 @@ fn valueAsI32(self: Self, val: Value, ty: Type) i32 {
2071 },2078 },
2072 .Int => switch (ty.intInfo(self.target).signedness) {2079 .Int => switch (ty.intInfo(self.target).signedness) {
2073 .signed => return @truncate(i32, val.toSignedInt()),2080 .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))),
2075 },2082 },
2076 .ErrorSet => {2083 .ErrorSet => {
2077 const kv = self.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function2084 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 {...@@ -2296,7 +2303,7 @@ fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2296 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();2303 const struct_ty = self.air.typeOf(extra.data.struct_operand).childType();
2297 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {2304 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, self.target)) catch {
2298 return self.fail("Field type '{}' too big to fit into stack frame", .{2305 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),
2300 });2307 });
2301 };2308 };
2302 return self.structFieldPtr(struct_ptr, offset);2309 return self.structFieldPtr(struct_ptr, offset);
...@@ -2309,7 +2316,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr...@@ -2309,7 +2316,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u32) InnerEr
2309 const field_ty = struct_ty.structFieldType(index);2316 const field_ty = struct_ty.structFieldType(index);
2310 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {2317 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, self.target)) catch {
2311 return self.fail("Field type '{}' too big to fit into stack frame", .{2318 return self.fail("Field type '{}' too big to fit into stack frame", .{
2312 field_ty,2319 field_ty.fmt(self.target),
2313 });2320 });
2314 };2321 };
2315 return self.structFieldPtr(struct_ptr, offset);2322 return self.structFieldPtr(struct_ptr, offset);
...@@ -2335,7 +2342,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2335,7 +2342,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2335 const field_ty = struct_ty.structFieldType(field_index);2342 const field_ty = struct_ty.structFieldType(field_index);
2336 if (!field_ty.hasRuntimeBits()) return WValue{ .none = {} };2343 if (!field_ty.hasRuntimeBits()) return WValue{ .none = {} };
2337 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, self.target)) catch {2344 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)});
2339 };2346 };
23402347
2341 if (isByRef(field_ty, self.target)) {2348 if (isByRef(field_ty, self.target)) {
...@@ -2716,7 +2723,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -2716,7 +2723,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
2716 var buf: Type.Payload.ElemType = undefined;2723 var buf: Type.Payload.ElemType = undefined;
2717 const payload_ty = opt_ty.optionalChild(&buf);2724 const payload_ty = opt_ty.optionalChild(&buf);
2718 if (!payload_ty.hasRuntimeBits()) {2725 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()});
2720 }2727 }
27212728
2722 if (opt_ty.isPtrLikeOptional()) {2729 if (opt_ty.isPtrLikeOptional()) {
...@@ -2724,7 +2731,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue...@@ -2724,7 +2731,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) InnerError!WValue
2724 }2731 }
27252732
2726 const offset = std.math.cast(u32, opt_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2733 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)});
2728 };2735 };
27292736
2730 try self.emitWValue(operand);2737 try self.emitWValue(operand);
...@@ -2753,7 +2760,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2753,7 +2760,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2753 return operand;2760 return operand;
2754 }2761 }
2755 const offset = std.math.cast(u32, op_ty.abiSize(self.target) - payload_ty.abiSize(self.target)) catch {2762 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)});
2757 };2764 };
27582765
2759 // Create optional type, set the non-null bit, and store the operand inside the optional type2766 // 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 {...@@ -892,8 +892,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
892 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));892 return self.allocMem(inst, @sizeOf(usize), @alignOf(usize));
893 }893 }
894894
895 const target = self.target.*;
895 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {896 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)});
897 };898 };
898 // TODO swap this for inst.ty.ptrAlign899 // TODO swap this for inst.ty.ptrAlign
899 const abi_align = ptr_ty.ptrAlignment(self.target.*);900 const abi_align = ptr_ty.ptrAlignment(self.target.*);
...@@ -902,8 +903,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {...@@ -902,8 +903,9 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
902903
903fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {904fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
904 const elem_ty = self.air.typeOfIndex(inst);905 const elem_ty = self.air.typeOfIndex(inst);
906 const target = self.target.*;
905 const abi_size = math.cast(u32, elem_ty.abiSize(self.target.*)) catch {907 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)});
907 };909 };
908 const abi_align = elem_ty.abiAlignment(self.target.*);910 const abi_align = elem_ty.abiAlignment(self.target.*);
909 if (abi_align > self.stack_align)911 if (abi_align > self.stack_align)
...@@ -1142,7 +1144,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void {...@@ -1142,7 +1144,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void {
11421144
1143 const ty = self.air.typeOfIndex(inst);1145 const ty = self.air.typeOfIndex(inst);
1144 if (ty.zigTypeTag() != .Int) {1146 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()});
1146 }1148 }
1147 const signedness = ty.intInfo(self.target.*).signedness;1149 const signedness = ty.intInfo(self.target.*).signedness;
1148 const result: MCValue = result: {1150 const result: MCValue = result: {
...@@ -1676,13 +1678,13 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void {...@@ -1676,13 +1678,13 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void {
1676 const ty = self.air.typeOfIndex(inst);1678 const ty = self.air.typeOfIndex(inst);
1677 const tag = self.air.instructions.items(.tag)[inst];1679 const tag = self.air.instructions.items(.tag)[inst];
1678 switch (tag) {1680 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() }),
1680 .shl => {},1682 .shl => {},
1681 else => unreachable,1683 else => unreachable,
1682 }1684 }
16831685
1684 if (ty.zigTypeTag() != .Int) {1686 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()});
1686 }1688 }
1687 if (ty.abiSize(self.target.*) > 8) {1689 if (ty.abiSize(self.target.*) > 8) {
1688 return self.fail("TODO implement .shl for integers larger than 8 bytes", .{});1690 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...@@ -5820,7 +5822,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
5820}5822}
58215823
5822fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {5824fn 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() });
5824 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {5826 const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| {
5825 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});5827 return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)});
5826 };5828 };
...@@ -5850,13 +5852,15 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5850,13 +5852,15 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5850 return self.lowerDeclRef(typed_value, payload.data.decl);5852 return self.lowerDeclRef(typed_value, payload.data.decl);
5851 }5853 }
58525854
5855 const target = self.target.*;
5856
5853 switch (typed_value.ty.zigTypeTag()) {5857 switch (typed_value.ty.zigTypeTag()) {
5854 .Pointer => switch (typed_value.ty.ptrSize()) {5858 .Pointer => switch (typed_value.ty.ptrSize()) {
5855 .Slice => {},5859 .Slice => {},
5856 else => {5860 else => {
5857 switch (typed_value.val.tag()) {5861 switch (typed_value.val.tag()) {
5858 .int_u64 => {5862 .int_u64 => {
5859 return MCValue{ .immediate = typed_value.val.toUnsignedInt() };5863 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
5860 },5864 },
5861 else => {},5865 else => {},
5862 }5866 }
...@@ -5868,7 +5872,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -5868,7 +5872,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
5868 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };5872 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
5869 }5873 }
5870 if (!(info.bits > ptr_bits or info.signedness == .signed)) {5874 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) };
5872 }5876 }
5873 },5877 },
5874 .Bool => {5878 .Bool => {
src/arch/x86_64/Emit.zig+3-1
...@@ -1118,7 +1118,9 @@ fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {...@@ -1118,7 +1118,9 @@ fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {
1118 const index = dbg_out.dbg_info.items.len;1118 const index = dbg_out.dbg_info.items.len;
1119 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref41119 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 });
1122 if (!gop.found_existing) {1124 if (!gop.found_existing) {
1123 gop.value_ptr.* = .{1125 gop.value_ptr.* = .{
1124 .off = undefined,1126 .off = undefined,
src/codegen.zig+19-16
...@@ -165,7 +165,10 @@ pub fn generateSymbol(...@@ -165,7 +165,10 @@ pub fn generateSymbol(
165 const target = bin_file.options.target;165 const target = bin_file.options.target;
166 const endian = target.cpu.arch.endian();166 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
170 if (typed_value.val.isUndefDeep()) {173 if (typed_value.val.isUndefDeep()) {
171 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));174 const abi_size = try math.cast(usize, typed_value.ty.abiSize(target));
...@@ -295,11 +298,11 @@ pub fn generateSymbol(...@@ -295,11 +298,11 @@ pub fn generateSymbol(
295 .zero, .one, .int_u64, .int_big_positive => {298 .zero, .one, .int_u64, .int_big_positive => {
296 switch (target.cpu.arch.ptrBitWidth()) {299 switch (target.cpu.arch.ptrBitWidth()) {
297 32 => {300 32 => {
298 const x = typed_value.val.toUnsignedInt();301 const x = typed_value.val.toUnsignedInt(target);
299 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);302 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, x), endian);
300 },303 },
301 64 => {304 64 => {
302 const x = typed_value.val.toUnsignedInt();305 const x = typed_value.val.toUnsignedInt(target);
303 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);306 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
304 },307 },
305 else => unreachable,308 else => unreachable,
...@@ -433,7 +436,7 @@ pub fn generateSymbol(...@@ -433,7 +436,7 @@ pub fn generateSymbol(
433 // TODO populate .debug_info for the integer436 // TODO populate .debug_info for the integer
434 const info = typed_value.ty.intInfo(bin_file.options.target);437 const info = typed_value.ty.intInfo(bin_file.options.target);
435 if (info.bits <= 8) {438 if (info.bits <= 8) {
436 const x = @intCast(u8, typed_value.val.toUnsignedInt());439 const x = @intCast(u8, typed_value.val.toUnsignedInt(target));
437 try code.append(x);440 try code.append(x);
438 return Result{ .appended = {} };441 return Result{ .appended = {} };
439 }442 }
...@@ -443,20 +446,20 @@ pub fn generateSymbol(...@@ -443,20 +446,20 @@ pub fn generateSymbol(
443 bin_file.allocator,446 bin_file.allocator,
444 src_loc,447 src_loc,
445 "TODO implement generateSymbol for big ints ('{}')",448 "TODO implement generateSymbol for big ints ('{}')",
446 .{typed_value.ty},449 .{typed_value.ty.fmtDebug()},
447 ),450 ),
448 };451 };
449 }452 }
450 switch (info.signedness) {453 switch (info.signedness) {
451 .unsigned => {454 .unsigned => {
452 if (info.bits <= 16) {455 if (info.bits <= 16) {
453 const x = @intCast(u16, typed_value.val.toUnsignedInt());456 const x = @intCast(u16, typed_value.val.toUnsignedInt(target));
454 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);457 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
455 } else if (info.bits <= 32) {458 } else if (info.bits <= 32) {
456 const x = @intCast(u32, typed_value.val.toUnsignedInt());459 const x = @intCast(u32, typed_value.val.toUnsignedInt(target));
457 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);460 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
458 } else {461 } else {
459 const x = typed_value.val.toUnsignedInt();462 const x = typed_value.val.toUnsignedInt(target);
460 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);463 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
461 }464 }
462 },465 },
...@@ -482,7 +485,7 @@ pub fn generateSymbol(...@@ -482,7 +485,7 @@ pub fn generateSymbol(
482485
483 const info = typed_value.ty.intInfo(target);486 const info = typed_value.ty.intInfo(target);
484 if (info.bits <= 8) {487 if (info.bits <= 8) {
485 const x = @intCast(u8, int_val.toUnsignedInt());488 const x = @intCast(u8, int_val.toUnsignedInt(target));
486 try code.append(x);489 try code.append(x);
487 return Result{ .appended = {} };490 return Result{ .appended = {} };
488 }491 }
...@@ -492,20 +495,20 @@ pub fn generateSymbol(...@@ -492,20 +495,20 @@ pub fn generateSymbol(
492 bin_file.allocator,495 bin_file.allocator,
493 src_loc,496 src_loc,
494 "TODO implement generateSymbol for big int enums ('{}')",497 "TODO implement generateSymbol for big int enums ('{}')",
495 .{typed_value.ty},498 .{typed_value.ty.fmtDebug()},
496 ),499 ),
497 };500 };
498 }501 }
499 switch (info.signedness) {502 switch (info.signedness) {
500 .unsigned => {503 .unsigned => {
501 if (info.bits <= 16) {504 if (info.bits <= 16) {
502 const x = @intCast(u16, int_val.toUnsignedInt());505 const x = @intCast(u16, int_val.toUnsignedInt(target));
503 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);506 mem.writeInt(u16, try code.addManyAsArray(2), x, endian);
504 } else if (info.bits <= 32) {507 } else if (info.bits <= 32) {
505 const x = @intCast(u32, int_val.toUnsignedInt());508 const x = @intCast(u32, int_val.toUnsignedInt(target));
506 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);509 mem.writeInt(u32, try code.addManyAsArray(4), x, endian);
507 } else {510 } else {
508 const x = int_val.toUnsignedInt();511 const x = int_val.toUnsignedInt(target);
509 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);512 mem.writeInt(u64, try code.addManyAsArray(8), x, endian);
510 }513 }
511 },514 },
...@@ -597,7 +600,7 @@ pub fn generateSymbol(...@@ -597,7 +600,7 @@ pub fn generateSymbol(
597 }600 }
598601
599 const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data;602 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).?;
601 assert(union_ty.haveFieldTypes());604 assert(union_ty.haveFieldTypes());
602 const field_ty = union_ty.fields.values()[field_index].ty;605 const field_ty = union_ty.fields.values()[field_index].ty;
603 if (!field_ty.hasRuntimeBits()) {606 if (!field_ty.hasRuntimeBits()) {
...@@ -787,6 +790,7 @@ fn lowerDeclRef(...@@ -787,6 +790,7 @@ fn lowerDeclRef(
787 debug_output: DebugInfoOutput,790 debug_output: DebugInfoOutput,
788 reloc_info: RelocInfo,791 reloc_info: RelocInfo,
789) GenerateSymbolError!Result {792) GenerateSymbolError!Result {
793 const target = bin_file.options.target;
790 if (typed_value.ty.isSlice()) {794 if (typed_value.ty.isSlice()) {
791 // generate ptr795 // generate ptr
792 var buf: Type.SlicePtrFieldTypeBuffer = undefined;796 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
...@@ -805,7 +809,7 @@ fn lowerDeclRef(...@@ -805,7 +809,7 @@ fn lowerDeclRef(
805 // generate length809 // generate length
806 var slice_len: Value.Payload.U64 = .{810 var slice_len: Value.Payload.U64 = .{
807 .base = .{ .tag = .int_u64 },811 .base = .{ .tag = .int_u64 },
808 .data = typed_value.val.sliceLen(),812 .data = typed_value.val.sliceLen(target),
809 };813 };
810 switch (try generateSymbol(bin_file, src_loc, .{814 switch (try generateSymbol(bin_file, src_loc, .{
811 .ty = Type.usize,815 .ty = Type.usize,
...@@ -821,7 +825,6 @@ fn lowerDeclRef(...@@ -821,7 +825,6 @@ fn lowerDeclRef(
821 return Result{ .appended = {} };825 return Result{ .appended = {} };
822 }826 }
823827
824 const target = bin_file.options.target;
825 const ptr_width = target.cpu.arch.ptrBitWidth();828 const ptr_width = target.cpu.arch.ptrBitWidth();
826 const is_fn_body = decl.ty.zigTypeTag() == .Fn;829 const is_fn_body = decl.ty.zigTypeTag() == .Fn;
827 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {830 if (!is_fn_body and !decl.ty.hasRuntimeBits()) {
src/codegen/c.zig+36-21
...@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(...@@ -56,8 +56,14 @@ pub const TypedefMap = std.ArrayHashMap(
56 true,56 true,
57);57);
5858
59const FormatTypeAsCIdentContext = struct {
60 ty: Type,
61 target: std.Target,
62};
63
64/// TODO make this not cut off at 128 bytes
59fn formatTypeAsCIdentifier(65fn formatTypeAsCIdentifier(
60 data: Type,66 data: FormatTypeAsCIdentContext,
61 comptime fmt: []const u8,67 comptime fmt: []const u8,
62 options: std.fmt.FormatOptions,68 options: std.fmt.FormatOptions,
63 writer: anytype,69 writer: anytype,
...@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(...@@ -65,13 +71,15 @@ fn formatTypeAsCIdentifier(
65 _ = fmt;71 _ = fmt;
66 _ = options;72 _ = options;
67 var buffer = [1]u8{0} ** 128;73 var buffer = [1]u8{0} ** 128;
68 // We don't care if it gets cut off, it's still more unique than a number74 var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.target)}) catch &buffer;
69 var buf = std.fmt.bufPrint(&buffer, "{}", .{data}) catch &buffer;
70 return formatIdent(buf, "", .{}, writer);75 return formatIdent(buf, "", .{}, writer);
71}76}
7277
73pub fn typeToCIdentifier(t: Type) std.fmt.Formatter(formatTypeAsCIdentifier) {78pub fn typeToCIdentifier(ty: Type, target: std.Target) std.fmt.Formatter(formatTypeAsCIdentifier) {
74 return .{ .data = t };79 return .{ .data = .{
80 .ty = ty,
81 .target = target,
82 } };
75}83}
7684
77const reserved_idents = std.ComptimeStringMap(void, .{85const reserved_idents = std.ComptimeStringMap(void, .{
...@@ -369,6 +377,8 @@ pub const DeclGen = struct {...@@ -369,6 +377,8 @@ pub const DeclGen = struct {
369 ) error{ OutOfMemory, AnalysisFail }!void {377 ) error{ OutOfMemory, AnalysisFail }!void {
370 decl.markAlive();378 decl.markAlive();
371379
380 const target = dg.module.getTarget();
381
372 if (ty.isSlice()) {382 if (ty.isSlice()) {
373 try writer.writeByte('(');383 try writer.writeByte('(');
374 try dg.renderTypecast(writer, ty);384 try dg.renderTypecast(writer, ty);
...@@ -376,7 +386,7 @@ pub const DeclGen = struct {...@@ -376,7 +386,7 @@ pub const DeclGen = struct {
376 var buf: Type.SlicePtrFieldTypeBuffer = undefined;386 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
377 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());387 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr());
378 try writer.writeAll(", ");388 try writer.writeAll(", ");
379 try writer.print("{d}", .{val.sliceLen()});389 try writer.print("{d}", .{val.sliceLen(target)});
380 try writer.writeAll("}");390 try writer.writeAll("}");
381 return;391 return;
382 }392 }
...@@ -388,7 +398,7 @@ pub const DeclGen = struct {...@@ -388,7 +398,7 @@ pub const DeclGen = struct {
388 // somewhere and we should let the C compiler tell us about it.398 // somewhere and we should let the C compiler tell us about it.
389 if (ty.castPtrToFn() == null) {399 if (ty.castPtrToFn() == null) {
390 // Determine if we must pointer cast.400 // Determine if we must pointer cast.
391 if (ty.eql(decl.ty)) {401 if (ty.eql(decl.ty, target)) {
392 try writer.writeByte('&');402 try writer.writeByte('&');
393 try dg.renderDeclName(writer, decl);403 try dg.renderDeclName(writer, decl);
394 return;404 return;
...@@ -508,6 +518,7 @@ pub const DeclGen = struct {...@@ -508,6 +518,7 @@ pub const DeclGen = struct {
508 ty: Type,518 ty: Type,
509 val: Value,519 val: Value,
510 ) error{ OutOfMemory, AnalysisFail }!void {520 ) error{ OutOfMemory, AnalysisFail }!void {
521 const target = dg.module.getTarget();
511 if (val.isUndefDeep()) {522 if (val.isUndefDeep()) {
512 switch (ty.zigTypeTag()) {523 switch (ty.zigTypeTag()) {
513 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)524 // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
...@@ -551,7 +562,7 @@ pub const DeclGen = struct {...@@ -551,7 +562,7 @@ pub const DeclGen = struct {
551 else => {562 else => {
552 if (ty.isSignedInt())563 if (ty.isSignedInt())
553 return writer.print("{d}", .{val.toSignedInt()});564 return writer.print("{d}", .{val.toSignedInt()});
554 return writer.print("{d}u", .{val.toUnsignedInt()});565 return writer.print("{d}u", .{val.toUnsignedInt(target)});
555 },566 },
556 },567 },
557 .Float => {568 .Float => {
...@@ -609,7 +620,7 @@ pub const DeclGen = struct {...@@ -609,7 +620,7 @@ pub const DeclGen = struct {
609 .int_u64, .one => {620 .int_u64, .one => {
610 try writer.writeAll("((");621 try writer.writeAll("((");
611 try dg.renderTypecast(writer, ty);622 try dg.renderTypecast(writer, ty);
612 try writer.print(")0x{x}u)", .{val.toUnsignedInt()});623 try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)});
613 },624 },
614 else => unreachable,625 else => unreachable,
615 },626 },
...@@ -653,7 +664,6 @@ pub const DeclGen = struct {...@@ -653,7 +664,6 @@ pub const DeclGen = struct {
653 if (ty.isPtrLikeOptional()) {664 if (ty.isPtrLikeOptional()) {
654 return dg.renderValue(writer, payload_type, val);665 return dg.renderValue(writer, payload_type, val);
655 }666 }
656 const target = dg.module.getTarget();
657 if (payload_type.abiSize(target) == 0) {667 if (payload_type.abiSize(target) == 0) {
658 const is_null = val.castTag(.opt_payload) == null;668 const is_null = val.castTag(.opt_payload) == null;
659 return writer.print("{}", .{is_null});669 return writer.print("{}", .{is_null});
...@@ -773,7 +783,6 @@ pub const DeclGen = struct {...@@ -773,7 +783,6 @@ pub const DeclGen = struct {
773 .Union => {783 .Union => {
774 const union_obj = val.castTag(.@"union").?.data;784 const union_obj = val.castTag(.@"union").?.data;
775 const union_ty = ty.cast(Type.Payload.Union).?.data;785 const union_ty = ty.cast(Type.Payload.Union).?.data;
776 const target = dg.module.getTarget();
777 const layout = ty.unionGetLayout(target);786 const layout = ty.unionGetLayout(target);
778787
779 try writer.writeAll("(");788 try writer.writeAll("(");
...@@ -789,7 +798,7 @@ pub const DeclGen = struct {...@@ -789,7 +798,7 @@ pub const DeclGen = struct {
789 try writer.writeAll(".payload = {");798 try writer.writeAll(".payload = {");
790 }799 }
791800
792 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?;801 const index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag, target).?;
793 const field_ty = ty.unionFields().values()[index].ty;802 const field_ty = ty.unionFields().values()[index].ty;
794 const field_name = ty.unionFields().keys()[index];803 const field_name = ty.unionFields().keys()[index];
795 if (field_ty.hasRuntimeBits()) {804 if (field_ty.hasRuntimeBits()) {
...@@ -879,8 +888,8 @@ pub const DeclGen = struct {...@@ -879,8 +888,8 @@ pub const DeclGen = struct {
879 try bw.writeAll(" (*");888 try bw.writeAll(" (*");
880889
881 const name_start = buffer.items.len;890 const name_start = buffer.items.len;
882 // TODO: typeToCIdentifier truncates to 128 bytes, we probably don't want to do this891 const target = dg.module.getTarget();
883 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t)});892 try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, target)});
884 const name_end = buffer.items.len - 2;893 const name_end = buffer.items.len - 2;
885894
886 const param_len = fn_info.param_types.len;895 const param_len = fn_info.param_types.len;
...@@ -934,10 +943,11 @@ pub const DeclGen = struct {...@@ -934,10 +943,11 @@ pub const DeclGen = struct {
934943
935 try bw.writeAll("; size_t len; } ");944 try bw.writeAll("; size_t len; } ");
936 const name_index = buffer.items.len;945 const name_index = buffer.items.len;
946 const target = dg.module.getTarget();
937 if (t.isConstPtr()) {947 if (t.isConstPtr()) {
938 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)});948 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, target)});
939 } else {949 } else {
940 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)});950 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, target)});
941 }951 }
942 if (ptr_sentinel) |s| {952 if (ptr_sentinel) |s| {
943 try bw.writeAll("_s_");953 try bw.writeAll("_s_");
...@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {...@@ -1023,7 +1033,8 @@ pub const DeclGen = struct {
1023 try buffer.appendSlice("} ");1033 try buffer.appendSlice("} ");
10241034
1025 const name_start = buffer.items.len;1035 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
1028 const rendered = buffer.toOwnedSlice();1039 const rendered = buffer.toOwnedSlice();
1029 errdefer dg.typedefs.allocator.free(rendered);1040 errdefer dg.typedefs.allocator.free(rendered);
...@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {...@@ -1107,6 +1118,7 @@ pub const DeclGen = struct {
1107 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1118 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1108 try bw.writeAll("; uint16_t error; } ");1119 try bw.writeAll("; uint16_t error; } ");
1109 const name_index = buffer.items.len;1120 const name_index = buffer.items.len;
1121 const target = dg.module.getTarget();
1110 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {1122 if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| {
1111 const func = inf_err_set_payload.data.func;1123 const func = inf_err_set_payload.data.func;
1112 try bw.writeAll("zig_E_");1124 try bw.writeAll("zig_E_");
...@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {...@@ -1114,7 +1126,7 @@ pub const DeclGen = struct {
1114 try bw.writeAll(";\n");1126 try bw.writeAll(";\n");
1115 } else {1127 } else {
1116 try bw.print("zig_E_{s}_{s};\n", .{1128 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),
1118 });1130 });
1119 }1131 }
11201132
...@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {...@@ -1144,7 +1156,8 @@ pub const DeclGen = struct {
1144 try dg.renderType(bw, elem_type);1156 try dg.renderType(bw, elem_type);
11451157
1146 const name_start = buffer.items.len + 1;1158 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 });
1148 const name_end = buffer.items.len;1161 const name_end = buffer.items.len;
11491162
1150 try bw.print("[{d}];\n", .{c_len});1163 try bw.print("[{d}];\n", .{c_len});
...@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {...@@ -1172,7 +1185,8 @@ pub const DeclGen = struct {
1172 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);1185 try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0);
1173 try bw.writeAll("; bool is_null; } ");1186 try bw.writeAll("; bool is_null; } ");
1174 const name_index = buffer.items.len;1187 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
1177 const rendered = buffer.toOwnedSlice();1191 const rendered = buffer.toOwnedSlice();
1178 errdefer dg.typedefs.allocator.free(rendered);1192 errdefer dg.typedefs.allocator.free(rendered);
...@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2177,12 +2191,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
2177 if (src_val_is_undefined)2191 if (src_val_is_undefined)
2178 return try airStoreUndefined(f, dest_ptr);2192 return try airStoreUndefined(f, dest_ptr);
21792193
2194 const target = f.object.dg.module.getTarget();
2180 const writer = f.object.writer();2195 const writer = f.object.writer();
2181 if (lhs_child_type.zigTypeTag() == .Array) {2196 if (lhs_child_type.zigTypeTag() == .Array) {
2182 // For this memcpy to safely work we need the rhs to have the same2197 // For this memcpy to safely work we need the rhs to have the same
2183 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).2198 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
2184 const rhs_type = f.air.typeOf(bin_op.rhs);2199 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
2187 // If the source is a constant, writeCValue will emit a brace initialization2202 // If the source is a constant, writeCValue will emit a brace initialization
2188 // so work around this by initializing into new local.2203 // so work around this by initializing into new local.
src/codegen/llvm.zig+54-52
...@@ -812,7 +812,7 @@ pub const Object = struct {...@@ -812,7 +812,7 @@ pub const Object = struct {
812 const gpa = o.gpa;812 const gpa = o.gpa;
813 // Be careful not to reference this `gop` variable after any recursive calls813 // Be careful not to reference this `gop` variable after any recursive calls
814 // to `lowerDebugType`.814 // 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 });
816 if (gop.found_existing) {816 if (gop.found_existing) {
817 const annotated = gop.value_ptr.*;817 const annotated = gop.value_ptr.*;
818 const di_type = annotated.toDIType();818 const di_type = annotated.toDIType();
...@@ -825,7 +825,7 @@ pub const Object = struct {...@@ -825,7 +825,7 @@ pub const Object = struct {
825 };825 };
826 return o.lowerDebugTypeImpl(entry, resolve, di_type);826 return o.lowerDebugTypeImpl(entry, resolve, di_type);
827 }827 }
828 errdefer assert(o.di_type_map.orderedRemove(ty));828 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .target = o.target }));
829 // The Type memory is ephemeral; since we want to store a longer-lived829 // The Type memory is ephemeral; since we want to store a longer-lived
830 // reference, we need to copy it here.830 // reference, we need to copy it here.
831 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());831 gop.key_ptr.* = try ty.copy(o.type_map_arena.allocator());
...@@ -856,7 +856,7 @@ pub const Object = struct {...@@ -856,7 +856,7 @@ pub const Object = struct {
856 .Int => {856 .Int => {
857 const info = ty.intInfo(target);857 const info = ty.intInfo(target);
858 assert(info.bits != 0);858 assert(info.bits != 0);
859 const name = try ty.nameAlloc(gpa);859 const name = try ty.nameAlloc(gpa, target);
860 defer gpa.free(name);860 defer gpa.free(name);
861 const dwarf_encoding: c_uint = switch (info.signedness) {861 const dwarf_encoding: c_uint = switch (info.signedness) {
862 .signed => DW.ATE.signed,862 .signed => DW.ATE.signed,
...@@ -873,7 +873,7 @@ pub const Object = struct {...@@ -873,7 +873,7 @@ pub const Object = struct {
873 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);873 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl);
874 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`874 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
875 // means we can't use `gop` anymore.875 // 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 });
877 return enum_di_ty;877 return enum_di_ty;
878 }878 }
879879
...@@ -903,7 +903,7 @@ pub const Object = struct {...@@ -903,7 +903,7 @@ pub const Object = struct {
903 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);903 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
904 const di_scope = try o.namespaceToDebugScope(owner_decl.src_namespace);904 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);
907 defer gpa.free(name);907 defer gpa.free(name);
908 var buffer: Type.Payload.Bits = undefined;908 var buffer: Type.Payload.Bits = undefined;
909 const int_ty = ty.intTagType(&buffer);909 const int_ty = ty.intTagType(&buffer);
...@@ -921,12 +921,12 @@ pub const Object = struct {...@@ -921,12 +921,12 @@ pub const Object = struct {
921 "",921 "",
922 );922 );
923 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.923 // 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 });
925 return enum_di_ty;925 return enum_di_ty;
926 },926 },
927 .Float => {927 .Float => {
928 const bits = ty.floatBits(target);928 const bits = ty.floatBits(target);
929 const name = try ty.nameAlloc(gpa);929 const name = try ty.nameAlloc(gpa, target);
930 defer gpa.free(name);930 defer gpa.free(name);
931 const di_type = dib.createBasicType(name, bits, DW.ATE.float);931 const di_type = dib.createBasicType(name, bits, DW.ATE.float);
932 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);932 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
...@@ -974,7 +974,7 @@ pub const Object = struct {...@@ -974,7 +974,7 @@ pub const Object = struct {
974 const bland_ptr_ty = Type.initPayload(&payload.base);974 const bland_ptr_ty = Type.initPayload(&payload.base);
975 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);975 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
976 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.976 // 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 });
978 return ptr_di_ty;978 return ptr_di_ty;
979 }979 }
980980
...@@ -983,7 +983,7 @@ pub const Object = struct {...@@ -983,7 +983,7 @@ pub const Object = struct {
983 const ptr_ty = ty.slicePtrFieldType(&buf);983 const ptr_ty = ty.slicePtrFieldType(&buf);
984 const len_ty = Type.usize;984 const len_ty = Type.usize;
985985
986 const name = try ty.nameAlloc(gpa);986 const name = try ty.nameAlloc(gpa, target);
987 defer gpa.free(name);987 defer gpa.free(name);
988 const di_file: ?*llvm.DIFile = null;988 const di_file: ?*llvm.DIFile = null;
989 const line = 0;989 const line = 0;
...@@ -1054,12 +1054,12 @@ pub const Object = struct {...@@ -1054,12 +1054,12 @@ pub const Object = struct {
1054 );1054 );
1055 dib.replaceTemporary(fwd_decl, full_di_ty);1055 dib.replaceTemporary(fwd_decl, full_di_ty);
1056 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1056 // 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 });
1058 return full_di_ty;1058 return full_di_ty;
1059 }1059 }
10601060
1061 const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd);1061 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);
1063 defer gpa.free(name);1063 defer gpa.free(name);
1064 const ptr_di_ty = dib.createPointerType(1064 const ptr_di_ty = dib.createPointerType(
1065 elem_di_ty,1065 elem_di_ty,
...@@ -1068,7 +1068,7 @@ pub const Object = struct {...@@ -1068,7 +1068,7 @@ pub const Object = struct {
1068 name,1068 name,
1069 );1069 );
1070 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1070 // 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 });
1072 return ptr_di_ty;1072 return ptr_di_ty;
1073 },1073 },
1074 .Opaque => {1074 .Opaque => {
...@@ -1077,7 +1077,7 @@ pub const Object = struct {...@@ -1077,7 +1077,7 @@ pub const Object = struct {
1077 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);1077 gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
1078 return di_ty;1078 return di_ty;
1079 }1079 }
1080 const name = try ty.nameAlloc(gpa);1080 const name = try ty.nameAlloc(gpa, target);
1081 defer gpa.free(name);1081 defer gpa.free(name);
1082 const owner_decl = ty.getOwnerDecl();1082 const owner_decl = ty.getOwnerDecl();
1083 const opaque_di_ty = dib.createForwardDeclType(1083 const opaque_di_ty = dib.createForwardDeclType(
...@@ -1089,7 +1089,7 @@ pub const Object = struct {...@@ -1089,7 +1089,7 @@ pub const Object = struct {
1089 );1089 );
1090 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`1090 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
1091 // means we can't use `gop` anymore.1091 // 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 });
1093 return opaque_di_ty;1093 return opaque_di_ty;
1094 },1094 },
1095 .Array => {1095 .Array => {
...@@ -1100,7 +1100,7 @@ pub const Object = struct {...@@ -1100,7 +1100,7 @@ pub const Object = struct {
1100 @intCast(c_int, ty.arrayLen()),1100 @intCast(c_int, ty.arrayLen()),
1101 );1101 );
1102 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1102 // 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 });
1104 return array_di_ty;1104 return array_di_ty;
1105 },1105 },
1106 .Vector => {1106 .Vector => {
...@@ -1111,11 +1111,11 @@ pub const Object = struct {...@@ -1111,11 +1111,11 @@ pub const Object = struct {
1111 ty.vectorLen(),1111 ty.vectorLen(),
1112 );1112 );
1113 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1113 // 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 });
1115 return vector_di_ty;1115 return vector_di_ty;
1116 },1116 },
1117 .Optional => {1117 .Optional => {
1118 const name = try ty.nameAlloc(gpa);1118 const name = try ty.nameAlloc(gpa, target);
1119 defer gpa.free(name);1119 defer gpa.free(name);
1120 var buf: Type.Payload.ElemType = undefined;1120 var buf: Type.Payload.ElemType = undefined;
1121 const child_ty = ty.optionalChild(&buf);1121 const child_ty = ty.optionalChild(&buf);
...@@ -1127,7 +1127,7 @@ pub const Object = struct {...@@ -1127,7 +1127,7 @@ pub const Object = struct {
1127 if (ty.isPtrLikeOptional()) {1127 if (ty.isPtrLikeOptional()) {
1128 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);1128 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
1129 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1129 // 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 });
1131 return ptr_di_ty;1131 return ptr_di_ty;
1132 }1132 }
11331133
...@@ -1200,7 +1200,7 @@ pub const Object = struct {...@@ -1200,7 +1200,7 @@ pub const Object = struct {
1200 );1200 );
1201 dib.replaceTemporary(fwd_decl, full_di_ty);1201 dib.replaceTemporary(fwd_decl, full_di_ty);
1202 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1202 // 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 });
1204 return full_di_ty;1204 return full_di_ty;
1205 },1205 },
1206 .ErrorUnion => {1206 .ErrorUnion => {
...@@ -1209,10 +1209,10 @@ pub const Object = struct {...@@ -1209,10 +1209,10 @@ pub const Object = struct {
1209 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {1209 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
1210 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);1210 const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full);
1211 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1211 // 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 });
1213 return err_set_di_ty;1213 return err_set_di_ty;
1214 }1214 }
1215 const name = try ty.nameAlloc(gpa);1215 const name = try ty.nameAlloc(gpa, target);
1216 defer gpa.free(name);1216 defer gpa.free(name);
1217 const di_file: ?*llvm.DIFile = null;1217 const di_file: ?*llvm.DIFile = null;
1218 const line = 0;1218 const line = 0;
...@@ -1282,7 +1282,7 @@ pub const Object = struct {...@@ -1282,7 +1282,7 @@ pub const Object = struct {
1282 );1282 );
1283 dib.replaceTemporary(fwd_decl, full_di_ty);1283 dib.replaceTemporary(fwd_decl, full_di_ty);
1284 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1284 // 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 });
1286 return full_di_ty;1286 return full_di_ty;
1287 },1287 },
1288 .ErrorSet => {1288 .ErrorSet => {
...@@ -1294,7 +1294,7 @@ pub const Object = struct {...@@ -1294,7 +1294,7 @@ pub const Object = struct {
1294 },1294 },
1295 .Struct => {1295 .Struct => {
1296 const compile_unit_scope = o.di_compile_unit.?.toScope();1296 const compile_unit_scope = o.di_compile_unit.?.toScope();
1297 const name = try ty.nameAlloc(gpa);1297 const name = try ty.nameAlloc(gpa, target);
1298 defer gpa.free(name);1298 defer gpa.free(name);
12991299
1300 if (ty.castTag(.@"struct")) |payload| {1300 if (ty.castTag(.@"struct")) |payload| {
...@@ -1381,7 +1381,7 @@ pub const Object = struct {...@@ -1381,7 +1381,7 @@ pub const Object = struct {
1381 );1381 );
1382 dib.replaceTemporary(fwd_decl, full_di_ty);1382 dib.replaceTemporary(fwd_decl, full_di_ty);
1383 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1383 // 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 });
1385 return full_di_ty;1385 return full_di_ty;
1386 }1386 }
13871387
...@@ -1395,7 +1395,7 @@ pub const Object = struct {...@@ -1395,7 +1395,7 @@ pub const Object = struct {
1395 dib.replaceTemporary(fwd_decl, struct_di_ty);1395 dib.replaceTemporary(fwd_decl, struct_di_ty);
1396 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1396 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1397 // means we can't use `gop` anymore.1397 // 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 });
1399 return struct_di_ty;1399 return struct_di_ty;
1400 }1400 }
1401 }1401 }
...@@ -1406,7 +1406,7 @@ pub const Object = struct {...@@ -1406,7 +1406,7 @@ pub const Object = struct {
1406 dib.replaceTemporary(fwd_decl, struct_di_ty);1406 dib.replaceTemporary(fwd_decl, struct_di_ty);
1407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1407 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1408 // means we can't use `gop` anymore.1408 // 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 });
1410 return struct_di_ty;1410 return struct_di_ty;
1411 }1411 }
14121412
...@@ -1461,13 +1461,13 @@ pub const Object = struct {...@@ -1461,13 +1461,13 @@ pub const Object = struct {
1461 );1461 );
1462 dib.replaceTemporary(fwd_decl, full_di_ty);1462 dib.replaceTemporary(fwd_decl, full_di_ty);
1463 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1463 // 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 });
1465 return full_di_ty;1465 return full_di_ty;
1466 },1466 },
1467 .Union => {1467 .Union => {
1468 const owner_decl = ty.getOwnerDecl();1468 const owner_decl = ty.getOwnerDecl();
14691469
1470 const name = try ty.nameAlloc(gpa);1470 const name = try ty.nameAlloc(gpa, target);
1471 defer gpa.free(name);1471 defer gpa.free(name);
14721472
1473 const fwd_decl = opt_fwd_decl orelse blk: {1473 const fwd_decl = opt_fwd_decl orelse blk: {
...@@ -1489,7 +1489,7 @@ pub const Object = struct {...@@ -1489,7 +1489,7 @@ pub const Object = struct {
1489 dib.replaceTemporary(fwd_decl, union_di_ty);1489 dib.replaceTemporary(fwd_decl, union_di_ty);
1490 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`1490 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
1491 // means we can't use `gop` anymore.1491 // 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 });
1493 return union_di_ty;1493 return union_di_ty;
1494 }1494 }
14951495
...@@ -1603,7 +1603,7 @@ pub const Object = struct {...@@ -1603,7 +1603,7 @@ pub const Object = struct {
1603 0,1603 0,
1604 );1604 );
1605 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.1605 // 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 });
1607 return fn_di_ty;1607 return fn_di_ty;
1608 },1608 },
1609 .ComptimeInt => unreachable,1609 .ComptimeInt => unreachable,
...@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {...@@ -1676,7 +1676,9 @@ pub const DeclGen = struct {
1676 const decl = dg.decl;1676 const decl = dg.decl;
1677 assert(decl.has_tv);1677 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
1681 if (decl.val.castTag(.function)) |func_payload| {1683 if (decl.val.castTag(.function)) |func_payload| {
1682 _ = func_payload;1684 _ = func_payload;
...@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {...@@ -1990,7 +1992,7 @@ pub const DeclGen = struct {
1990 },1992 },
1991 .Opaque => switch (t.tag()) {1993 .Opaque => switch (t.tag()) {
1992 .@"opaque" => {1994 .@"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 });
1994 if (gop.found_existing) return gop.value_ptr.*;1996 if (gop.found_existing) return gop.value_ptr.*;
19951997
1996 // The Type memory is ephemeral; since we want to store a longer-lived1998 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {...@@ -2051,7 +2053,7 @@ pub const DeclGen = struct {
2051 return dg.context.intType(16);2053 return dg.context.intType(16);
2052 },2054 },
2053 .Struct => {2055 .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 });
2055 if (gop.found_existing) return gop.value_ptr.*;2057 if (gop.found_existing) return gop.value_ptr.*;
20562058
2057 // The Type memory is ephemeral; since we want to store a longer-lived2059 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {...@@ -2174,7 +2176,7 @@ pub const DeclGen = struct {
2174 return llvm_struct_ty;2176 return llvm_struct_ty;
2175 },2177 },
2176 .Union => {2178 .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 });
2178 if (gop.found_existing) return gop.value_ptr.*;2180 if (gop.found_existing) return gop.value_ptr.*;
21792181
2180 // The Type memory is ephemeral; since we want to store a longer-lived2182 // The Type memory is ephemeral; since we want to store a longer-lived
...@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {...@@ -2289,6 +2291,7 @@ pub const DeclGen = struct {
2289 const llvm_type = try dg.llvmType(tv.ty);2291 const llvm_type = try dg.llvmType(tv.ty);
2290 return llvm_type.getUndef();2292 return llvm_type.getUndef();
2291 }2293 }
2294 const target = dg.module.getTarget();
22922295
2293 switch (tv.ty.zigTypeTag()) {2296 switch (tv.ty.zigTypeTag()) {
2294 .Bool => {2297 .Bool => {
...@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {...@@ -2302,8 +2305,7 @@ pub const DeclGen = struct {
2302 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),2305 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
2303 else => {2306 else => {
2304 var bigint_space: Value.BigIntSpace = undefined;2307 var bigint_space: Value.BigIntSpace = undefined;
2305 const bigint = tv.val.toBigInt(&bigint_space);2308 const bigint = tv.val.toBigInt(&bigint_space, target);
2306 const target = dg.module.getTarget();
2307 const int_info = tv.ty.intInfo(target);2309 const int_info = tv.ty.intInfo(target);
2308 assert(int_info.bits != 0);2310 assert(int_info.bits != 0);
2309 const llvm_type = dg.context.intType(int_info.bits);2311 const llvm_type = dg.context.intType(int_info.bits);
...@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {...@@ -2331,9 +2333,8 @@ pub const DeclGen = struct {
2331 const int_val = tv.enumToInt(&int_buffer);2333 const int_val = tv.enumToInt(&int_buffer);
23322334
2333 var bigint_space: Value.BigIntSpace = undefined;2335 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();
2337 const int_info = tv.ty.intInfo(target);2338 const int_info = tv.ty.intInfo(target);
2338 const llvm_type = dg.context.intType(int_info.bits);2339 const llvm_type = dg.context.intType(int_info.bits);
23392340
...@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {...@@ -2356,7 +2357,6 @@ pub const DeclGen = struct {
2356 },2357 },
2357 .Float => {2358 .Float => {
2358 const llvm_ty = try dg.llvmType(tv.ty);2359 const llvm_ty = try dg.llvmType(tv.ty);
2359 const target = dg.module.getTarget();
2360 switch (tv.ty.floatBits(target)) {2360 switch (tv.ty.floatBits(target)) {
2361 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),2361 16, 32, 64 => return llvm_ty.constReal(tv.val.toFloat(f64)),
2362 80 => {2362 80 => {
...@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {...@@ -2414,7 +2414,7 @@ pub const DeclGen = struct {
2414 },2414 },
2415 .int_u64, .one, .int_big_positive => {2415 .int_u64, .one, .int_big_positive => {
2416 const llvm_usize = try dg.llvmType(Type.usize);2416 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);
2418 return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));2418 return llvm_int.constIntToPtr(try dg.llvmType(tv.ty));
2419 },2419 },
2420 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {2420 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
...@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {...@@ -2424,7 +2424,9 @@ pub const DeclGen = struct {
2424 const llvm_type = try dg.llvmType(tv.ty);2424 const llvm_type = try dg.llvmType(tv.ty);
2425 return llvm_type.constNull();2425 return llvm_type.constNull();
2426 },2426 },
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 }),
2428 },2430 },
2429 .Array => switch (tv.val.tag()) {2431 .Array => switch (tv.val.tag()) {
2430 .bytes => {2432 .bytes => {
...@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {...@@ -2592,7 +2594,6 @@ pub const DeclGen = struct {
2592 const llvm_struct_ty = try dg.llvmType(tv.ty);2594 const llvm_struct_ty = try dg.llvmType(tv.ty);
2593 const field_vals = tv.val.castTag(.aggregate).?.data;2595 const field_vals = tv.val.castTag(.aggregate).?.data;
2594 const gpa = dg.gpa;2596 const gpa = dg.gpa;
2595 const target = dg.module.getTarget();
25962597
2597 if (tv.ty.isTupleOrAnonStruct()) {2598 if (tv.ty.isTupleOrAnonStruct()) {
2598 const tuple = tv.ty.tupleFields();2599 const tuple = tv.ty.tupleFields();
...@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {...@@ -2753,7 +2754,6 @@ pub const DeclGen = struct {
2753 const llvm_union_ty = try dg.llvmType(tv.ty);2754 const llvm_union_ty = try dg.llvmType(tv.ty);
2754 const tag_and_val = tv.val.castTag(.@"union").?.data;2755 const tag_and_val = tv.val.castTag(.@"union").?.data;
27552756
2756 const target = dg.module.getTarget();
2757 const layout = tv.ty.unionGetLayout(target);2757 const layout = tv.ty.unionGetLayout(target);
27582758
2759 if (layout.payload_size == 0) {2759 if (layout.payload_size == 0) {
...@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {...@@ -2763,7 +2763,7 @@ pub const DeclGen = struct {
2763 });2763 });
2764 }2764 }
2765 const union_obj = tv.ty.cast(Type.Payload.Union).?.data;2765 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).?;
2767 assert(union_obj.haveFieldTypes());2767 assert(union_obj.haveFieldTypes());
2768 const field_ty = union_obj.fields.values()[field_index].ty;2768 const field_ty = union_obj.fields.values()[field_index].ty;
2769 const payload = p: {2769 const payload = p: {
...@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {...@@ -2892,7 +2892,7 @@ pub const DeclGen = struct {
28922892
2893 .Frame,2893 .Frame,
2894 .AnyFrame,2894 .AnyFrame,
2895 => return dg.todo("implement const of type '{}'", .{tv.ty}),2895 => return dg.todo("implement const of type '{}'", .{tv.ty.fmtDebug()}),
2896 }2896 }
2897 }2897 }
28982898
...@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {...@@ -2910,7 +2910,8 @@ pub const DeclGen = struct {
2910 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);2910 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
2911 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl);2911 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)) {
2914 return llvm_ptr;2915 return llvm_ptr;
2915 } else {2916 } else {
2916 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));2917 return llvm_ptr.constBitCast((try dg.llvmType(ptr_child_ty)).pointerType(0));
...@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {...@@ -2918,6 +2919,7 @@ pub const DeclGen = struct {
2918 }2919 }
29192920
2920 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {2921 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value {
2922 const target = dg.module.getTarget();
2921 var bitcast_needed: bool = undefined;2923 var bitcast_needed: bool = undefined;
2922 const llvm_ptr = switch (ptr_val.tag()) {2924 const llvm_ptr = switch (ptr_val.tag()) {
2923 .decl_ref_mut => {2925 .decl_ref_mut => {
...@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {...@@ -2951,7 +2953,6 @@ pub const DeclGen = struct {
29512953
2952 const field_index = @intCast(u32, field_ptr.field_index);2954 const field_index = @intCast(u32, field_ptr.field_index);
2953 const llvm_u32 = dg.context.intType(32);2955 const llvm_u32 = dg.context.intType(32);
2954 const target = dg.module.getTarget();
2955 switch (parent_ty.zigTypeTag()) {2956 switch (parent_ty.zigTypeTag()) {
2956 .Union => {2957 .Union => {
2957 bitcast_needed = true;2958 bitcast_needed = true;
...@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {...@@ -2974,7 +2975,7 @@ pub const DeclGen = struct {
2974 },2975 },
2975 .Struct => {2976 .Struct => {
2976 const field_ty = parent_ty.structFieldType(field_index);2977 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
2979 var ty_buf: Type.Payload.Pointer = undefined;2980 var ty_buf: Type.Payload.Pointer = undefined;
2980 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;2981 const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?;
...@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {...@@ -2990,7 +2991,7 @@ pub const DeclGen = struct {
2990 .elem_ptr => blk: {2991 .elem_ptr => blk: {
2991 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2992 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2992 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);2993 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
2995 const llvm_usize = try dg.llvmType(Type.usize);2996 const llvm_usize = try dg.llvmType(Type.usize);
2996 const indices: [1]*const llvm.Value = .{2997 const indices: [1]*const llvm.Value = .{
...@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {...@@ -3004,7 +3005,7 @@ pub const DeclGen = struct {
3004 var buf: Type.Payload.ElemType = undefined;3005 var buf: Type.Payload.ElemType = undefined;
30053006
3006 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);3007 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
3009 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {3010 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or payload_ty.isPtrLikeOptional()) {
3010 // In this case, we represent pointer to optional the same as pointer3011 // In this case, we represent pointer to optional the same as pointer
...@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {...@@ -3024,7 +3025,7 @@ pub const DeclGen = struct {
3024 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);3025 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
30253026
3026 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();3027 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
3029 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3030 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3030 // In this case, we represent pointer to error union the same as pointer3031 // In this case, we represent pointer to error union the same as pointer
...@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {...@@ -3053,12 +3054,13 @@ pub const DeclGen = struct {
3053 tv: TypedValue,3054 tv: TypedValue,
3054 decl: *Module.Decl,3055 decl: *Module.Decl,
3055 ) Error!*const llvm.Value {3056 ) Error!*const llvm.Value {
3057 const target = self.module.getTarget();
3056 if (tv.ty.isSlice()) {3058 if (tv.ty.isSlice()) {
3057 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3059 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3058 const ptr_ty = tv.ty.slicePtrFieldType(&buf);3060 const ptr_ty = tv.ty.slicePtrFieldType(&buf);
3059 var slice_len: Value.Payload.U64 = .{3061 var slice_len: Value.Payload.U64 = .{
3060 .base = .{ .tag = .int_u64 },3062 .base = .{ .tag = .int_u64 },
3061 .data = tv.val.sliceLen(),3063 .data = tv.val.sliceLen(target),
3062 };3064 };
3063 const fields: [2]*const llvm.Value = .{3065 const fields: [2]*const llvm.Value = .{
3064 try self.genTypedValue(.{3066 try self.genTypedValue(.{
src/codegen/spirv.zig+10-8
...@@ -313,7 +313,7 @@ pub const DeclGen = struct {...@@ -313,7 +313,7 @@ pub const DeclGen = struct {
313 // As of yet, there is no vector support in the self-hosted compiler.313 // As of yet, there is no vector support in the self-hosted compiler.
314 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),314 .Vector => self.todo("implement arithmeticTypeInfo for Vector", .{}),
315 // TODO: For which types is this the case?315 // 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()}),
317 };317 };
318 }318 }
319319
...@@ -335,7 +335,7 @@ pub const DeclGen = struct {...@@ -335,7 +335,7 @@ pub const DeclGen = struct {
335 const int_info = ty.intInfo(target);335 const int_info = ty.intInfo(target);
336 const backing_bits = self.backingIntBits(int_info.bits) orelse {336 const backing_bits = self.backingIntBits(int_info.bits) orelse {
337 // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.337 // 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()});
339 };339 };
340340
341 // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any341 // 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 {...@@ -345,7 +345,7 @@ pub const DeclGen = struct {
345345
346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.
347 // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal347 // 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
350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {
351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },
...@@ -388,7 +388,7 @@ pub const DeclGen = struct {...@@ -388,7 +388,7 @@ pub const DeclGen = struct {
388 });388 });
389 },389 },
390 .Void => unreachable,390 .Void => unreachable,
391 else => return self.todo("constant generation of type {}", .{ty}),391 else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}),
392 }392 }
393393
394 return result_id.toRef();394 return result_id.toRef();
...@@ -414,7 +414,7 @@ pub const DeclGen = struct {...@@ -414,7 +414,7 @@ pub const DeclGen = struct {
414 const backing_bits = self.backingIntBits(int_info.bits) orelse {414 const backing_bits = self.backingIntBits(int_info.bits) orelse {
415 // TODO: Integers too big for any native type are represented as "composite integers":415 // TODO: Integers too big for any native type are represented as "composite integers":
416 // An array of largestSupportedIntBits.416 // An array of largestSupportedIntBits.
417 return self.todo("Implement composite int type {}", .{ty});417 return self.todo("Implement composite int type {}", .{ty.fmtDebug()});
418 };418 };
419419
420 const payload = try self.spv.arena.create(SpvType.Payload.Int);420 const payload = try self.spv.arena.create(SpvType.Payload.Int);
...@@ -644,8 +644,10 @@ pub const DeclGen = struct {...@@ -644,8 +644,10 @@ pub const DeclGen = struct {
644 const result_id = self.spv.allocId();644 const result_id = self.spv.allocId();
645 const result_type_id = try self.resolveTypeId(ty);645 const result_type_id = try self.resolveTypeId(ty);
646646
647 assert(self.air.typeOf(bin_op.lhs).eql(ty));647 const target = self.getTarget();
648 assert(self.air.typeOf(bin_op.rhs).eql(ty));648
649 assert(self.air.typeOf(bin_op.lhs).eql(ty, target));
650 assert(self.air.typeOf(bin_op.rhs).eql(ty, target));
649651
650 // Binary operations are generally applicable to both scalar and vector operations652 // Binary operations are generally applicable to both scalar and vector operations
651 // in SPIR-V, but int and float versions of operations require different opcodes.653 // in SPIR-V, but int and float versions of operations require different opcodes.
...@@ -692,7 +694,7 @@ pub const DeclGen = struct {...@@ -692,7 +694,7 @@ pub const DeclGen = struct {
692 const result_id = self.spv.allocId();694 const result_id = self.spv.allocId();
693 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));695 const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
694 const op_ty = self.air.typeOf(bin_op.lhs);696 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
697 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,699 // Comparisons are generally applicable to both scalar and vector operations in SPIR-V,
698 // but int and float versions of operations require different opcodes.700 // but int and float versions of operations require different opcodes.
src/link.zig+2-2
...@@ -457,7 +457,7 @@ pub const File = struct {...@@ -457,7 +457,7 @@ pub const File = struct {
457 /// May be called before or after updateDeclExports but must be called457 /// May be called before or after updateDeclExports but must be called
458 /// after allocateDeclIndexes for any given Decl.458 /// after allocateDeclIndexes for any given Decl.
459 pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) UpdateDeclError!void {459 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() });
461 assert(decl.has_tv);461 assert(decl.has_tv);
462 switch (base.tag) {462 switch (base.tag) {
463 // zig fmt: off463 // zig fmt: off
...@@ -477,7 +477,7 @@ pub const File = struct {...@@ -477,7 +477,7 @@ pub const File = struct {
477 /// after allocateDeclIndexes for any given Decl.477 /// after allocateDeclIndexes for any given Decl.
478 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {478 pub fn updateFunc(base: *File, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) UpdateDeclError!void {
479 log.debug("updateFunc {*} ({s}), type={}", .{479 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(),
481 });481 });
482 switch (base.tag) {482 switch (base.tag) {
483 // zig fmt: off483 // 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...@@ -127,7 +127,7 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes
127 .error_msg = null,127 .error_msg = null,
128 .decl = decl,128 .decl = decl,
129 .fwd_decl = fwd_decl.toManaged(module.gpa),129 .fwd_decl = fwd_decl.toManaged(module.gpa),
130 .typedefs = typedefs.promote(module.gpa),130 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
131 .typedefs_arena = self.arena.allocator(),131 .typedefs_arena = self.arena.allocator(),
132 },132 },
133 .code = code.toManaged(module.gpa),133 .code = code.toManaged(module.gpa),
...@@ -192,7 +192,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -192,7 +192,7 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
192 .error_msg = null,192 .error_msg = null,
193 .decl = decl,193 .decl = decl,
194 .fwd_decl = fwd_decl.toManaged(module.gpa),194 .fwd_decl = fwd_decl.toManaged(module.gpa),
195 .typedefs = typedefs.promote(module.gpa),195 .typedefs = typedefs.promoteContext(module.gpa, .{ .target = module.getTarget() }),
196 .typedefs_arena = self.arena.allocator(),196 .typedefs_arena = self.arena.allocator(),
197 },197 },
198 .code = code.toManaged(module.gpa),198 .code = code.toManaged(module.gpa),
...@@ -366,7 +366,9 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void...@@ -366,7 +366,9 @@ fn flushDecl(self: *C, f: *Flush, decl: *const Module.Decl) FlushDeclError!void
366 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));366 try f.typedefs.ensureUnusedCapacity(gpa, @intCast(u32, decl_block.typedefs.count()));
367 var it = decl_block.typedefs.iterator();367 var it = decl_block.typedefs.iterator();
368 while (it.next()) |new| {368 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 });
370 if (!gop.found_existing) {372 if (!gop.found_existing) {
371 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);373 try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered);
372 }374 }
src/link/Dwarf.zig+15-9
...@@ -200,7 +200,9 @@ pub fn initDeclDebugInfo(self: *Dwarf, decl: *Module.Decl) !DeclDebugBuffers {...@@ -200,7 +200,9 @@ pub fn initDeclDebugInfo(self: *Dwarf, decl: *Module.Decl) !DeclDebugBuffers {
200 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);200 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
201 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4201 dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4
202 if (fn_ret_has_bits) {202 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 });
204 if (!gop.found_existing) {206 if (!gop.found_existing) {
205 gop.value_ptr.* = .{207 gop.value_ptr.* = .{
206 .off = undefined,208 .off = undefined,
...@@ -455,7 +457,9 @@ pub fn commitDeclDebugInfo(...@@ -455,7 +457,9 @@ pub fn commitDeclDebugInfo(
455 var it: usize = 0;457 var it: usize = 0;
456 while (it < dbg_info_type_relocs.count()) : (it += 1) {458 while (it < dbg_info_type_relocs.count()) : (it += 1) {
457 const ty = dbg_info_type_relocs.keys()[it];459 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 }).?;
459 value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);463 value_ptr.off = @intCast(u32, dbg_info_buffer.items.len);
460 try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs);464 try self.addDbgInfoType(dbg_type_arena.allocator(), ty, dbg_info_buffer, dbg_info_type_relocs);
461 }465 }
...@@ -774,7 +778,7 @@ fn addDbgInfoType(...@@ -774,7 +778,7 @@ fn addDbgInfoType(
774 // DW.AT.byte_size, DW.FORM.data1778 // DW.AT.byte_size, DW.FORM.data1
775 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));779 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
776 // DW.AT.name, DW.FORM.string780 // 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)});
778 },782 },
779 .Optional => {783 .Optional => {
780 if (ty.isPtrLikeOptional()) {784 if (ty.isPtrLikeOptional()) {
...@@ -785,7 +789,7 @@ fn addDbgInfoType(...@@ -785,7 +789,7 @@ fn addDbgInfoType(
785 // DW.AT.byte_size, DW.FORM.data1789 // DW.AT.byte_size, DW.FORM.data1
786 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));790 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
787 // DW.AT.name, DW.FORM.string791 // 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)});
789 } else {793 } else {
790 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }794 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
791 var buf = try arena.create(Type.Payload.ElemType);795 var buf = try arena.create(Type.Payload.ElemType);
...@@ -796,7 +800,7 @@ fn addDbgInfoType(...@@ -796,7 +800,7 @@ fn addDbgInfoType(
796 const abi_size = ty.abiSize(target);800 const abi_size = ty.abiSize(target);
797 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);801 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
798 // DW.AT.name, DW.FORM.string802 // 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)});
800 // DW.AT.member804 // DW.AT.member
801 try dbg_info_buffer.ensureUnusedCapacity(7);805 try dbg_info_buffer.ensureUnusedCapacity(7);
802 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);806 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -835,7 +839,7 @@ fn addDbgInfoType(...@@ -835,7 +839,7 @@ fn addDbgInfoType(
835 // DW.AT.byte_size, DW.FORM.sdata839 // DW.AT.byte_size, DW.FORM.sdata
836 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);840 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
837 // DW.AT.name, DW.FORM.string841 // 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)});
839 // DW.AT.member843 // DW.AT.member
840 try dbg_info_buffer.ensureUnusedCapacity(5);844 try dbg_info_buffer.ensureUnusedCapacity(5);
841 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);845 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -882,7 +886,7 @@ fn addDbgInfoType(...@@ -882,7 +886,7 @@ fn addDbgInfoType(
882 const abi_size = ty.abiSize(target);886 const abi_size = ty.abiSize(target);
883 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);887 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
884 // DW.AT.name, DW.FORM.string888 // DW.AT.name, DW.FORM.string
885 const struct_name = try ty.nameAllocArena(arena);889 const struct_name = try ty.nameAllocArena(arena, target);
886 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);890 try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1);
887 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);891 dbg_info_buffer.appendSliceAssumeCapacity(struct_name);
888 dbg_info_buffer.appendAssumeCapacity(0);892 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -915,13 +919,15 @@ fn addDbgInfoType(...@@ -915,13 +919,15 @@ fn addDbgInfoType(
915 try dbg_info_buffer.append(0);919 try dbg_info_buffer.append(0);
916 },920 },
917 else => {921 else => {
918 log.debug("TODO implement .debug_info for type '{}'", .{ty});922 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
919 try dbg_info_buffer.append(abbrev_pad1);923 try dbg_info_buffer.append(abbrev_pad1);
920 },924 },
921 }925 }
922926
923 for (relocs.items) |rel| {927 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 });
925 if (!gop.found_existing) {931 if (!gop.found_existing) {
926 gop.value_ptr.* = .{932 gop.value_ptr.* = .{
927 .off = undefined,933 .off = undefined,
src/link/MachO.zig+10-9
...@@ -3874,7 +3874,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3874,7 +3874,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38743874
3875/// Checks if the value, or any of its embedded values stores a pointer, and thus requires3875/// Checks if the value, or any of its embedded values stores a pointer, and thus requires
3876/// a rebase opcode for the dynamic linker.3876/// a rebase opcode for the dynamic linker.
3877fn needsPointerRebase(ty: Type, val: Value) bool {3877fn needsPointerRebase(ty: Type, val: Value, target: std.Target) bool {
3878 if (ty.zigTypeTag() == .Fn) {3878 if (ty.zigTypeTag() == .Fn) {
3879 return false;3879 return false;
3880 }3880 }
...@@ -3890,7 +3890,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3890,7 +3890,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3890 const elem_ty = ty.childType();3890 const elem_ty = ty.childType();
3891 var elem_value_buf: Value.ElemValueBuffer = undefined;3891 var elem_value_buf: Value.ElemValueBuffer = undefined;
3892 const elem_val = val.elemValueBuffer(0, &elem_value_buf);3892 const elem_val = val.elemValueBuffer(0, &elem_value_buf);
3893 return needsPointerRebase(elem_ty, elem_val);3893 return needsPointerRebase(elem_ty, elem_val, target);
3894 },3894 },
3895 .Struct => {3895 .Struct => {
3896 const fields = ty.structFields().values();3896 const fields = ty.structFields().values();
...@@ -3898,7 +3898,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3898,7 +3898,7 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3898 if (val.castTag(.aggregate)) |payload| {3898 if (val.castTag(.aggregate)) |payload| {
3899 const field_values = payload.data;3899 const field_values = payload.data;
3900 for (field_values) |field_val, i| {3900 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;
3902 } else return false;3902 } else return false;
3903 } else return false;3903 } else return false;
3904 },3904 },
...@@ -3907,18 +3907,18 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3907,18 +3907,18 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
3907 const sub_val = payload.data;3907 const sub_val = payload.data;
3908 var buffer: Type.Payload.ElemType = undefined;3908 var buffer: Type.Payload.ElemType = undefined;
3909 const sub_ty = ty.optionalChild(&buffer);3909 const sub_ty = ty.optionalChild(&buffer);
3910 return needsPointerRebase(sub_ty, sub_val);3910 return needsPointerRebase(sub_ty, sub_val, target);
3911 } else return false;3911 } else return false;
3912 },3912 },
3913 .Union => {3913 .Union => {
3914 const union_obj = val.cast(Value.Payload.Union).?.data;3914 const union_obj = val.cast(Value.Payload.Union).?.data;
3915 const active_field_ty = ty.unionFieldType(union_obj.tag);3915 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
3916 return needsPointerRebase(active_field_ty, union_obj.val);3916 return needsPointerRebase(active_field_ty, union_obj.val, target);
3917 },3917 },
3918 .ErrorUnion => {3918 .ErrorUnion => {
3919 if (val.castTag(.eu_payload)) |payload| {3919 if (val.castTag(.eu_payload)) |payload| {
3920 const payload_ty = ty.errorUnionPayload();3920 const payload_ty = ty.errorUnionPayload();
3921 return needsPointerRebase(payload_ty, payload.data);3921 return needsPointerRebase(payload_ty, payload.data, target);
3922 } else return false;3922 } else return false;
3923 },3923 },
3924 else => return false,3924 else => return false,
...@@ -3927,7 +3927,8 @@ fn needsPointerRebase(ty: Type, val: Value) bool {...@@ -3927,7 +3927,8 @@ fn needsPointerRebase(ty: Type, val: Value) bool {
39273927
3928fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {3928fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type, val: Value) !MatchingSection {
3929 const code = atom.code.items;3929 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);
3931 const align_log_2 = math.log2(alignment);3932 const align_log_2 = math.log2(alignment);
3932 const zig_ty = ty.zigTypeTag();3933 const zig_ty = ty.zigTypeTag();
3933 const mode = self.base.options.optimize_mode;3934 const mode = self.base.options.optimize_mode;
...@@ -3954,7 +3955,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,...@@ -3954,7 +3955,7 @@ fn getMatchingSectionAtom(self: *MachO, atom: *Atom, name: []const u8, ty: Type,
3954 };3955 };
3955 }3956 }
39563957
3957 if (needsPointerRebase(ty, val)) {3958 if (needsPointerRebase(ty, val, target)) {
3958 break :blk (try self.getMatchingSection(.{3959 break :blk (try self.getMatchingSection(.{
3959 .segname = makeStaticString("__DATA_CONST"),3960 .segname = makeStaticString("__DATA_CONST"),
3960 .sectname = makeStaticString("__const"),3961 .sectname = makeStaticString("__const"),
src/print_air.zig+6-6
...@@ -299,12 +299,12 @@ const Writer = struct {...@@ -299,12 +299,12 @@ const Writer = struct {
299299
300 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {300 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
301 const ty = w.air.instructions.items(.data)[inst].ty;301 const ty = w.air.instructions.items(.data)[inst].ty;
302 try s.print("{}", .{ty});302 try s.print("{}", .{ty.fmtDebug()});
303 }303 }
304304
305 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {305 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
306 const ty_op = w.air.instructions.items(.data)[inst].ty_op;306 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()});
308 try w.writeOperand(s, inst, 0, ty_op.operand);308 try w.writeOperand(s, inst, 0, ty_op.operand);
309 }309 }
310310
...@@ -313,7 +313,7 @@ const Writer = struct {...@@ -313,7 +313,7 @@ const Writer = struct {
313 const extra = w.air.extraData(Air.Block, ty_pl.payload);313 const extra = w.air.extraData(Air.Block, ty_pl.payload);
314 const body = w.air.extra[extra.end..][0..extra.data.body_len];314 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()});
317 const old_indent = w.indent;317 const old_indent = w.indent;
318 w.indent += 2;318 w.indent += 2;
319 try w.writeBody(s, body);319 try w.writeBody(s, body);
...@@ -328,7 +328,7 @@ const Writer = struct {...@@ -328,7 +328,7 @@ const Writer = struct {
328 const len = @intCast(usize, vector_ty.arrayLen());328 const len = @intCast(usize, vector_ty.arrayLen());
329 const elements = @bitCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]);329 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()});
332 for (elements) |elem, i| {332 for (elements) |elem, i| {
333 if (i != 0) try s.writeAll(", ");333 if (i != 0) try s.writeAll(", ");
334 try w.writeOperand(s, inst, i, elem);334 try w.writeOperand(s, inst, i, elem);
...@@ -502,7 +502,7 @@ const Writer = struct {...@@ -502,7 +502,7 @@ const Writer = struct {
502 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {502 fn writeConstant(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
503 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;503 const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
504 const val = w.air.values[ty_pl.payload];504 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() });
506 }506 }
507507
508 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {508 fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
...@@ -514,7 +514,7 @@ const Writer = struct {...@@ -514,7 +514,7 @@ const Writer = struct {
514 var op_index: usize = 0;514 var op_index: usize = 0;
515515
516 const ret_ty = w.air.typeOfIndex(inst);516 const ret_ty = w.air.typeOfIndex(inst);
517 try s.print("{}", .{ret_ty});517 try s.print("{}", .{ret_ty.fmtDebug()});
518518
519 if (is_volatile) {519 if (is_volatile) {
520 try s.writeAll(", volatile");520 try s.writeAll(", volatile");
src/type.zig+544-269
...@@ -6,6 +6,7 @@ const Target = std.Target;...@@ -6,6 +6,7 @@ const Target = std.Target;
6const Module = @import("Module.zig");6const Module = @import("Module.zig");
7const log = std.log.scoped(.Type);7const log = std.log.scoped(.Type);
8const target_util = @import("target.zig");8const target_util = @import("target.zig");
9const TypedValue = @import("TypedValue.zig");
910
10const file_struct = @This();11const file_struct = @This();
1112
...@@ -520,7 +521,7 @@ pub const Type = extern union {...@@ -520,7 +521,7 @@ pub const Type = extern union {
520 }521 }
521 }522 }
522523
523 pub fn eql(a: Type, b: Type) bool {524 pub fn eql(a: Type, b: Type, target: Target) bool {
524 // As a shortcut, if the small tags / addresses match, we're done.525 // As a shortcut, if the small tags / addresses match, we're done.
525 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;526 if (a.tag_if_small_enough == b.tag_if_small_enough) return true;
526527
...@@ -636,7 +637,7 @@ pub const Type = extern union {...@@ -636,7 +637,7 @@ pub const Type = extern union {
636 const a_info = a.fnInfo();637 const a_info = a.fnInfo();
637 const b_info = b.fnInfo();638 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))
640 return false;641 return false;
641642
642 if (a_info.cc != b_info.cc)643 if (a_info.cc != b_info.cc)
...@@ -662,7 +663,7 @@ pub const Type = extern union {...@@ -662,7 +663,7 @@ pub const Type = extern union {
662 if (a_param_ty.tag() == .generic_poison) continue;663 if (a_param_ty.tag() == .generic_poison) continue;
663 if (b_param_ty.tag() == .generic_poison) continue;664 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))
666 return false;667 return false;
667 }668 }
668669
...@@ -680,13 +681,13 @@ pub const Type = extern union {...@@ -680,13 +681,13 @@ pub const Type = extern union {
680 if (a.arrayLen() != b.arrayLen())681 if (a.arrayLen() != b.arrayLen())
681 return false;682 return false;
682 const elem_ty = a.elemType();683 const elem_ty = a.elemType();
683 if (!elem_ty.eql(b.elemType()))684 if (!elem_ty.eql(b.elemType(), target))
684 return false;685 return false;
685 const sentinel_a = a.sentinel();686 const sentinel_a = a.sentinel();
686 const sentinel_b = b.sentinel();687 const sentinel_b = b.sentinel();
687 if (sentinel_a) |sa| {688 if (sentinel_a) |sa| {
688 if (sentinel_b) |sb| {689 if (sentinel_b) |sb| {
689 return sa.eql(sb, elem_ty);690 return sa.eql(sb, elem_ty, target);
690 } else {691 } else {
691 return false;692 return false;
692 }693 }
...@@ -717,7 +718,7 @@ pub const Type = extern union {...@@ -717,7 +718,7 @@ pub const Type = extern union {
717718
718 const info_a = a.ptrInfo().data;719 const info_a = a.ptrInfo().data;
719 const info_b = b.ptrInfo().data;720 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))
721 return false;722 return false;
722 if (info_a.@"align" != info_b.@"align")723 if (info_a.@"align" != info_b.@"align")
723 return false;724 return false;
...@@ -740,7 +741,7 @@ pub const Type = extern union {...@@ -740,7 +741,7 @@ pub const Type = extern union {
740 const sentinel_b = info_b.sentinel;741 const sentinel_b = info_b.sentinel;
741 if (sentinel_a) |sa| {742 if (sentinel_a) |sa| {
742 if (sentinel_b) |sb| {743 if (sentinel_b) |sb| {
743 if (!sa.eql(sb, info_a.pointee_type))744 if (!sa.eql(sb, info_a.pointee_type, target))
744 return false;745 return false;
745 } else {746 } else {
746 return false;747 return false;
...@@ -761,7 +762,7 @@ pub const Type = extern union {...@@ -761,7 +762,7 @@ pub const Type = extern union {
761762
762 var buf_a: Payload.ElemType = undefined;763 var buf_a: Payload.ElemType = undefined;
763 var buf_b: Payload.ElemType = undefined;764 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);
765 },766 },
766767
767 .anyerror_void_error_union, .error_union => {768 .anyerror_void_error_union, .error_union => {
...@@ -769,18 +770,18 @@ pub const Type = extern union {...@@ -769,18 +770,18 @@ pub const Type = extern union {
769770
770 const a_set = a.errorUnionSet();771 const a_set = a.errorUnionSet();
771 const b_set = b.errorUnionSet();772 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
774 const a_payload = a.errorUnionPayload();775 const a_payload = a.errorUnionPayload();
775 const b_payload = b.errorUnionPayload();776 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
778 return true;779 return true;
779 },780 },
780781
781 .anyframe_T => {782 .anyframe_T => {
782 if (b.zigTypeTag() != .AnyFrame) return false;783 if (b.zigTypeTag() != .AnyFrame) return false;
783 return a.childType().eql(b.childType());784 return a.childType().eql(b.childType(), target);
784 },785 },
785786
786 .empty_struct => {787 .empty_struct => {
...@@ -803,7 +804,7 @@ pub const Type = extern union {...@@ -803,7 +804,7 @@ pub const Type = extern union {
803804
804 for (a_tuple.types) |a_ty, i| {805 for (a_tuple.types) |a_ty, i| {
805 const b_ty = b_tuple.types[i];806 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;
807 }808 }
808809
809 for (a_tuple.values) |a_val, i| {810 for (a_tuple.values) |a_val, i| {
...@@ -819,7 +820,7 @@ pub const Type = extern union {...@@ -819,7 +820,7 @@ pub const Type = extern union {
819 if (b_val.tag() == .unreachable_value) {820 if (b_val.tag() == .unreachable_value) {
820 return false;821 return false;
821 } else {822 } else {
822 if (!Value.eql(a_val, b_val, ty)) return false;823 if (!Value.eql(a_val, b_val, ty, target)) return false;
823 }824 }
824 }825 }
825 }826 }
...@@ -839,7 +840,7 @@ pub const Type = extern union {...@@ -839,7 +840,7 @@ pub const Type = extern union {
839840
840 for (a_struct_obj.types) |a_ty, i| {841 for (a_struct_obj.types) |a_ty, i| {
841 const b_ty = b_struct_obj.types[i];842 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;
843 }844 }
844845
845 for (a_struct_obj.values) |a_val, i| {846 for (a_struct_obj.values) |a_val, i| {
...@@ -855,7 +856,7 @@ pub const Type = extern union {...@@ -855,7 +856,7 @@ pub const Type = extern union {
855 if (b_val.tag() == .unreachable_value) {856 if (b_val.tag() == .unreachable_value) {
856 return false;857 return false;
857 } else {858 } else {
858 if (!Value.eql(a_val, b_val, ty)) return false;859 if (!Value.eql(a_val, b_val, ty, target)) return false;
859 }860 }
860 }861 }
861 }862 }
...@@ -910,13 +911,13 @@ pub const Type = extern union {...@@ -910,13 +911,13 @@ pub const Type = extern union {
910 }911 }
911 }912 }
912913
913 pub fn hash(self: Type) u64 {914 pub fn hash(self: Type, target: Target) u64 {
914 var hasher = std.hash.Wyhash.init(0);915 var hasher = std.hash.Wyhash.init(0);
915 self.hashWithHasher(&hasher);916 self.hashWithHasher(&hasher, target);
916 return hasher.final();917 return hasher.final();
917 }918 }
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 {
920 switch (ty.tag()) {921 switch (ty.tag()) {
921 .generic_poison => unreachable,922 .generic_poison => unreachable,
922923
...@@ -1035,7 +1036,7 @@ pub const Type = extern union {...@@ -1035,7 +1036,7 @@ pub const Type = extern union {
1035 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);1036 std.hash.autoHash(hasher, std.builtin.TypeId.Fn);
10361037
1037 const fn_info = ty.fnInfo();1038 const fn_info = ty.fnInfo();
1038 hashWithHasher(fn_info.return_type, hasher);1039 hashWithHasher(fn_info.return_type, hasher, target);
1039 std.hash.autoHash(hasher, fn_info.alignment);1040 std.hash.autoHash(hasher, fn_info.alignment);
1040 std.hash.autoHash(hasher, fn_info.cc);1041 std.hash.autoHash(hasher, fn_info.cc);
1041 std.hash.autoHash(hasher, fn_info.is_var_args);1042 std.hash.autoHash(hasher, fn_info.is_var_args);
...@@ -1045,7 +1046,7 @@ pub const Type = extern union {...@@ -1045,7 +1046,7 @@ pub const Type = extern union {
1045 for (fn_info.param_types) |param_ty, i| {1046 for (fn_info.param_types) |param_ty, i| {
1046 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));1047 std.hash.autoHash(hasher, fn_info.paramIsComptime(i));
1047 if (param_ty.tag() == .generic_poison) continue;1048 if (param_ty.tag() == .generic_poison) continue;
1048 hashWithHasher(param_ty, hasher);1049 hashWithHasher(param_ty, hasher, target);
1049 }1050 }
1050 },1051 },
10511052
...@@ -1058,8 +1059,8 @@ pub const Type = extern union {...@@ -1058,8 +1059,8 @@ pub const Type = extern union {
10581059
1059 const elem_ty = ty.elemType();1060 const elem_ty = ty.elemType();
1060 std.hash.autoHash(hasher, ty.arrayLen());1061 std.hash.autoHash(hasher, ty.arrayLen());
1061 hashWithHasher(elem_ty, hasher);1062 hashWithHasher(elem_ty, hasher, target);
1062 hashSentinel(ty.sentinel(), elem_ty, hasher);1063 hashSentinel(ty.sentinel(), elem_ty, hasher, target);
1063 },1064 },
10641065
1065 .vector => {1066 .vector => {
...@@ -1067,7 +1068,7 @@ pub const Type = extern union {...@@ -1067,7 +1068,7 @@ pub const Type = extern union {
10671068
1068 const elem_ty = ty.elemType();1069 const elem_ty = ty.elemType();
1069 std.hash.autoHash(hasher, ty.vectorLen());1070 std.hash.autoHash(hasher, ty.vectorLen());
1070 hashWithHasher(elem_ty, hasher);1071 hashWithHasher(elem_ty, hasher, target);
1071 },1072 },
10721073
1073 .single_const_pointer_to_comptime_int,1074 .single_const_pointer_to_comptime_int,
...@@ -1091,8 +1092,8 @@ pub const Type = extern union {...@@ -1091,8 +1092,8 @@ pub const Type = extern union {
1091 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);1092 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);
10921093
1093 const info = ty.ptrInfo().data;1094 const info = ty.ptrInfo().data;
1094 hashWithHasher(info.pointee_type, hasher);1095 hashWithHasher(info.pointee_type, hasher, target);
1095 hashSentinel(info.sentinel, info.pointee_type, hasher);1096 hashSentinel(info.sentinel, info.pointee_type, hasher, target);
1096 std.hash.autoHash(hasher, info.@"align");1097 std.hash.autoHash(hasher, info.@"align");
1097 std.hash.autoHash(hasher, info.@"addrspace");1098 std.hash.autoHash(hasher, info.@"addrspace");
1098 std.hash.autoHash(hasher, info.bit_offset);1099 std.hash.autoHash(hasher, info.bit_offset);
...@@ -1110,22 +1111,22 @@ pub const Type = extern union {...@@ -1110,22 +1111,22 @@ pub const Type = extern union {
1110 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);1111 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
11111112
1112 var buf: Payload.ElemType = undefined;1113 var buf: Payload.ElemType = undefined;
1113 hashWithHasher(ty.optionalChild(&buf), hasher);1114 hashWithHasher(ty.optionalChild(&buf), hasher, target);
1114 },1115 },
11151116
1116 .anyerror_void_error_union, .error_union => {1117 .anyerror_void_error_union, .error_union => {
1117 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);1118 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
11181119
1119 const set_ty = ty.errorUnionSet();1120 const set_ty = ty.errorUnionSet();
1120 hashWithHasher(set_ty, hasher);1121 hashWithHasher(set_ty, hasher, target);
11211122
1122 const payload_ty = ty.errorUnionPayload();1123 const payload_ty = ty.errorUnionPayload();
1123 hashWithHasher(payload_ty, hasher);1124 hashWithHasher(payload_ty, hasher, target);
1124 },1125 },
11251126
1126 .anyframe_T => {1127 .anyframe_T => {
1127 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);1128 std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);
1128 hashWithHasher(ty.childType(), hasher);1129 hashWithHasher(ty.childType(), hasher, target);
1129 },1130 },
11301131
1131 .empty_struct => {1132 .empty_struct => {
...@@ -1144,10 +1145,10 @@ pub const Type = extern union {...@@ -1144,10 +1145,10 @@ pub const Type = extern union {
1144 std.hash.autoHash(hasher, tuple.types.len);1145 std.hash.autoHash(hasher, tuple.types.len);
11451146
1146 for (tuple.types) |field_ty, i| {1147 for (tuple.types) |field_ty, i| {
1147 hashWithHasher(field_ty, hasher);1148 hashWithHasher(field_ty, hasher, target);
1148 const field_val = tuple.values[i];1149 const field_val = tuple.values[i];
1149 if (field_val.tag() == .unreachable_value) continue;1150 if (field_val.tag() == .unreachable_value) continue;
1150 field_val.hash(field_ty, hasher);1151 field_val.hash(field_ty, hasher, target);
1151 }1152 }
1152 },1153 },
1153 .anon_struct => {1154 .anon_struct => {
...@@ -1159,9 +1160,9 @@ pub const Type = extern union {...@@ -1159,9 +1160,9 @@ pub const Type = extern union {
1159 const field_name = struct_obj.names[i];1160 const field_name = struct_obj.names[i];
1160 const field_val = struct_obj.values[i];1161 const field_val = struct_obj.values[i];
1161 hasher.update(field_name);1162 hasher.update(field_name);
1162 hashWithHasher(field_ty, hasher);1163 hashWithHasher(field_ty, hasher, target);
1163 if (field_val.tag() == .unreachable_value) continue;1164 if (field_val.tag() == .unreachable_value) continue;
1164 field_val.hash(field_ty, hasher);1165 field_val.hash(field_ty, hasher, target);
1165 }1166 }
1166 },1167 },
11671168
...@@ -1209,35 +1210,35 @@ pub const Type = extern union {...@@ -1209,35 +1210,35 @@ pub const Type = extern union {
1209 }1210 }
1210 }1211 }
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 {
1213 if (opt_val) |s| {1214 if (opt_val) |s| {
1214 std.hash.autoHash(hasher, true);1215 std.hash.autoHash(hasher, true);
1215 s.hash(ty, hasher);1216 s.hash(ty, hasher, target);
1216 } else {1217 } else {
1217 std.hash.autoHash(hasher, false);1218 std.hash.autoHash(hasher, false);
1218 }1219 }
1219 }1220 }
12201221
1221 pub const HashContext64 = struct {1222 pub const HashContext64 = struct {
1223 target: Target,
1224
1222 pub fn hash(self: @This(), t: Type) u64 {1225 pub fn hash(self: @This(), t: Type) u64 {
1223 _ = self;1226 return t.hash(self.target);
1224 return t.hash();
1225 }1227 }
1226 pub fn eql(self: @This(), a: Type, b: Type) bool {1228 pub fn eql(self: @This(), a: Type, b: Type) bool {
1227 _ = self;1229 return a.eql(b, self.target);
1228 return a.eql(b);
1229 }1230 }
1230 };1231 };
12311232
1232 pub const HashContext32 = struct {1233 pub const HashContext32 = struct {
1234 target: Target,
1235
1233 pub fn hash(self: @This(), t: Type) u32 {1236 pub fn hash(self: @This(), t: Type) u32 {
1234 _ = self;1237 return @truncate(u32, t.hash(self.target));
1235 return @truncate(u32, t.hash());
1236 }1238 }
1237 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {1239 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {
1238 _ = self;
1239 _ = b_index;1240 _ = b_index;
1240 return a.eql(b);1241 return a.eql(b, self.target);
1241 }1242 }
1242 };1243 };
12431244
...@@ -1404,8 +1405,8 @@ pub const Type = extern union {...@@ -1404,8 +1405,8 @@ pub const Type = extern union {
1404 .function => {1405 .function => {
1405 const payload = self.castTag(.function).?.data;1406 const payload = self.castTag(.function).?.data;
1406 const param_types = try allocator.alloc(Type, payload.param_types.len);1407 const param_types = try allocator.alloc(Type, payload.param_types.len);
1407 for (payload.param_types) |param_type, i| {1408 for (payload.param_types) |param_ty, i| {
1408 param_types[i] = try param_type.copy(allocator);1409 param_types[i] = try param_ty.copy(allocator);
1409 }1410 }
1410 const other_comptime_params = payload.comptime_params[0..payload.param_types.len];1411 const other_comptime_params = payload.comptime_params[0..payload.param_types.len];
1411 const comptime_params = try allocator.dupe(bool, other_comptime_params);1412 const comptime_params = try allocator.dupe(bool, other_comptime_params);
...@@ -1474,14 +1475,51 @@ pub const Type = extern union {...@@ -1474,14 +1475,51 @@ pub const Type = extern union {
1474 return Type{ .ptr_otherwise = &new_payload.base };1475 return Type{ .ptr_otherwise = &new_payload.base };
1475 }1476 }
14761477
1477 pub fn format(1478 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
1479 _ = ty;
1480 _ = unused_fmt_string;
1481 _ = options;
1482 _ = writer;
1483 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
1484 }
1485
1486 pub fn fmt(ty: Type, target: Target) std.fmt.Formatter(format2) {
1487 return .{ .data = .{
1488 .ty = ty,
1489 .target = target,
1490 } };
1491 }
1492
1493 const FormatContext = struct {
1494 ty: Type,
1495 target: Target,
1496 };
1497
1498 fn format2(
1499 ctx: FormatContext,
1500 comptime unused_format_string: []const u8,
1501 options: std.fmt.FormatOptions,
1502 writer: anytype,
1503 ) !void {
1504 comptime assert(unused_format_string.len == 0);
1505 _ = options;
1506 return print(ctx.ty, writer, ctx.target);
1507 }
1508
1509 pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
1510 return .{ .data = ty };
1511 }
1512
1513 /// This is a debug function. In order to print types in a meaningful way
1514 /// we also need access to the target.
1515 pub fn dump(
1478 start_type: Type,1516 start_type: Type,
1479 comptime fmt: []const u8,1517 comptime unused_format_string: []const u8,
1480 options: std.fmt.FormatOptions,1518 options: std.fmt.FormatOptions,
1481 writer: anytype,1519 writer: anytype,
1482 ) @TypeOf(writer).Error!void {1520 ) @TypeOf(writer).Error!void {
1483 _ = options;1521 _ = options;
1484 comptime assert(fmt.len == 0);1522 comptime assert(unused_format_string.len == 0);
1485 var ty = start_type;1523 var ty = start_type;
1486 while (true) {1524 while (true) {
1487 const t = ty.tag();1525 const t = ty.tag();
...@@ -1584,7 +1622,7 @@ pub const Type = extern union {...@@ -1584,7 +1622,7 @@ pub const Type = extern union {
1584 try writer.writeAll("fn(");1622 try writer.writeAll("fn(");
1585 for (payload.param_types) |param_type, i| {1623 for (payload.param_types) |param_type, i| {
1586 if (i != 0) try writer.writeAll(", ");1624 if (i != 0) try writer.writeAll(", ");
1587 try param_type.format("", .{}, writer);1625 try param_type.dump("", .{}, writer);
1588 }1626 }
1589 if (payload.is_var_args) {1627 if (payload.is_var_args) {
1590 if (payload.param_types.len != 0) {1628 if (payload.param_types.len != 0) {
...@@ -1622,7 +1660,7 @@ pub const Type = extern union {...@@ -1622,7 +1660,7 @@ pub const Type = extern union {
1622 .vector => {1660 .vector => {
1623 const payload = ty.castTag(.vector).?.data;1661 const payload = ty.castTag(.vector).?.data;
1624 try writer.print("@Vector({d}, ", .{payload.len});1662 try writer.print("@Vector({d}, ", .{payload.len});
1625 try payload.elem_type.format("", .{}, writer);1663 try payload.elem_type.dump("", .{}, writer);
1626 return writer.writeAll(")");1664 return writer.writeAll(")");
1627 },1665 },
1628 .array => {1666 .array => {
...@@ -1633,7 +1671,10 @@ pub const Type = extern union {...@@ -1633,7 +1671,10 @@ pub const Type = extern union {
1633 },1671 },
1634 .array_sentinel => {1672 .array_sentinel => {
1635 const payload = ty.castTag(.array_sentinel).?.data;1673 const payload = ty.castTag(.array_sentinel).?.data;
1636 try writer.print("[{d}:{}]", .{ payload.len, payload.sentinel.fmtValue(payload.elem_type) });1674 try writer.print("[{d}:{}]", .{
1675 payload.len,
1676 payload.sentinel.fmtDebug(),
1677 });
1637 ty = payload.elem_type;1678 ty = payload.elem_type;
1638 continue;1679 continue;
1639 },1680 },
...@@ -1646,9 +1687,9 @@ pub const Type = extern union {...@@ -1646,9 +1687,9 @@ pub const Type = extern union {
1646 if (val.tag() != .unreachable_value) {1687 if (val.tag() != .unreachable_value) {
1647 try writer.writeAll("comptime ");1688 try writer.writeAll("comptime ");
1648 }1689 }
1649 try field_ty.format("", .{}, writer);1690 try field_ty.dump("", .{}, writer);
1650 if (val.tag() != .unreachable_value) {1691 if (val.tag() != .unreachable_value) {
1651 try writer.print(" = {}", .{val.fmtValue(field_ty)});1692 try writer.print(" = {}", .{val.fmtDebug()});
1652 }1693 }
1653 }1694 }
1654 try writer.writeAll("}");1695 try writer.writeAll("}");
...@@ -1665,9 +1706,9 @@ pub const Type = extern union {...@@ -1665,9 +1706,9 @@ pub const Type = extern union {
1665 }1706 }
1666 try writer.writeAll(anon_struct.names[i]);1707 try writer.writeAll(anon_struct.names[i]);
1667 try writer.writeAll(": ");1708 try writer.writeAll(": ");
1668 try field_ty.format("", .{}, writer);1709 try field_ty.dump("", .{}, writer);
1669 if (val.tag() != .unreachable_value) {1710 if (val.tag() != .unreachable_value) {
1670 try writer.print(" = {}", .{val.fmtValue(field_ty)});1711 try writer.print(" = {}", .{val.fmtDebug()});
1671 }1712 }
1672 }1713 }
1673 try writer.writeAll("}");1714 try writer.writeAll("}");
...@@ -1752,8 +1793,8 @@ pub const Type = extern union {...@@ -1752,8 +1793,8 @@ pub const Type = extern union {
1752 const payload = ty.castTag(.pointer).?.data;1793 const payload = ty.castTag(.pointer).?.data;
1753 if (payload.sentinel) |some| switch (payload.size) {1794 if (payload.sentinel) |some| switch (payload.size) {
1754 .One, .C => unreachable,1795 .One, .C => unreachable,
1755 .Many => try writer.print("[*:{}]", .{some.fmtValue(payload.pointee_type)}),1796 .Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
1756 .Slice => try writer.print("[:{}]", .{some.fmtValue(payload.pointee_type)}),1797 .Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
1757 } else switch (payload.size) {1798 } else switch (payload.size) {
1758 .One => try writer.writeAll("*"),1799 .One => try writer.writeAll("*"),
1759 .Many => try writer.writeAll("[*]"),1800 .Many => try writer.writeAll("[*]"),
...@@ -1780,7 +1821,7 @@ pub const Type = extern union {...@@ -1780,7 +1821,7 @@ pub const Type = extern union {
1780 },1821 },
1781 .error_union => {1822 .error_union => {
1782 const payload = ty.castTag(.error_union).?.data;1823 const payload = ty.castTag(.error_union).?.data;
1783 try payload.error_set.format("", .{}, writer);1824 try payload.error_set.dump("", .{}, writer);
1784 try writer.writeAll("!");1825 try writer.writeAll("!");
1785 ty = payload.payload;1826 ty = payload.payload;
1786 continue;1827 continue;
...@@ -1821,20 +1862,17 @@ pub const Type = extern union {...@@ -1821,20 +1862,17 @@ pub const Type = extern union {
1821 }1862 }
1822 }1863 }
18231864
1824 pub fn nameAllocArena(ty: Type, arena: Allocator) Allocator.Error![:0]const u8 {1865 pub const nameAllocArena = nameAlloc;
1825 return nameAllocAdvanced(ty, arena, true);
1826 }
18271866
1828 pub fn nameAlloc(ty: Type, gpa: Allocator) Allocator.Error![:0]const u8 {1867 pub fn nameAlloc(ty: Type, ally: Allocator, target: Target) Allocator.Error![:0]const u8 {
1829 return nameAllocAdvanced(ty, gpa, false);1868 var buffer = std.ArrayList(u8).init(ally);
1869 defer buffer.deinit();
1870 try ty.print(buffer.writer(), target);
1871 return buffer.toOwnedSliceSentinel(0);
1830 }1872 }
18311873
1832 /// Returns a name suitable for `@typeName`.1874 /// Prints a name suitable for `@typeName`.
1833 pub fn nameAllocAdvanced(1875 pub fn print(ty: Type, writer: anytype, target: Target) @TypeOf(writer).Error!void {
1834 ty: Type,
1835 ally: Allocator,
1836 is_arena: bool,
1837 ) Allocator.Error![:0]const u8 {
1838 const t = ty.tag();1876 const t = ty.tag();
1839 switch (t) {1877 switch (t) {
1840 .inferred_alloc_const => unreachable,1878 .inferred_alloc_const => unreachable,
...@@ -1892,141 +1930,251 @@ pub const Type = extern union {...@@ -1892,141 +1930,251 @@ pub const Type = extern union {
1892 .comptime_int,1930 .comptime_int,
1893 .comptime_float,1931 .comptime_float,
1894 .noreturn,1932 .noreturn,
1895 => return maybeDupe(@tagName(t), ally, is_arena),1933 => try writer.writeAll(@tagName(t)),
18961934
1897 .enum_literal => return maybeDupe("@TypeOf(.enum_literal)", ally, is_arena),1935 .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"),
1898 .@"null" => return maybeDupe("@TypeOf(null)", ally, is_arena),1936 .@"null" => try writer.writeAll("@TypeOf(null)"),
1899 .@"undefined" => return maybeDupe("@TypeOf(undefined)", ally, is_arena),1937 .@"undefined" => try writer.writeAll("@TypeOf(undefined)"),
1900 .empty_struct_literal => return maybeDupe("@TypeOf(.{})", ally, is_arena),1938 .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"),
19011939
1902 .empty_struct => {1940 .empty_struct => {
1903 const namespace = ty.castTag(.empty_struct).?.data;1941 const namespace = ty.castTag(.empty_struct).?.data;
1904 var buffer = std.ArrayList(u8).init(ally);1942 try namespace.renderFullyQualifiedName("", writer);
1905 defer buffer.deinit();
1906 try namespace.renderFullyQualifiedName("", buffer.writer());
1907 return buffer.toOwnedSliceSentinel(0);
1908 },1943 },
19091944
1910 .@"struct" => {1945 .@"struct" => {
1911 const struct_obj = ty.castTag(.@"struct").?.data;1946 const struct_obj = ty.castTag(.@"struct").?.data;
1912 return try struct_obj.owner_decl.getFullyQualifiedName(ally);1947 try struct_obj.owner_decl.renderFullyQualifiedName(writer);
1913 },1948 },
1914 .@"union", .union_tagged => {1949 .@"union", .union_tagged => {
1915 const union_obj = ty.cast(Payload.Union).?.data;1950 const union_obj = ty.cast(Payload.Union).?.data;
1916 return try union_obj.owner_decl.getFullyQualifiedName(ally);1951 try union_obj.owner_decl.renderFullyQualifiedName(writer);
1917 },1952 },
1918 .enum_full, .enum_nonexhaustive => {1953 .enum_full, .enum_nonexhaustive => {
1919 const enum_full = ty.cast(Payload.EnumFull).?.data;1954 const enum_full = ty.cast(Payload.EnumFull).?.data;
1920 return try enum_full.owner_decl.getFullyQualifiedName(ally);1955 try enum_full.owner_decl.renderFullyQualifiedName(writer);
1921 },1956 },
1922 .enum_simple => {1957 .enum_simple => {
1923 const enum_simple = ty.castTag(.enum_simple).?.data;1958 const enum_simple = ty.castTag(.enum_simple).?.data;
1924 return try enum_simple.owner_decl.getFullyQualifiedName(ally);1959 try enum_simple.owner_decl.renderFullyQualifiedName(writer);
1925 },1960 },
1926 .enum_numbered => {1961 .enum_numbered => {
1927 const enum_numbered = ty.castTag(.enum_numbered).?.data;1962 const enum_numbered = ty.castTag(.enum_numbered).?.data;
1928 return try enum_numbered.owner_decl.getFullyQualifiedName(ally);1963 try enum_numbered.owner_decl.renderFullyQualifiedName(writer);
1929 },1964 },
1930 .@"opaque" => {1965 .@"opaque" => {
1931 const opaque_obj = ty.cast(Payload.Opaque).?.data;1966 const opaque_obj = ty.cast(Payload.Opaque).?.data;
1932 return try opaque_obj.owner_decl.getFullyQualifiedName(ally);1967 try opaque_obj.owner_decl.renderFullyQualifiedName(writer);
1933 },1968 },
19341969
1935 .anyerror_void_error_union => return maybeDupe("anyerror!void", ally, is_arena),1970 .anyerror_void_error_union => try writer.writeAll("anyerror!void"),
1936 .const_slice_u8 => return maybeDupe("[]const u8", ally, is_arena),1971 .const_slice_u8 => try writer.writeAll("[]const u8"),
1937 .const_slice_u8_sentinel_0 => return maybeDupe("[:0]const u8", ally, is_arena),1972 .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"),
1938 .fn_noreturn_no_args => return maybeDupe("fn() noreturn", ally, is_arena),1973 .fn_noreturn_no_args => try writer.writeAll("fn() noreturn"),
1939 .fn_void_no_args => return maybeDupe("fn() void", ally, is_arena),1974 .fn_void_no_args => try writer.writeAll("fn() void"),
1940 .fn_naked_noreturn_no_args => return maybeDupe("fn() callconv(.Naked) noreturn", ally, is_arena),1975 .fn_naked_noreturn_no_args => try writer.writeAll("fn() callconv(.Naked) noreturn"),
1941 .fn_ccc_void_no_args => return maybeDupe("fn() callconv(.C) void", ally, is_arena),1976 .fn_ccc_void_no_args => try writer.writeAll("fn() callconv(.C) void"),
1942 .single_const_pointer_to_comptime_int => return maybeDupe("*const comptime_int", ally, is_arena),1977 .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"),
1943 .manyptr_u8 => return maybeDupe("[*]u8", ally, is_arena),1978 .manyptr_u8 => try writer.writeAll("[*]u8"),
1944 .manyptr_const_u8 => return maybeDupe("[*]const u8", ally, is_arena),1979 .manyptr_const_u8 => try writer.writeAll("[*]const u8"),
1945 .manyptr_const_u8_sentinel_0 => return maybeDupe("[*:0]const u8", ally, is_arena),1980 .manyptr_const_u8_sentinel_0 => try writer.writeAll("[*:0]const u8"),
19461981
1947 .error_set_inferred => {1982 .error_set_inferred => {
1948 const func = ty.castTag(.error_set_inferred).?.data.func;1983 const func = ty.castTag(.error_set_inferred).?.data.func;
19491984
1950 var buf = std.ArrayList(u8).init(ally);1985 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
1951 defer buf.deinit();1986 try func.owner_decl.renderFullyQualifiedName(writer);
1952 try buf.appendSlice("@typeInfo(@typeInfo(@TypeOf(");1987 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
1953 try func.owner_decl.renderFullyQualifiedName(buf.writer());
1954 try buf.appendSlice(")).Fn.return_type.?).ErrorUnion.error_set");
1955 return try buf.toOwnedSliceSentinel(0);
1956 },1988 },
19571989
1958 .function => {1990 .function => {
1959 const fn_info = ty.fnInfo();1991 const fn_info = ty.fnInfo();
1960 var buf = std.ArrayList(u8).init(ally);1992 try writer.writeAll("fn(");
1961 defer buf.deinit();1993 for (fn_info.param_types) |param_ty, i| {
1962 try buf.appendSlice("fn(");1994 if (i != 0) try writer.writeAll(", ");
1963 for (fn_info.param_types) |param_type, i| {1995 try print(param_ty, writer, target);
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);
1968 }1996 }
1969 if (fn_info.is_var_args) {1997 if (fn_info.is_var_args) {
1970 if (fn_info.param_types.len != 0) {1998 if (fn_info.param_types.len != 0) {
1971 try buf.appendSlice(", ");1999 try writer.writeAll(", ");
1972 }2000 }
1973 try buf.appendSlice("...");2001 try writer.writeAll("...");
1974 }2002 }
1975 try buf.appendSlice(") ");2003 try writer.writeAll(") ");
1976 if (fn_info.cc != .Unspecified) {2004 if (fn_info.cc != .Unspecified) {
1977 try buf.appendSlice("callconv(.");2005 try writer.writeAll("callconv(.");
1978 try buf.appendSlice(@tagName(fn_info.cc));2006 try writer.writeAll(@tagName(fn_info.cc));
1979 try buf.appendSlice(") ");2007 try writer.writeAll(") ");
1980 }2008 }
1981 if (fn_info.alignment != 0) {2009 if (fn_info.alignment != 0) {
1982 try buf.writer().print("align({d}) ", .{fn_info.alignment});2010 try writer.print("align({d}) ", .{fn_info.alignment});
1983 }2011 }
1984 {2012 try print(fn_info.return_type, writer, target);
1985 const ret_ty_name = try fn_info.return_type.nameAllocAdvanced(ally, is_arena);
1986 defer if (!is_arena) ally.free(ret_ty_name);
1987 try buf.appendSlice(ret_ty_name);
1988 }
1989 return try buf.toOwnedSliceSentinel(0);
1990 },2013 },
19912014
1992 .error_union => {2015 .error_union => {
1993 const error_union = ty.castTag(.error_union).?.data;2016 const error_union = ty.castTag(.error_union).?.data;
2017 try print(error_union.error_set, writer, target);
2018 try writer.writeAll("!");
2019 try print(error_union.payload, writer, target);
2020 },
19942021
1995 var buf = std.ArrayList(u8).init(ally);2022 .array_u8 => {
1996 defer buf.deinit();2023 const len = ty.castTag(.array_u8).?.data;
2024 try writer.print("[{d}]u8", .{len});
2025 },
2026 .array_u8_sentinel_0 => {
2027 const len = ty.castTag(.array_u8_sentinel_0).?.data;
2028 try writer.print("[{d}:0]u8", .{len});
2029 },
2030 .vector => {
2031 const payload = ty.castTag(.vector).?.data;
2032 try writer.print("@Vector({d}, ", .{payload.len});
2033 try print(payload.elem_type, writer, target);
2034 try writer.writeAll(")");
2035 },
2036 .array => {
2037 const payload = ty.castTag(.array).?.data;
2038 try writer.print("[{d}]", .{payload.len});
2039 try print(payload.elem_type, writer, target);
2040 },
2041 .array_sentinel => {
2042 const payload = ty.castTag(.array_sentinel).?.data;
2043 try writer.print("[{d}:{}]", .{
2044 payload.len,
2045 payload.sentinel.fmtValue(payload.elem_type, target),
2046 });
2047 try print(payload.elem_type, writer, target);
2048 },
2049 .tuple => {
2050 const tuple = ty.castTag(.tuple).?.data;
19972051
1998 {2052 try writer.writeAll("tuple{");
1999 const err_set_ty_name = try error_union.error_set.nameAllocAdvanced(ally, is_arena);2053 for (tuple.types) |field_ty, i| {
2000 defer if (!is_arena) ally.free(err_set_ty_name);2054 if (i != 0) try writer.writeAll(", ");
2001 try buf.appendSlice(err_set_ty_name);2055 const val = tuple.values[i];
2056 if (val.tag() != .unreachable_value) {
2057 try writer.writeAll("comptime ");
2058 }
2059 try print(field_ty, writer, target);
2060 if (val.tag() != .unreachable_value) {
2061 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2062 }
2063 }
2064 try writer.writeAll("}");
2065 },
2066 .anon_struct => {
2067 const anon_struct = ty.castTag(.anon_struct).?.data;
2068
2069 try writer.writeAll("struct{");
2070 for (anon_struct.types) |field_ty, i| {
2071 if (i != 0) try writer.writeAll(", ");
2072 const val = anon_struct.values[i];
2073 if (val.tag() != .unreachable_value) {
2074 try writer.writeAll("comptime ");
2075 }
2076 try writer.writeAll(anon_struct.names[i]);
2077 try writer.writeAll(": ");
2078
2079 try print(field_ty, writer, target);
2080
2081 if (val.tag() != .unreachable_value) {
2082 try writer.print(" = {}", .{val.fmtValue(field_ty, target)});
2083 }
2002 }2084 }
2085 try writer.writeAll("}");
2086 },
20032087
2004 try buf.appendSlice("!");2088 .pointer,
2089 .single_const_pointer,
2090 .single_mut_pointer,
2091 .many_const_pointer,
2092 .many_mut_pointer,
2093 .c_const_pointer,
2094 .c_mut_pointer,
2095 .const_slice,
2096 .mut_slice,
2097 => {
2098 const info = ty.ptrInfo().data;
20052099
2006 {2100 if (info.sentinel) |s| switch (info.size) {
2007 const payload_ty_name = try error_union.payload.nameAllocAdvanced(ally, is_arena);2101 .One, .C => unreachable,
2008 defer if (!is_arena) ally.free(payload_ty_name);2102 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, target)}),
2009 try buf.appendSlice(payload_ty_name);2103 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, target)}),
2104 } else switch (info.size) {
2105 .One => try writer.writeAll("*"),
2106 .Many => try writer.writeAll("[*]"),
2107 .C => try writer.writeAll("[*c]"),
2108 .Slice => try writer.writeAll("[]"),
2010 }2109 }
2110 if (info.@"align" != 0 or info.host_size != 0) {
2111 try writer.print("align({d}", .{info.@"align"});
20112112
2012 return try buf.toOwnedSliceSentinel(0);2113 if (info.bit_offset != 0) {
2013 },2114 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
2115 }
2116 try writer.writeAll(") ");
2117 }
2118 if (info.@"addrspace" != .generic) {
2119 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
2120 }
2121 if (!info.mutable) try writer.writeAll("const ");
2122 if (info.@"volatile") try writer.writeAll("volatile ");
2123 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
20142124
2015 else => {2125 try print(info.pointee_type, writer, target);
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);
2021 },2126 },
2022 }
2023 }
20242127
2025 fn maybeDupe(s: [:0]const u8, ally: Allocator, is_arena: bool) Allocator.Error![:0]const u8 {2128 .int_signed => {
2026 if (is_arena) {2129 const bits = ty.castTag(.int_signed).?.data;
2027 return s;2130 return writer.print("i{d}", .{bits});
2028 } else {2131 },
2029 return try ally.dupeZ(u8, s);2132 .int_unsigned => {
2133 const bits = ty.castTag(.int_unsigned).?.data;
2134 return writer.print("u{d}", .{bits});
2135 },
2136 .optional => {
2137 const child_type = ty.castTag(.optional).?.data;
2138 try writer.writeByte('?');
2139 try print(child_type, writer, target);
2140 },
2141 .optional_single_mut_pointer => {
2142 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
2143 try writer.writeAll("?*");
2144 try print(pointee_type, writer, target);
2145 },
2146 .optional_single_const_pointer => {
2147 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
2148 try writer.writeAll("?*const ");
2149 try print(pointee_type, writer, target);
2150 },
2151 .anyframe_T => {
2152 const return_type = ty.castTag(.anyframe_T).?.data;
2153 try writer.print("anyframe->", .{});
2154 try print(return_type, writer, target);
2155 },
2156 .error_set => {
2157 const names = ty.castTag(.error_set).?.data.names.keys();
2158 try writer.writeAll("error{");
2159 for (names) |name, i| {
2160 if (i != 0) try writer.writeByte(',');
2161 try writer.writeAll(name);
2162 }
2163 try writer.writeAll("}");
2164 },
2165 .error_set_single => {
2166 const name = ty.castTag(.error_set_single).?.data;
2167 return writer.print("error{{{s}}}", .{name});
2168 },
2169 .error_set_merged => {
2170 const names = ty.castTag(.error_set_merged).?.data.keys();
2171 try writer.writeAll("error{");
2172 for (names) |name, i| {
2173 if (i != 0) try writer.writeByte(',');
2174 try writer.writeAll(name);
2175 }
2176 try writer.writeAll("}");
2177 },
2030 }2178 }
2031 }2179 }
20322180
...@@ -2102,8 +2250,12 @@ pub const Type = extern union {...@@ -2102,8 +2250,12 @@ pub const Type = extern union {
2102 /// * the type has only one possible value, making its ABI size 0.2250 /// * the type has only one possible value, making its ABI size 0.
2103 /// When `ignore_comptime_only` is true, then types that are comptime only2251 /// When `ignore_comptime_only` is true, then types that are comptime only
2104 /// may return false positives.2252 /// may return false positives.
2105 pub fn hasRuntimeBitsAdvanced(ty: Type, ignore_comptime_only: bool) bool {2253 pub fn hasRuntimeBitsAdvanced(
2106 return switch (ty.tag()) {2254 ty: Type,
2255 ignore_comptime_only: bool,
2256 sema_kit: ?Module.WipAnalysis,
2257 ) Module.CompileError!bool {
2258 switch (ty.tag()) {
2107 .u1,2259 .u1,
2108 .u8,2260 .u8,
2109 .i8,2261 .i8,
...@@ -2157,7 +2309,7 @@ pub const Type = extern union {...@@ -2157,7 +2309,7 @@ pub const Type = extern union {
2157 .@"anyframe",2309 .@"anyframe",
2158 .anyopaque,2310 .anyopaque,
2159 .@"opaque",2311 .@"opaque",
2160 => true,2312 => return true,
21612313
2162 // These are false because they are comptime-only types.2314 // These are false because they are comptime-only types.
2163 .single_const_pointer_to_comptime_int,2315 .single_const_pointer_to_comptime_int,
...@@ -2181,7 +2333,7 @@ pub const Type = extern union {...@@ -2181,7 +2333,7 @@ pub const Type = extern union {
2181 .fn_void_no_args,2333 .fn_void_no_args,
2182 .fn_naked_noreturn_no_args,2334 .fn_naked_noreturn_no_args,
2183 .fn_ccc_void_no_args,2335 .fn_ccc_void_no_args,
2184 => false,2336 => return false,
21852337
2186 // These types have more than one possible value, so the result is the same as2338 // These types have more than one possible value, so the result is the same as
2187 // asking whether they are comptime-only types.2339 // asking whether they are comptime-only types.
...@@ -2198,20 +2350,34 @@ pub const Type = extern union {...@@ -2198,20 +2350,34 @@ pub const Type = extern union {
2198 .const_slice,2350 .const_slice,
2199 .mut_slice,2351 .mut_slice,
2200 .pointer,2352 .pointer,
2201 => if (ignore_comptime_only) true else !comptimeOnly(ty),2353 => {
2354 if (ignore_comptime_only) {
2355 return true;
2356 } else if (sema_kit) |sk| {
2357 return !(try sk.sema.typeRequiresComptime(sk.block, sk.src, ty));
2358 } else {
2359 return !comptimeOnly(ty);
2360 }
2361 },
22022362
2203 .@"struct" => {2363 .@"struct" => {
2204 const struct_obj = ty.castTag(.@"struct").?.data;2364 const struct_obj = ty.castTag(.@"struct").?.data;
2365 if (sema_kit) |sk| {
2366 _ = try sk.sema.typeRequiresComptime(sk.block, sk.src, ty);
2367 }
2205 switch (struct_obj.requires_comptime) {2368 switch (struct_obj.requires_comptime) {
2206 .wip => unreachable,2369 .wip => unreachable,
2207 .yes => return false,2370 .yes => return false,
2208 .no => if (struct_obj.known_non_opv) return true,2371 .no => if (struct_obj.known_non_opv) return true,
2209 .unknown => {},2372 .unknown => {},
2210 }2373 }
2374 if (sema_kit) |sk| {
2375 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2376 }
2211 assert(struct_obj.haveFieldTypes());2377 assert(struct_obj.haveFieldTypes());
2212 for (struct_obj.fields.values()) |value| {2378 for (struct_obj.fields.values()) |value| {
2213 if (value.is_comptime) continue;2379 if (value.is_comptime) continue;
2214 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))2380 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
2215 return true;2381 return true;
2216 } else {2382 } else {
2217 return false;2383 return false;
...@@ -2229,14 +2395,17 @@ pub const Type = extern union {...@@ -2229,14 +2395,17 @@ pub const Type = extern union {
2229 .enum_numbered, .enum_nonexhaustive => {2395 .enum_numbered, .enum_nonexhaustive => {
2230 var buffer: Payload.Bits = undefined;2396 var buffer: Payload.Bits = undefined;
2231 const int_tag_ty = ty.intTagType(&buffer);2397 const int_tag_ty = ty.intTagType(&buffer);
2232 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only);2398 return int_tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit);
2233 },2399 },
22342400
2235 .@"union" => {2401 .@"union" => {
2236 const union_obj = ty.castTag(.@"union").?.data;2402 const union_obj = ty.castTag(.@"union").?.data;
2403 if (sema_kit) |sk| {
2404 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2405 }
2237 assert(union_obj.haveFieldTypes());2406 assert(union_obj.haveFieldTypes());
2238 for (union_obj.fields.values()) |value| {2407 for (union_obj.fields.values()) |value| {
2239 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))2408 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
2240 return true;2409 return true;
2241 } else {2410 } else {
2242 return false;2411 return false;
...@@ -2244,29 +2413,32 @@ pub const Type = extern union {...@@ -2244,29 +2413,32 @@ pub const Type = extern union {
2244 },2413 },
2245 .union_tagged => {2414 .union_tagged => {
2246 const union_obj = ty.castTag(.union_tagged).?.data;2415 const union_obj = ty.castTag(.union_tagged).?.data;
2247 if (union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only)) {2416 if (try union_obj.tag_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) {
2248 return true;2417 return true;
2249 }2418 }
2419 if (sema_kit) |sk| {
2420 _ = try sk.sema.resolveTypeFields(sk.block, sk.src, ty);
2421 }
2250 assert(union_obj.haveFieldTypes());2422 assert(union_obj.haveFieldTypes());
2251 for (union_obj.fields.values()) |value| {2423 for (union_obj.fields.values()) |value| {
2252 if (value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only))2424 if (try value.ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit))
2253 return true;2425 return true;
2254 } else {2426 } else {
2255 return false;2427 return false;
2256 }2428 }
2257 },2429 },
22582430
2259 .array, .vector => ty.arrayLen() != 0 and2431 .array, .vector => return ty.arrayLen() != 0 and
2260 ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only),2432 try ty.elemType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
2261 .array_u8 => ty.arrayLen() != 0,2433 .array_u8 => return ty.arrayLen() != 0,
2262 .array_sentinel => ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only),2434 .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit),
22632435
2264 .int_signed, .int_unsigned => ty.cast(Payload.Bits).?.data != 0,2436 .int_signed, .int_unsigned => return ty.cast(Payload.Bits).?.data != 0,
22652437
2266 .error_union => {2438 .error_union => {
2267 const payload = ty.castTag(.error_union).?.data;2439 const payload = ty.castTag(.error_union).?.data;
2268 return payload.error_set.hasRuntimeBitsAdvanced(ignore_comptime_only) or2440 return (try payload.error_set.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) or
2269 payload.payload.hasRuntimeBitsAdvanced(ignore_comptime_only);2441 (try payload.payload.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit));
2270 },2442 },
22712443
2272 .tuple, .anon_struct => {2444 .tuple, .anon_struct => {
...@@ -2274,7 +2446,7 @@ pub const Type = extern union {...@@ -2274,7 +2446,7 @@ pub const Type = extern union {
2274 for (tuple.types) |field_ty, i| {2446 for (tuple.types) |field_ty, i| {
2275 const val = tuple.values[i];2447 const val = tuple.values[i];
2276 if (val.tag() != .unreachable_value) continue; // comptime field2448 if (val.tag() != .unreachable_value) continue; // comptime field
2277 if (field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only)) return true;2449 if (try field_ty.hasRuntimeBitsAdvanced(ignore_comptime_only, sema_kit)) return true;
2278 }2450 }
2279 return false;2451 return false;
2280 },2452 },
...@@ -2283,7 +2455,7 @@ pub const Type = extern union {...@@ -2283,7 +2455,7 @@ pub const Type = extern union {
2283 .inferred_alloc_mut => unreachable,2455 .inferred_alloc_mut => unreachable,
2284 .var_args_param => unreachable,2456 .var_args_param => unreachable,
2285 .generic_poison => unreachable,2457 .generic_poison => unreachable,
2286 };2458 }
2287 }2459 }
22882460
2289 /// true if and only if the type has a well-defined memory layout2461 /// true if and only if the type has a well-defined memory layout
...@@ -2409,11 +2581,11 @@ pub const Type = extern union {...@@ -2409,11 +2581,11 @@ pub const Type = extern union {
2409 }2581 }
24102582
2411 pub fn hasRuntimeBits(ty: Type) bool {2583 pub fn hasRuntimeBits(ty: Type) bool {
2412 return hasRuntimeBitsAdvanced(ty, false);2584 return hasRuntimeBitsAdvanced(ty, false, null) catch unreachable;
2413 }2585 }
24142586
2415 pub fn hasRuntimeBitsIgnoreComptime(ty: Type) bool {2587 pub fn hasRuntimeBitsIgnoreComptime(ty: Type) bool {
2416 return hasRuntimeBitsAdvanced(ty, true);2588 return hasRuntimeBitsAdvanced(ty, true, null) catch unreachable;
2417 }2589 }
24182590
2419 pub fn isFnOrHasRuntimeBits(ty: Type) bool {2591 pub fn isFnOrHasRuntimeBits(ty: Type) bool {
...@@ -2518,8 +2690,33 @@ pub const Type = extern union {...@@ -2518,8 +2690,33 @@ pub const Type = extern union {
2518 }2690 }
25192691
2520 /// Returns 0 for 0-bit types.2692 /// Returns 0 for 0-bit types.
2521 pub fn abiAlignment(self: Type, target: Target) u32 {2693 pub fn abiAlignment(ty: Type, target: Target) u32 {
2522 return switch (self.tag()) {2694 return ty.abiAlignmentAdvanced(target, .eager).scalar;
2695 }
2696
2697 /// May capture a reference to `ty`.
2698 pub fn lazyAbiAlignment(ty: Type, target: Target, arena: Allocator) !Value {
2699 switch (ty.abiAlignmentAdvanced(target, .{ .lazy = arena })) {
2700 .val => |val| return try val,
2701 .scalar => |x| return Value.Tag.int_u64.create(arena, x),
2702 }
2703 }
2704
2705 /// If you pass `eager` you will get back `scalar` and assert the type is resolved.
2706 /// If you pass `lazy` you may get back `scalar` or `val`.
2707 /// If `val` is returned, a reference to `ty` has been captured.
2708 fn abiAlignmentAdvanced(
2709 ty: Type,
2710 target: Target,
2711 strat: union(enum) {
2712 eager,
2713 lazy: Allocator,
2714 },
2715 ) union(enum) {
2716 scalar: u32,
2717 val: Allocator.Error!Value,
2718 } {
2719 return switch (ty.tag()) {
2523 .u1,2720 .u1,
2524 .u8,2721 .u8,
2525 .i8,2722 .i8,
...@@ -2538,25 +2735,25 @@ pub const Type = extern union {...@@ -2538,25 +2735,25 @@ pub const Type = extern union {
2538 .extern_options,2735 .extern_options,
2539 .@"opaque",2736 .@"opaque",
2540 .anyopaque,2737 .anyopaque,
2541 => return 1,2738 => return .{ .scalar = 1 },
25422739
2543 .fn_noreturn_no_args, // represents machine code; not a pointer2740 .fn_noreturn_no_args, // represents machine code; not a pointer
2544 .fn_void_no_args, // represents machine code; not a pointer2741 .fn_void_no_args, // represents machine code; not a pointer
2545 .fn_naked_noreturn_no_args, // represents machine code; not a pointer2742 .fn_naked_noreturn_no_args, // represents machine code; not a pointer
2546 .fn_ccc_void_no_args, // represents machine code; not a pointer2743 .fn_ccc_void_no_args, // represents machine code; not a pointer
2547 => return target_util.defaultFunctionAlignment(target),2744 => return .{ .scalar = target_util.defaultFunctionAlignment(target) },
25482745
2549 // represents machine code; not a pointer2746 // represents machine code; not a pointer
2550 .function => {2747 .function => {
2551 const alignment = self.castTag(.function).?.data.alignment;2748 const alignment = ty.castTag(.function).?.data.alignment;
2552 if (alignment != 0) return alignment;2749 if (alignment != 0) return .{ .scalar = alignment };
2553 return target_util.defaultFunctionAlignment(target);2750 return .{ .scalar = target_util.defaultFunctionAlignment(target) };
2554 },2751 },
25552752
2556 .i16, .u16 => return 2,2753 .i16, .u16 => return .{ .scalar = 2 },
2557 .i32, .u32 => return 4,2754 .i32, .u32 => return .{ .scalar = 4 },
2558 .i64, .u64 => return 8,2755 .i64, .u64 => return .{ .scalar = 8 },
2559 .u128, .i128 => return 16,2756 .u128, .i128 => return .{ .scalar = 16 },
25602757
2561 .isize,2758 .isize,
2562 .usize,2759 .usize,
...@@ -2579,40 +2776,40 @@ pub const Type = extern union {...@@ -2579,40 +2776,40 @@ pub const Type = extern union {
2579 .manyptr_const_u8_sentinel_0,2776 .manyptr_const_u8_sentinel_0,
2580 .@"anyframe",2777 .@"anyframe",
2581 .anyframe_T,2778 .anyframe_T,
2582 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),2779 => return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
25832780
2584 .c_short => return @divExact(CType.short.sizeInBits(target), 8),2781 .c_short => return .{ .scalar = @divExact(CType.short.sizeInBits(target), 8) },
2585 .c_ushort => return @divExact(CType.ushort.sizeInBits(target), 8),2782 .c_ushort => return .{ .scalar = @divExact(CType.ushort.sizeInBits(target), 8) },
2586 .c_int => return @divExact(CType.int.sizeInBits(target), 8),2783 .c_int => return .{ .scalar = @divExact(CType.int.sizeInBits(target), 8) },
2587 .c_uint => return @divExact(CType.uint.sizeInBits(target), 8),2784 .c_uint => return .{ .scalar = @divExact(CType.uint.sizeInBits(target), 8) },
2588 .c_long => return @divExact(CType.long.sizeInBits(target), 8),2785 .c_long => return .{ .scalar = @divExact(CType.long.sizeInBits(target), 8) },
2589 .c_ulong => return @divExact(CType.ulong.sizeInBits(target), 8),2786 .c_ulong => return .{ .scalar = @divExact(CType.ulong.sizeInBits(target), 8) },
2590 .c_longlong => return @divExact(CType.longlong.sizeInBits(target), 8),2787 .c_longlong => return .{ .scalar = @divExact(CType.longlong.sizeInBits(target), 8) },
2591 .c_ulonglong => return @divExact(CType.ulonglong.sizeInBits(target), 8),2788 .c_ulonglong => return .{ .scalar = @divExact(CType.ulonglong.sizeInBits(target), 8) },
25922789
2593 .f16 => return 2,2790 .f16 => return .{ .scalar = 2 },
2594 .f32 => return 4,2791 .f32 => return .{ .scalar = 4 },
2595 .f64 => return 8,2792 .f64 => return .{ .scalar = 8 },
2596 .f128 => return 16,2793 .f128 => return .{ .scalar = 16 },
25972794
2598 .f80 => switch (target.cpu.arch) {2795 .f80 => switch (target.cpu.arch) {
2599 .i386 => return 4,2796 .i386 => return .{ .scalar = 4 },
2600 .x86_64 => return 16,2797 .x86_64 => return .{ .scalar = 16 },
2601 else => {2798 else => {
2602 var payload: Payload.Bits = .{2799 var payload: Payload.Bits = .{
2603 .base = .{ .tag = .int_unsigned },2800 .base = .{ .tag = .int_unsigned },
2604 .data = 80,2801 .data = 80,
2605 };2802 };
2606 const u80_ty = initPayload(&payload.base);2803 const u80_ty = initPayload(&payload.base);
2607 return abiAlignment(u80_ty, target);2804 return .{ .scalar = abiAlignment(u80_ty, target) };
2608 },2805 },
2609 },2806 },
2610 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {2807 .c_longdouble => switch (CType.longdouble.sizeInBits(target)) {
2611 16 => return abiAlignment(Type.f16, target),2808 16 => return .{ .scalar = abiAlignment(Type.f16, target) },
2612 32 => return abiAlignment(Type.f32, target),2809 32 => return .{ .scalar = abiAlignment(Type.f32, target) },
2613 64 => return abiAlignment(Type.f64, target),2810 64 => return .{ .scalar = abiAlignment(Type.f64, target) },
2614 80 => return abiAlignment(Type.f80, target),2811 80 => return .{ .scalar = abiAlignment(Type.f80, target) },
2615 128 => return abiAlignment(Type.f128, target),2812 128 => return .{ .scalar = abiAlignment(Type.f128, target) },
2616 else => unreachable,2813 else => unreachable,
2617 },2814 },
26182815
...@@ -2622,60 +2819,93 @@ pub const Type = extern union {...@@ -2622,60 +2819,93 @@ pub const Type = extern union {
2622 .anyerror,2819 .anyerror,
2623 .error_set_inferred,2820 .error_set_inferred,
2624 .error_set_merged,2821 .error_set_merged,
2625 => return 2, // TODO revisit this when we have the concept of the error tag type2822 => return .{ .scalar = 2 }, // TODO revisit this when we have the concept of the error tag type
26262823
2627 .array, .array_sentinel => return self.elemType().abiAlignment(target),2824 .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
26282825
2629 // TODO audit this - is there any more complicated logic to determine2826 // TODO audit this - is there any more complicated logic to determine
2630 // ABI alignment of vectors?2827 // ABI alignment of vectors?
2631 .vector => return 16,2828 .vector => return .{ .scalar = 16 },
26322829
2633 .int_signed, .int_unsigned => {2830 .int_signed, .int_unsigned => {
2634 const bits: u16 = self.cast(Payload.Bits).?.data;2831 const bits: u16 = ty.cast(Payload.Bits).?.data;
2635 if (bits == 0) return 0;2832 if (bits == 0) return .{ .scalar = 0 };
2636 if (bits <= 8) return 1;2833 if (bits <= 8) return .{ .scalar = 1 };
2637 if (bits <= 16) return 2;2834 if (bits <= 16) return .{ .scalar = 2 };
2638 if (bits <= 32) return 4;2835 if (bits <= 32) return .{ .scalar = 4 };
2639 if (bits <= 64) return 8;2836 if (bits <= 64) return .{ .scalar = 8 };
2640 return 16;2837 return .{ .scalar = 16 };
2641 },2838 },
26422839
2643 .optional => {2840 .optional => {
2644 var buf: Payload.ElemType = undefined;2841 var buf: Payload.ElemType = undefined;
2645 const child_type = self.optionalChild(&buf);2842 const child_type = ty.optionalChild(&buf);
2646 if (!child_type.hasRuntimeBits()) return 1;
26472843
2648 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr())2844 if (child_type.zigTypeTag() == .Pointer and !child_type.isCPtr()) {
2649 return @divExact(target.cpu.arch.ptrBitWidth(), 8);2845 return .{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
2846 }
26502847
2651 return child_type.abiAlignment(target);2848 switch (strat) {
2849 .eager => {
2850 if (!child_type.hasRuntimeBits()) return .{ .scalar = 1 };
2851 return .{ .scalar = child_type.abiAlignment(target) };
2852 },
2853 .lazy => |arena| switch (child_type.abiAlignmentAdvanced(target, strat)) {
2854 .scalar => |x| return .{ .scalar = @maximum(x, 1) },
2855 .val => return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2856 },
2857 }
2652 },2858 },
26532859
2654 .error_union => {2860 .error_union => {
2655 const data = self.castTag(.error_union).?.data;2861 const data = ty.castTag(.error_union).?.data;
2656 if (!data.error_set.hasRuntimeBits()) {2862 switch (strat) {
2657 return data.payload.abiAlignment(target);2863 .eager => {
2658 } else if (!data.payload.hasRuntimeBits()) {2864 if (!data.error_set.hasRuntimeBits()) {
2659 return data.error_set.abiAlignment(target);2865 return .{ .scalar = data.payload.abiAlignment(target) };
2866 } else if (!data.payload.hasRuntimeBits()) {
2867 return .{ .scalar = data.error_set.abiAlignment(target) };
2868 }
2869 return .{ .scalar = @maximum(
2870 data.payload.abiAlignment(target),
2871 data.error_set.abiAlignment(target),
2872 ) };
2873 },
2874 .lazy => |arena| {
2875 switch (data.payload.abiAlignmentAdvanced(target, strat)) {
2876 .scalar => |payload_align| {
2877 if (payload_align == 0) {
2878 return data.error_set.abiAlignmentAdvanced(target, strat);
2879 }
2880 switch (data.error_set.abiAlignmentAdvanced(target, strat)) {
2881 .scalar => |err_set_align| {
2882 return .{ .scalar = @maximum(payload_align, err_set_align) };
2883 },
2884 .val => {},
2885 }
2886 },
2887 .val => {},
2888 }
2889 return .{ .val = Value.Tag.lazy_align.create(arena, ty) };
2890 },
2660 }2891 }
2661 return @maximum(
2662 data.payload.abiAlignment(target),
2663 data.error_set.abiAlignment(target),
2664 );
2665 },2892 },
26662893
2667 .@"struct" => {2894 .@"struct" => {
2668 const fields = self.structFields();2895 if (ty.castTag(.@"struct")) |payload| {
2669 if (self.castTag(.@"struct")) |payload| {
2670 const struct_obj = payload.data;2896 const struct_obj = payload.data;
2671 assert(struct_obj.haveLayout());2897 if (!struct_obj.haveLayout()) switch (strat) {
2898 .eager => unreachable, // struct layout not resolved
2899 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2900 };
2672 if (struct_obj.layout == .Packed) {2901 if (struct_obj.layout == .Packed) {
2673 var buf: Type.Payload.Bits = undefined;2902 var buf: Type.Payload.Bits = undefined;
2674 const int_ty = struct_obj.packedIntegerType(target, &buf);2903 const int_ty = struct_obj.packedIntegerType(target, &buf);
2675 return int_ty.abiAlignment(target);2904 return .{ .scalar = int_ty.abiAlignment(target) };
2676 }2905 }
2677 }2906 }
26782907
2908 const fields = ty.structFields();
2679 var big_align: u32 = 0;2909 var big_align: u32 = 0;
2680 for (fields.values()) |field| {2910 for (fields.values()) |field| {
2681 if (!field.ty.hasRuntimeBits()) continue;2911 if (!field.ty.hasRuntimeBits()) continue;
...@@ -2683,31 +2913,45 @@ pub const Type = extern union {...@@ -2683,31 +2913,45 @@ pub const Type = extern union {
2683 const field_align = field.normalAlignment(target);2913 const field_align = field.normalAlignment(target);
2684 big_align = @maximum(big_align, field_align);2914 big_align = @maximum(big_align, field_align);
2685 }2915 }
2686 return big_align;2916 return .{ .scalar = big_align };
2687 },2917 },
26882918
2689 .tuple, .anon_struct => {2919 .tuple, .anon_struct => {
2690 const tuple = self.tupleFields();2920 const tuple = ty.tupleFields();
2691 var big_align: u32 = 0;2921 var big_align: u32 = 0;
2692 for (tuple.types) |field_ty, i| {2922 for (tuple.types) |field_ty, i| {
2693 const val = tuple.values[i];2923 const val = tuple.values[i];
2694 if (val.tag() != .unreachable_value) continue; // comptime field2924 if (val.tag() != .unreachable_value) continue; // comptime field
2695 if (!field_ty.hasRuntimeBits()) continue;
26962925
2697 const field_align = field_ty.abiAlignment(target);2926 switch (field_ty.abiAlignmentAdvanced(target, strat)) {
2698 big_align = @maximum(big_align, field_align);2927 .scalar => |field_align| big_align = @maximum(big_align, field_align),
2928 .val => switch (strat) {
2929 .eager => unreachable, // field type alignment not resolved
2930 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2931 },
2932 }
2699 }2933 }
2700 return big_align;2934 return .{ .scalar = big_align };
2701 },2935 },
27022936
2703 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {2937 .enum_full, .enum_nonexhaustive, .enum_simple, .enum_numbered => {
2704 var buffer: Payload.Bits = undefined;2938 var buffer: Payload.Bits = undefined;
2705 const int_tag_ty = self.intTagType(&buffer);2939 const int_tag_ty = ty.intTagType(&buffer);
2706 return int_tag_ty.abiAlignment(target);2940 return .{ .scalar = int_tag_ty.abiAlignment(target) };
2941 },
2942 .@"union" => switch (strat) {
2943 .eager => {
2944 // TODO pass `true` for have_tag when unions have a safety tag
2945 return .{ .scalar = ty.castTag(.@"union").?.data.abiAlignment(target, false) };
2946 },
2947 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2948 },
2949 .union_tagged => switch (strat) {
2950 .eager => {
2951 return .{ .scalar = ty.castTag(.union_tagged).?.data.abiAlignment(target, true) };
2952 },
2953 .lazy => |arena| return .{ .val = Value.Tag.lazy_align.create(arena, ty) },
2707 },2954 },
2708 // TODO pass `true` for have_tag when unions have a safety tag
2709 .@"union" => return self.castTag(.@"union").?.data.abiAlignment(target, false),
2710 .union_tagged => return self.castTag(.union_tagged).?.data.abiAlignment(target, true),
27112955
2712 .empty_struct,2956 .empty_struct,
2713 .void,2957 .void,
...@@ -2719,7 +2963,7 @@ pub const Type = extern union {...@@ -2719,7 +2963,7 @@ pub const Type = extern union {
2719 .@"undefined",2963 .@"undefined",
2720 .enum_literal,2964 .enum_literal,
2721 .type_info,2965 .type_info,
2722 => return 0,2966 => return .{ .scalar = 0 },
27232967
2724 .noreturn,2968 .noreturn,
2725 .inferred_alloc_const,2969 .inferred_alloc_const,
...@@ -3392,10 +3636,7 @@ pub const Type = extern union {...@@ -3392,10 +3636,7 @@ pub const Type = extern union {
33923636
3393 .optional => {3637 .optional => {
3394 const child_ty = self.castTag(.optional).?.data;3638 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;
3397 if (child_ty.zigTypeTag() != .Pointer) return false;3639 if (child_ty.zigTypeTag() != .Pointer) return false;
3398
3399 const info = child_ty.ptrInfo().data;3640 const info = child_ty.ptrInfo().data;
3400 switch (info.size) {3641 switch (info.size) {
3401 .Slice, .C => return false,3642 .Slice, .C => return false,
...@@ -3663,9 +3904,9 @@ pub const Type = extern union {...@@ -3663,9 +3904,9 @@ pub const Type = extern union {
3663 return union_obj.fields;3904 return union_obj.fields;
3664 }3905 }
36653906
3666 pub fn unionFieldType(ty: Type, enum_tag: Value) Type {3907 pub fn unionFieldType(ty: Type, enum_tag: Value, target: Target) Type {
3667 const union_obj = ty.cast(Payload.Union).?.data;3908 const union_obj = ty.cast(Payload.Union).?.data;
3668 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag).?;3909 const index = union_obj.tag_ty.enumTagFieldIndex(enum_tag, target).?;
3669 assert(union_obj.haveFieldTypes());3910 assert(union_obj.haveFieldTypes());
3670 return union_obj.fields.values()[index].ty;3911 return union_obj.fields.values()[index].ty;
3671 }3912 }
...@@ -4330,6 +4571,8 @@ pub const Type = extern union {...@@ -4330,6 +4571,8 @@ pub const Type = extern union {
43304571
4331 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which4572 /// During semantic analysis, instead call `Sema.typeRequiresComptime` which
4332 /// resolves field types rather than asserting they are already resolved.4573 /// resolves field types rather than asserting they are already resolved.
4574 /// TODO merge these implementations together with the "advanced" pattern seen
4575 /// elsewhere in this file.
4333 pub fn comptimeOnly(ty: Type) bool {4576 pub fn comptimeOnly(ty: Type) bool {
4334 return switch (ty.tag()) {4577 return switch (ty.tag()) {
4335 .u1,4578 .u1,
...@@ -4679,20 +4922,20 @@ pub const Type = extern union {...@@ -4679,20 +4922,20 @@ pub const Type = extern union {
4679 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or4922 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
4680 /// an integer which represents the enum value. Returns the field index in4923 /// an integer which represents the enum value. Returns the field index in
4681 /// declaration order, or `null` if `enum_tag` does not match any field.4924 /// declaration order, or `null` if `enum_tag` does not match any field.
4682 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value) ?usize {4925 pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, target: Target) ?usize {
4683 if (enum_tag.castTag(.enum_field_index)) |payload| {4926 if (enum_tag.castTag(.enum_field_index)) |payload| {
4684 return @as(usize, payload.data);4927 return @as(usize, payload.data);
4685 }4928 }
4686 const S = struct {4929 const S = struct {
4687 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize) ?usize {4930 fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, tg: Target) ?usize {
4688 if (int_val.compareWithZero(.lt)) return null;4931 if (int_val.compareWithZero(.lt)) return null;
4689 var end_payload: Value.Payload.U64 = .{4932 var end_payload: Value.Payload.U64 = .{
4690 .base = .{ .tag = .int_u64 },4933 .base = .{ .tag = .int_u64 },
4691 .data = end,4934 .data = end,
4692 };4935 };
4693 const end_val = Value.initPayload(&end_payload.base);4936 const end_val = Value.initPayload(&end_payload.base);
4694 if (int_val.compare(.gte, end_val, int_ty)) return null;4937 if (int_val.compare(.gte, end_val, int_ty, tg)) return null;
4695 return @intCast(usize, int_val.toUnsignedInt());4938 return @intCast(usize, int_val.toUnsignedInt(tg));
4696 }4939 }
4697 };4940 };
4698 switch (ty.tag()) {4941 switch (ty.tag()) {
...@@ -4700,18 +4943,24 @@ pub const Type = extern union {...@@ -4700,18 +4943,24 @@ pub const Type = extern union {
4700 const enum_full = ty.cast(Payload.EnumFull).?.data;4943 const enum_full = ty.cast(Payload.EnumFull).?.data;
4701 const tag_ty = enum_full.tag_ty;4944 const tag_ty = enum_full.tag_ty;
4702 if (enum_full.values.count() == 0) {4945 if (enum_full.values.count() == 0) {
4703 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count());4946 return S.fieldWithRange(tag_ty, enum_tag, enum_full.fields.count(), target);
4704 } else {4947 } else {
4705 return enum_full.values.getIndexContext(enum_tag, .{ .ty = tag_ty });4948 return enum_full.values.getIndexContext(enum_tag, .{
4949 .ty = tag_ty,
4950 .target = target,
4951 });
4706 }4952 }
4707 },4953 },
4708 .enum_numbered => {4954 .enum_numbered => {
4709 const enum_obj = ty.castTag(.enum_numbered).?.data;4955 const enum_obj = ty.castTag(.enum_numbered).?.data;
4710 const tag_ty = enum_obj.tag_ty;4956 const tag_ty = enum_obj.tag_ty;
4711 if (enum_obj.values.count() == 0) {4957 if (enum_obj.values.count() == 0) {
4712 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count());4958 return S.fieldWithRange(tag_ty, enum_tag, enum_obj.fields.count(), target);
4713 } else {4959 } else {
4714 return enum_obj.values.getIndexContext(enum_tag, .{ .ty = tag_ty });4960 return enum_obj.values.getIndexContext(enum_tag, .{
4961 .ty = tag_ty,
4962 .target = target,
4963 });
4715 }4964 }
4716 },4965 },
4717 .enum_simple => {4966 .enum_simple => {
...@@ -4723,7 +4972,7 @@ pub const Type = extern union {...@@ -4723,7 +4972,7 @@ pub const Type = extern union {
4723 .data = bits,4972 .data = bits,
4724 };4973 };
4725 const tag_ty = Type.initPayload(&buffer.base);4974 const tag_ty = Type.initPayload(&buffer.base);
4726 return S.fieldWithRange(tag_ty, enum_tag, fields_len);4975 return S.fieldWithRange(tag_ty, enum_tag, fields_len, target);
4727 },4976 },
4728 .atomic_order,4977 .atomic_order,
4729 .atomic_rmw_op,4978 .atomic_rmw_op,
...@@ -5018,14 +5267,14 @@ pub const Type = extern union {...@@ -5018,14 +5267,14 @@ pub const Type = extern union {
5018 /// Asserts the type is an enum.5267 /// Asserts the type is an enum.
5019 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {5268 pub fn enumHasInt(ty: Type, int: Value, target: Target) bool {
5020 const S = struct {5269 const S = struct {
5021 fn intInRange(tag_ty: Type, int_val: Value, end: usize) bool {5270 fn intInRange(tag_ty: Type, int_val: Value, end: usize, tg: Target) bool {
5022 if (int_val.compareWithZero(.lt)) return false;5271 if (int_val.compareWithZero(.lt)) return false;
5023 var end_payload: Value.Payload.U64 = .{5272 var end_payload: Value.Payload.U64 = .{
5024 .base = .{ .tag = .int_u64 },5273 .base = .{ .tag = .int_u64 },
5025 .data = end,5274 .data = end,
5026 };5275 };
5027 const end_val = Value.initPayload(&end_payload.base);5276 const end_val = Value.initPayload(&end_payload.base);
5028 if (int_val.compare(.gte, end_val, tag_ty)) return false;5277 if (int_val.compare(.gte, end_val, tag_ty, tg)) return false;
5029 return true;5278 return true;
5030 }5279 }
5031 };5280 };
...@@ -5035,18 +5284,24 @@ pub const Type = extern union {...@@ -5035,18 +5284,24 @@ pub const Type = extern union {
5035 const enum_full = ty.castTag(.enum_full).?.data;5284 const enum_full = ty.castTag(.enum_full).?.data;
5036 const tag_ty = enum_full.tag_ty;5285 const tag_ty = enum_full.tag_ty;
5037 if (enum_full.values.count() == 0) {5286 if (enum_full.values.count() == 0) {
5038 return S.intInRange(tag_ty, int, enum_full.fields.count());5287 return S.intInRange(tag_ty, int, enum_full.fields.count(), target);
5039 } else {5288 } else {
5040 return enum_full.values.containsContext(int, .{ .ty = tag_ty });5289 return enum_full.values.containsContext(int, .{
5290 .ty = tag_ty,
5291 .target = target,
5292 });
5041 }5293 }
5042 },5294 },
5043 .enum_numbered => {5295 .enum_numbered => {
5044 const enum_obj = ty.castTag(.enum_numbered).?.data;5296 const enum_obj = ty.castTag(.enum_numbered).?.data;
5045 const tag_ty = enum_obj.tag_ty;5297 const tag_ty = enum_obj.tag_ty;
5046 if (enum_obj.values.count() == 0) {5298 if (enum_obj.values.count() == 0) {
5047 return S.intInRange(tag_ty, int, enum_obj.fields.count());5299 return S.intInRange(tag_ty, int, enum_obj.fields.count(), target);
5048 } else {5300 } else {
5049 return enum_obj.values.containsContext(int, .{ .ty = tag_ty });5301 return enum_obj.values.containsContext(int, .{
5302 .ty = tag_ty,
5303 .target = target,
5304 });
5050 }5305 }
5051 },5306 },
5052 .enum_simple => {5307 .enum_simple => {
...@@ -5058,7 +5313,7 @@ pub const Type = extern union {...@@ -5058,7 +5313,7 @@ pub const Type = extern union {
5058 .data = bits,5313 .data = bits,
5059 };5314 };
5060 const tag_ty = Type.initPayload(&buffer.base);5315 const tag_ty = Type.initPayload(&buffer.base);
5061 return S.intInRange(tag_ty, int, fields_len);5316 return S.intInRange(tag_ty, int, fields_len, target);
5062 },5317 },
5063 .atomic_order,5318 .atomic_order,
5064 .atomic_rmw_op,5319 .atomic_rmw_op,
...@@ -5070,7 +5325,7 @@ pub const Type = extern union {...@@ -5070,7 +5325,7 @@ pub const Type = extern union {
5070 .prefetch_options,5325 .prefetch_options,
5071 .export_options,5326 .export_options,
5072 .extern_options,5327 .extern_options,
5073 => @panic("TODO resolve std.builtin types"),5328 => unreachable,
50745329
5075 else => unreachable,5330 else => unreachable,
5076 }5331 }
...@@ -5620,7 +5875,7 @@ pub const Type = extern union {...@@ -5620,7 +5875,7 @@ pub const Type = extern union {
5620 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")5875 d.bit_offset == 0 and d.host_size == 0 and !d.@"allowzero" and !d.@"volatile")
5621 {5876 {
5622 if (d.sentinel) |sent| {5877 if (d.sentinel) |sent| {
5623 if (!d.mutable and d.pointee_type.eql(Type.u8)) {5878 if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
5624 switch (d.size) {5879 switch (d.size) {
5625 .Slice => {5880 .Slice => {
5626 if (sent.compareWithZero(.eq)) {5881 if (sent.compareWithZero(.eq)) {
...@@ -5635,7 +5890,7 @@ pub const Type = extern union {...@@ -5635,7 +5890,7 @@ pub const Type = extern union {
5635 else => {},5890 else => {},
5636 }5891 }
5637 }5892 }
5638 } else if (!d.mutable and d.pointee_type.eql(Type.u8)) {5893 } else if (!d.mutable and d.pointee_type.eql(Type.u8, target)) {
5639 switch (d.size) {5894 switch (d.size) {
5640 .Slice => return Type.initTag(.const_slice_u8),5895 .Slice => return Type.initTag(.const_slice_u8),
5641 .Many => return Type.initTag(.manyptr_const_u8),5896 .Many => return Type.initTag(.manyptr_const_u8),
...@@ -5669,10 +5924,11 @@ pub const Type = extern union {...@@ -5669,10 +5924,11 @@ pub const Type = extern union {
5669 len: u64,5924 len: u64,
5670 sent: ?Value,5925 sent: ?Value,
5671 elem_type: Type,5926 elem_type: Type,
5927 target: Target,
5672 ) Allocator.Error!Type {5928 ) Allocator.Error!Type {
5673 if (elem_type.eql(Type.u8)) {5929 if (elem_type.eql(Type.u8, target)) {
5674 if (sent) |some| {5930 if (sent) |some| {
5675 if (some.eql(Value.zero, elem_type)) {5931 if (some.eql(Value.zero, elem_type, target)) {
5676 return Tag.array_u8_sentinel_0.create(arena, len);5932 return Tag.array_u8_sentinel_0.create(arena, len);
5677 }5933 }
5678 } else {5934 } else {
...@@ -5715,6 +5971,25 @@ pub const Type = extern union {...@@ -5715,6 +5971,25 @@ pub const Type = extern union {
5715 }5971 }
5716 }5972 }
57175973
5974 pub fn errorUnion(
5975 arena: Allocator,
5976 error_set: Type,
5977 payload: Type,
5978 target: Target,
5979 ) Allocator.Error!Type {
5980 assert(error_set.zigTypeTag() == .ErrorSet);
5981 if (error_set.eql(Type.@"anyerror", target) and
5982 payload.eql(Type.void, target))
5983 {
5984 return Type.initTag(.anyerror_void_error_union);
5985 }
5986
5987 return Type.Tag.error_union.create(arena, .{
5988 .error_set = error_set,
5989 .payload = payload,
5990 });
5991 }
5992
5718 pub fn smallestUnsignedBits(max: u64) u16 {5993 pub fn smallestUnsignedBits(max: u64) u16 {
5719 if (max == 0) return 0;5994 if (max == 0) return 0;
5720 const base = std.math.log2(max);5995 const base = std.math.log2(max);
src/value.zig+307-208
...@@ -8,6 +8,8 @@ const Target = std.Target;...@@ -8,6 +8,8 @@ const Target = std.Target;
8const Allocator = std.mem.Allocator;8const Allocator = std.mem.Allocator;
9const Module = @import("Module.zig");9const Module = @import("Module.zig");
10const Air = @import("Air.zig");10const Air = @import("Air.zig");
11const TypedValue = @import("TypedValue.zig");
12const Sema = @import("Sema.zig");
1113
12/// This is the raw data, with no bookkeeping, no memory awareness,14/// This is the raw data, with no bookkeeping, no memory awareness,
13/// no de-duplication, and no type system awareness.15/// no de-duplication, and no type system awareness.
...@@ -175,6 +177,8 @@ pub const Value = extern union {...@@ -175,6 +177,8 @@ pub const Value = extern union {
175 /// and refers directly to the air. It will never be referenced by the air itself.177 /// and refers directly to the air. It will never be referenced by the air itself.
176 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.178 /// TODO: This is probably a bad encoding, maybe put temp data in the sema instead.
177 bound_fn,179 bound_fn,
180 /// The ABI alignment of the payload type.
181 lazy_align,
178182
179 pub const last_no_payload_tag = Tag.empty_array;183 pub const last_no_payload_tag = Tag.empty_array;
180 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;184 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
...@@ -283,7 +287,10 @@ pub const Value = extern union {...@@ -283,7 +287,10 @@ pub const Value = extern union {
283287
284 .enum_field_index => Payload.U32,288 .enum_field_index => Payload.U32,
285289
286 .ty => Payload.Ty,290 .ty,
291 .lazy_align,
292 => Payload.Ty,
293
287 .int_type => Payload.IntType,294 .int_type => Payload.IntType,
288 .int_u64 => Payload.U64,295 .int_u64 => Payload.U64,
289 .int_i64 => Payload.I64,296 .int_i64 => Payload.I64,
...@@ -453,7 +460,7 @@ pub const Value = extern union {...@@ -453,7 +460,7 @@ pub const Value = extern union {
453 .bound_fn,460 .bound_fn,
454 => unreachable,461 => unreachable,
455462
456 .ty => {463 .ty, .lazy_align => {
457 const payload = self.castTag(.ty).?;464 const payload = self.castTag(.ty).?;
458 const new_payload = try arena.create(Payload.Ty);465 const new_payload = try arena.create(Payload.Ty);
459 new_payload.* = .{466 new_payload.* = .{
...@@ -608,7 +615,7 @@ pub const Value = extern union {...@@ -608,7 +615,7 @@ pub const Value = extern union {
608 @compileError("do not use format values directly; use either fmtDebug or fmtValue");615 @compileError("do not use format values directly; use either fmtDebug or fmtValue");
609 }616 }
610617
611 /// TODO this should become a debug dump() function. In order to print values in a meaningful way618 /// This is a debug function. In order to print values in a meaningful way
612 /// we also need access to the type.619 /// we also need access to the type.
613 pub fn dump(620 pub fn dump(
614 start_val: Value,621 start_val: Value,
...@@ -699,7 +706,12 @@ pub const Value = extern union {...@@ -699,7 +706,12 @@ pub const Value = extern union {
699 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),706 .the_only_possible_value => return out_stream.writeAll("(the only possible value)"),
700 .bool_true => return out_stream.writeAll("true"),707 .bool_true => return out_stream.writeAll("true"),
701 .bool_false => return out_stream.writeAll("false"),708 .bool_false => return out_stream.writeAll("false"),
702 .ty => return val.castTag(.ty).?.data.format("", options, out_stream),709 .ty => return val.castTag(.ty).?.data.dump("", options, out_stream),
710 .lazy_align => {
711 try out_stream.writeAll("@alignOf(");
712 try val.castTag(.lazy_align).?.data.dump("", options, out_stream);
713 try out_stream.writeAll(")");
714 },
703 .int_type => {715 .int_type => {
704 const int_type = val.castTag(.int_type).?.data;716 const int_type = val.castTag(.int_type).?.data;
705 return out_stream.print("{s}{d}", .{717 return out_stream.print("{s}{d}", .{
...@@ -778,15 +790,16 @@ pub const Value = extern union {...@@ -778,15 +790,16 @@ pub const Value = extern union {
778 return .{ .data = val };790 return .{ .data = val };
779 }791 }
780792
781 const TypedValue = @import("TypedValue.zig");793 pub fn fmtValue(val: Value, ty: Type, target: Target) std.fmt.Formatter(TypedValue.format) {
782794 return .{ .data = .{
783 pub fn fmtValue(val: Value, ty: Type) std.fmt.Formatter(TypedValue.format) {795 .tv = .{ .ty = ty, .val = val },
784 return .{ .data = .{ .ty = ty, .val = val } };796 .target = target,
797 } };
785 }798 }
786799
787 /// Asserts that the value is representable as an array of bytes.800 /// Asserts that the value is representable as an array of bytes.
788 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.801 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
789 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator) ![]u8 {802 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, target: Target) ![]u8 {
790 switch (val.tag()) {803 switch (val.tag()) {
791 .bytes => {804 .bytes => {
792 const bytes = val.castTag(.bytes).?.data;805 const bytes = val.castTag(.bytes).?.data;
...@@ -796,7 +809,7 @@ pub const Value = extern union {...@@ -796,7 +809,7 @@ pub const Value = extern union {
796 },809 },
797 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),810 .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data),
798 .repeated => {811 .repeated => {
799 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt());812 const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(target));
800 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));813 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen()));
801 std.mem.set(u8, result, byte);814 std.mem.set(u8, result, byte);
802 return result;815 return result;
...@@ -804,23 +817,23 @@ pub const Value = extern union {...@@ -804,23 +817,23 @@ pub const Value = extern union {
804 .decl_ref => {817 .decl_ref => {
805 const decl = val.castTag(.decl_ref).?.data;818 const decl = val.castTag(.decl_ref).?.data;
806 const decl_val = try decl.value();819 const decl_val = try decl.value();
807 return decl_val.toAllocatedBytes(decl.ty, allocator);820 return decl_val.toAllocatedBytes(decl.ty, allocator, target);
808 },821 },
809 .the_only_possible_value => return &[_]u8{},822 .the_only_possible_value => return &[_]u8{},
810 .slice => {823 .slice => {
811 const slice = val.castTag(.slice).?.data;824 const slice = val.castTag(.slice).?.data;
812 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(), allocator);825 return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(target), allocator, target);
813 },826 },
814 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator),827 else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, target),
815 }828 }
816 }829 }
817830
818 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator) ![]u8 {831 fn arrayToAllocatedBytes(val: Value, len: u64, allocator: Allocator, target: Target) ![]u8 {
819 const result = try allocator.alloc(u8, @intCast(usize, len));832 const result = try allocator.alloc(u8, @intCast(usize, len));
820 var elem_value_buf: ElemValueBuffer = undefined;833 var elem_value_buf: ElemValueBuffer = undefined;
821 for (result) |*elem, i| {834 for (result) |*elem, i| {
822 const elem_val = val.elemValueBuffer(i, &elem_value_buf);835 const elem_val = val.elemValueBuffer(i, &elem_value_buf);
823 elem.* = @intCast(u8, elem_val.toUnsignedInt());836 elem.* = @intCast(u8, elem_val.toUnsignedInt(target));
824 }837 }
825 return result;838 return result;
826 }839 }
...@@ -977,8 +990,18 @@ pub const Value = extern union {...@@ -977,8 +990,18 @@ pub const Value = extern union {
977 }990 }
978991
979 /// Asserts the value is an integer.992 /// Asserts the value is an integer.
980 pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {993 pub fn toBigInt(val: Value, space: *BigIntSpace, target: Target) BigIntConst {
981 switch (self.tag()) {994 return val.toBigIntAdvanced(space, target, null) catch unreachable;
995 }
996
997 /// Asserts the value is an integer.
998 pub fn toBigIntAdvanced(
999 val: Value,
1000 space: *BigIntSpace,
1001 target: Target,
1002 sema_kit: ?Module.WipAnalysis,
1003 ) !BigIntConst {
1004 switch (val.tag()) {
982 .zero,1005 .zero,
983 .bool_false,1006 .bool_false,
984 .the_only_possible_value, // i0, u01007 .the_only_possible_value, // i0, u0
...@@ -988,19 +1011,35 @@ pub const Value = extern union {...@@ -988,19 +1011,35 @@ pub const Value = extern union {
988 .bool_true,1011 .bool_true,
989 => return BigIntMutable.init(&space.limbs, 1).toConst(),1012 => return BigIntMutable.init(&space.limbs, 1).toConst(),
9901013
991 .int_u64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_u64).?.data).toConst(),1014 .int_u64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_u64).?.data).toConst(),
992 .int_i64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_i64).?.data).toConst(),1015 .int_i64 => return BigIntMutable.init(&space.limbs, val.castTag(.int_i64).?.data).toConst(),
993 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt(),1016 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(),
994 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt(),1017 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(),
9951018
996 .undef => unreachable,1019 .undef => unreachable,
1020
1021 .lazy_align => {
1022 const ty = val.castTag(.lazy_align).?.data;
1023 if (sema_kit) |sk| {
1024 try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
1025 }
1026 const x = ty.abiAlignment(target);
1027 return BigIntMutable.init(&space.limbs, x).toConst();
1028 },
1029
997 else => unreachable,1030 else => unreachable,
998 }1031 }
999 }1032 }
10001033
1001 /// If the value fits in a u64, return it, otherwise null.1034 /// If the value fits in a u64, return it, otherwise null.
1002 /// Asserts not undefined.1035 /// Asserts not undefined.
1003 pub fn getUnsignedInt(val: Value) ?u64 {1036 pub fn getUnsignedInt(val: Value, target: Target) ?u64 {
1037 return getUnsignedIntAdvanced(val, target, null) catch unreachable;
1038 }
1039
1040 /// If the value fits in a u64, return it, otherwise null.
1041 /// Asserts not undefined.
1042 pub fn getUnsignedIntAdvanced(val: Value, target: Target, sema_kit: ?Module.WipAnalysis) !?u64 {
1004 switch (val.tag()) {1043 switch (val.tag()) {
1005 .zero,1044 .zero,
1006 .bool_false,1045 .bool_false,
...@@ -1017,13 +1056,22 @@ pub const Value = extern union {...@@ -1017,13 +1056,22 @@ pub const Value = extern union {
1017 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,1056 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null,
10181057
1019 .undef => unreachable,1058 .undef => unreachable,
1059
1060 .lazy_align => {
1061 const ty = val.castTag(.lazy_align).?.data;
1062 if (sema_kit) |sk| {
1063 try sk.sema.resolveTypeLayout(sk.block, sk.src, ty);
1064 }
1065 return ty.abiAlignment(target);
1066 },
1067
1020 else => return null,1068 else => return null,
1021 }1069 }
1022 }1070 }
10231071
1024 /// Asserts the value is an integer and it fits in a u641072 /// Asserts the value is an integer and it fits in a u64
1025 pub fn toUnsignedInt(val: Value) u64 {1073 pub fn toUnsignedInt(val: Value, target: Target) u64 {
1026 return getUnsignedInt(val).?;1074 return getUnsignedInt(val, target).?;
1027 }1075 }
10281076
1029 /// Asserts the value is an integer and it fits in a i641077 /// Asserts the value is an integer and it fits in a i64
...@@ -1066,7 +1114,7 @@ pub const Value = extern union {...@@ -1066,7 +1114,7 @@ pub const Value = extern union {
1066 switch (ty.zigTypeTag()) {1114 switch (ty.zigTypeTag()) {
1067 .Int => {1115 .Int => {
1068 var bigint_buffer: BigIntSpace = undefined;1116 var bigint_buffer: BigIntSpace = undefined;
1069 const bigint = val.toBigInt(&bigint_buffer);1117 const bigint = val.toBigInt(&bigint_buffer, target);
1070 const bits = ty.intInfo(target).bits;1118 const bits = ty.intInfo(target).bits;
1071 const abi_size = @intCast(usize, ty.abiSize(target));1119 const abi_size = @intCast(usize, ty.abiSize(target));
1072 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());1120 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
...@@ -1075,7 +1123,7 @@ pub const Value = extern union {...@@ -1075,7 +1123,7 @@ pub const Value = extern union {
1075 var enum_buffer: Payload.U64 = undefined;1123 var enum_buffer: Payload.U64 = undefined;
1076 const int_val = val.enumToInt(ty, &enum_buffer);1124 const int_val = val.enumToInt(ty, &enum_buffer);
1077 var bigint_buffer: BigIntSpace = undefined;1125 var bigint_buffer: BigIntSpace = undefined;
1078 const bigint = int_val.toBigInt(&bigint_buffer);1126 const bigint = int_val.toBigInt(&bigint_buffer, target);
1079 const bits = ty.intInfo(target).bits;1127 const bits = ty.intInfo(target).bits;
1080 const abi_size = @intCast(usize, ty.abiSize(target));1128 const abi_size = @intCast(usize, ty.abiSize(target));
1081 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());1129 bigint.writeTwosComplement(buffer, bits, abi_size, target.cpu.arch.endian());
...@@ -1151,7 +1199,7 @@ pub const Value = extern union {...@@ -1151,7 +1199,7 @@ pub const Value = extern union {
1151 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),1199 128 => bitcastFloatToBigInt(f128, val.toFloat(f128), &field_buf),
1152 else => unreachable,1200 else => unreachable,
1153 },1201 },
1154 .Int, .Bool => field_val.toBigInt(&field_space),1202 .Int, .Bool => field_val.toBigInt(&field_space, target),
1155 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),1203 .Struct => packedStructToInt(field_val, field.ty, target, &field_buf),
1156 else => unreachable,1204 else => unreachable,
1157 };1205 };
...@@ -1511,7 +1559,7 @@ pub const Value = extern union {...@@ -1511,7 +1559,7 @@ pub const Value = extern union {
1511 const info = ty.intInfo(target);1559 const info = ty.intInfo(target);
15121560
1513 var buffer: Value.BigIntSpace = undefined;1561 var buffer: Value.BigIntSpace = undefined;
1514 const operand_bigint = val.toBigInt(&buffer);1562 const operand_bigint = val.toBigInt(&buffer, target);
15151563
1516 var limbs_buffer: [4]std.math.big.Limb = undefined;1564 var limbs_buffer: [4]std.math.big.Limb = undefined;
1517 var result_bigint = BigIntMutable{1565 var result_bigint = BigIntMutable{
...@@ -1532,7 +1580,7 @@ pub const Value = extern union {...@@ -1532,7 +1580,7 @@ pub const Value = extern union {
1532 const info = ty.intInfo(target);1580 const info = ty.intInfo(target);
15331581
1534 var buffer: Value.BigIntSpace = undefined;1582 var buffer: Value.BigIntSpace = undefined;
1535 const operand_bigint = val.toBigInt(&buffer);1583 const operand_bigint = val.toBigInt(&buffer, target);
15361584
1537 const limbs = try arena.alloc(1585 const limbs = try arena.alloc(
1538 std.math.big.Limb,1586 std.math.big.Limb,
...@@ -1553,7 +1601,7 @@ pub const Value = extern union {...@@ -1553,7 +1601,7 @@ pub const Value = extern union {
1553 assert(info.bits % 8 == 0);1601 assert(info.bits % 8 == 0);
15541602
1555 var buffer: Value.BigIntSpace = undefined;1603 var buffer: Value.BigIntSpace = undefined;
1556 const operand_bigint = val.toBigInt(&buffer);1604 const operand_bigint = val.toBigInt(&buffer, target);
15571605
1558 const limbs = try arena.alloc(1606 const limbs = try arena.alloc(
1559 std.math.big.Limb,1607 std.math.big.Limb,
...@@ -1597,7 +1645,7 @@ pub const Value = extern union {...@@ -1597,7 +1645,7 @@ pub const Value = extern union {
15971645
1598 else => {1646 else => {
1599 var buffer: BigIntSpace = undefined;1647 var buffer: BigIntSpace = undefined;
1600 return self.toBigInt(&buffer).bitCountTwosComp();1648 return self.toBigInt(&buffer, target).bitCountTwosComp();
1601 },1649 },
1602 }1650 }
1603 }1651 }
...@@ -1624,6 +1672,17 @@ pub const Value = extern union {...@@ -1624,6 +1672,17 @@ pub const Value = extern union {
1624 else => unreachable,1672 else => unreachable,
1625 },1673 },
16261674
1675 .lazy_align => {
1676 const info = ty.intInfo(target);
1677 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
1678 // If it is u16 or bigger we know the alignment fits without resolving it.
1679 if (info.bits >= max_needed_bits) return true;
1680 const x = self.castTag(.lazy_align).?.data.abiAlignment(target);
1681 if (x == 0) return true;
1682 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
1683 return info.bits >= actual_needed_bits;
1684 },
1685
1627 .int_u64 => switch (ty.zigTypeTag()) {1686 .int_u64 => switch (ty.zigTypeTag()) {
1628 .Int => {1687 .Int => {
1629 const x = self.castTag(.int_u64).?.data;1688 const x = self.castTag(.int_u64).?.data;
...@@ -1643,7 +1702,7 @@ pub const Value = extern union {...@@ -1643,7 +1702,7 @@ pub const Value = extern union {
1643 if (info.signedness == .unsigned and x < 0)1702 if (info.signedness == .unsigned and x < 0)
1644 return false;1703 return false;
1645 var buffer: BigIntSpace = undefined;1704 var buffer: BigIntSpace = undefined;
1646 return self.toBigInt(&buffer).fitsInTwosComp(info.signedness, info.bits);1705 return self.toBigInt(&buffer, target).fitsInTwosComp(info.signedness, info.bits);
1647 },1706 },
1648 .ComptimeInt => return true,1707 .ComptimeInt => return true,
1649 else => unreachable,1708 else => unreachable,
...@@ -1745,6 +1804,10 @@ pub const Value = extern union {...@@ -1745,6 +1804,10 @@ pub const Value = extern union {
1745 }1804 }
17461805
1747 pub fn orderAgainstZero(lhs: Value) std.math.Order {1806 pub fn orderAgainstZero(lhs: Value) std.math.Order {
1807 return orderAgainstZeroAdvanced(lhs, null) catch unreachable;
1808 }
1809
1810 pub fn orderAgainstZeroAdvanced(lhs: Value, sema_kit: ?Module.WipAnalysis) !std.math.Order {
1748 return switch (lhs.tag()) {1811 return switch (lhs.tag()) {
1749 .zero,1812 .zero,
1750 .bool_false,1813 .bool_false,
...@@ -1765,6 +1828,15 @@ pub const Value = extern union {...@@ -1765,6 +1828,15 @@ pub const Value = extern union {
1765 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),1828 .int_big_positive => lhs.castTag(.int_big_positive).?.asBigInt().orderAgainstScalar(0),
1766 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),1829 .int_big_negative => lhs.castTag(.int_big_negative).?.asBigInt().orderAgainstScalar(0),
17671830
1831 .lazy_align => {
1832 const ty = lhs.castTag(.lazy_align).?.data;
1833 if (try ty.hasRuntimeBitsAdvanced(false, sema_kit)) {
1834 return .gt;
1835 } else {
1836 return .eq;
1837 }
1838 },
1839
1768 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),1840 .float_16 => std.math.order(lhs.castTag(.float_16).?.data, 0),
1769 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),1841 .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
1770 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),1842 .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
...@@ -1776,11 +1848,17 @@ pub const Value = extern union {...@@ -1776,11 +1848,17 @@ pub const Value = extern union {
1776 }1848 }
17771849
1778 /// Asserts the value is comparable.1850 /// Asserts the value is comparable.
1779 pub fn order(lhs: Value, rhs: Value) std.math.Order {1851 pub fn order(lhs: Value, rhs: Value, target: Target) std.math.Order {
1852 return orderAdvanced(lhs, rhs, target, null) catch unreachable;
1853 }
1854
1855 /// Asserts the value is comparable.
1856 /// If sema_kit is null then this function asserts things are resolved and cannot fail.
1857 pub fn orderAdvanced(lhs: Value, rhs: Value, target: Target, sema_kit: ?Module.WipAnalysis) !std.math.Order {
1780 const lhs_tag = lhs.tag();1858 const lhs_tag = lhs.tag();
1781 const rhs_tag = rhs.tag();1859 const rhs_tag = rhs.tag();
1782 const lhs_against_zero = lhs.orderAgainstZero();1860 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(sema_kit);
1783 const rhs_against_zero = rhs.orderAgainstZero();1861 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(sema_kit);
1784 switch (lhs_against_zero) {1862 switch (lhs_against_zero) {
1785 .lt => if (rhs_against_zero != .lt) return .lt,1863 .lt => if (rhs_against_zero != .lt) return .lt,
1786 .eq => return rhs_against_zero.invert(),1864 .eq => return rhs_against_zero.invert(),
...@@ -1814,14 +1892,24 @@ pub const Value = extern union {...@@ -1814,14 +1892,24 @@ pub const Value = extern union {
18141892
1815 var lhs_bigint_space: BigIntSpace = undefined;1893 var lhs_bigint_space: BigIntSpace = undefined;
1816 var rhs_bigint_space: BigIntSpace = undefined;1894 var rhs_bigint_space: BigIntSpace = undefined;
1817 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space);1895 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, target, sema_kit);
1818 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space);1896 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, target, sema_kit);
1819 return lhs_bigint.order(rhs_bigint);1897 return lhs_bigint.order(rhs_bigint);
1820 }1898 }
18211899
1822 /// Asserts the value is comparable. Does not take a type parameter because it supports1900 /// Asserts the value is comparable. Does not take a type parameter because it supports
1823 /// comparisons between heterogeneous types.1901 /// comparisons between heterogeneous types.
1824 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value) bool {1902 pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, target: Target) bool {
1903 return compareHeteroAdvanced(lhs, op, rhs, target, null) catch unreachable;
1904 }
1905
1906 pub fn compareHeteroAdvanced(
1907 lhs: Value,
1908 op: std.math.CompareOperator,
1909 rhs: Value,
1910 target: Target,
1911 sema_kit: ?Module.WipAnalysis,
1912 ) !bool {
1825 if (lhs.pointerDecl()) |lhs_decl| {1913 if (lhs.pointerDecl()) |lhs_decl| {
1826 if (rhs.pointerDecl()) |rhs_decl| {1914 if (rhs.pointerDecl()) |rhs_decl| {
1827 switch (op) {1915 switch (op) {
...@@ -1843,39 +1931,39 @@ pub const Value = extern union {...@@ -1843,39 +1931,39 @@ pub const Value = extern union {
1843 else => {},1931 else => {},
1844 }1932 }
1845 }1933 }
1846 return order(lhs, rhs).compare(op);1934 return (try orderAdvanced(lhs, rhs, target, sema_kit)).compare(op);
1847 }1935 }
18481936
1849 /// Asserts the values are comparable. Both operands have type `ty`.1937 /// Asserts the values are comparable. Both operands have type `ty`.
1850 /// Vector results will be reduced with AND.1938 /// Vector results will be reduced with AND.
1851 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {1939 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
1852 if (ty.zigTypeTag() == .Vector) {1940 if (ty.zigTypeTag() == .Vector) {
1853 var i: usize = 0;1941 var i: usize = 0;
1854 while (i < ty.vectorLen()) : (i += 1) {1942 while (i < ty.vectorLen()) : (i += 1) {
1855 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType())) {1943 if (!compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target)) {
1856 return false;1944 return false;
1857 }1945 }
1858 }1946 }
1859 return true;1947 return true;
1860 }1948 }
1861 return compareScalar(lhs, op, rhs, ty);1949 return compareScalar(lhs, op, rhs, ty, target);
1862 }1950 }
18631951
1864 /// Asserts the values are comparable. Both operands have type `ty`.1952 /// Asserts the values are comparable. Both operands have type `ty`.
1865 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type) bool {1953 pub fn compareScalar(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, target: Target) bool {
1866 return switch (op) {1954 return switch (op) {
1867 .eq => lhs.eql(rhs, ty),1955 .eq => lhs.eql(rhs, ty, target),
1868 .neq => !lhs.eql(rhs, ty),1956 .neq => !lhs.eql(rhs, ty, target),
1869 else => compareHetero(lhs, op, rhs),1957 else => compareHetero(lhs, op, rhs, target),
1870 };1958 };
1871 }1959 }
18721960
1873 /// Asserts the values are comparable vectors of type `ty`.1961 /// Asserts the values are comparable vectors of type `ty`.
1874 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator) !Value {1962 pub fn compareVector(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
1875 assert(ty.zigTypeTag() == .Vector);1963 assert(ty.zigTypeTag() == .Vector);
1876 const result_data = try allocator.alloc(Value, ty.vectorLen());1964 const result_data = try allocator.alloc(Value, ty.vectorLen());
1877 for (result_data) |*scalar, i| {1965 for (result_data) |*scalar, i| {
1878 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType());1966 const res_bool = compareScalar(lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType(), target);
1879 scalar.* = if (res_bool) Value.@"true" else Value.@"false";1967 scalar.* = if (res_bool) Value.@"true" else Value.@"false";
1880 }1968 }
1881 return Value.Tag.aggregate.create(allocator, result_data);1969 return Value.Tag.aggregate.create(allocator, result_data);
...@@ -1899,12 +1987,12 @@ pub const Value = extern union {...@@ -1899,12 +1987,12 @@ pub const Value = extern union {
18991987
1900 /// This function is used by hash maps and so treats floating-point NaNs as equal1988 /// This function is used by hash maps and so treats floating-point NaNs as equal
1901 /// to each other, and not equal to other floating-point values.1989 /// to each other, and not equal to other floating-point values.
1902 pub fn eql(a: Value, b: Value, ty: Type) bool {1990 /// Similarly, it treats `undef` as a distinct value from all other values.
1991 pub fn eql(a: Value, b: Value, ty: Type, target: Target) bool {
1903 const a_tag = a.tag();1992 const a_tag = a.tag();
1904 const b_tag = b.tag();1993 const b_tag = b.tag();
1905 assert(a_tag != .undef);
1906 assert(b_tag != .undef);
1907 if (a_tag == b_tag) switch (a_tag) {1994 if (a_tag == b_tag) switch (a_tag) {
1995 .undef => return true,
1908 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,1996 .void_value, .null_value, .the_only_possible_value, .empty_struct_value => return true,
1909 .enum_literal => {1997 .enum_literal => {
1910 const a_name = a.castTag(.enum_literal).?.data;1998 const a_name = a.castTag(.enum_literal).?.data;
...@@ -1920,31 +2008,31 @@ pub const Value = extern union {...@@ -1920,31 +2008,31 @@ pub const Value = extern union {
1920 const a_payload = a.castTag(.opt_payload).?.data;2008 const a_payload = a.castTag(.opt_payload).?.data;
1921 const b_payload = b.castTag(.opt_payload).?.data;2009 const b_payload = b.castTag(.opt_payload).?.data;
1922 var buffer: Type.Payload.ElemType = undefined;2010 var buffer: Type.Payload.ElemType = undefined;
1923 return eql(a_payload, b_payload, ty.optionalChild(&buffer));2011 return eql(a_payload, b_payload, ty.optionalChild(&buffer), target);
1924 },2012 },
1925 .slice => {2013 .slice => {
1926 const a_payload = a.castTag(.slice).?.data;2014 const a_payload = a.castTag(.slice).?.data;
1927 const b_payload = b.castTag(.slice).?.data;2015 const b_payload = b.castTag(.slice).?.data;
1928 if (!eql(a_payload.len, b_payload.len, Type.usize)) return false;2016 if (!eql(a_payload.len, b_payload.len, Type.usize, target)) return false;
19292017
1930 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2018 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
1931 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2019 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
19322020
1933 return eql(a_payload.ptr, b_payload.ptr, ptr_ty);2021 return eql(a_payload.ptr, b_payload.ptr, ptr_ty, target);
1934 },2022 },
1935 .elem_ptr => {2023 .elem_ptr => {
1936 const a_payload = a.castTag(.elem_ptr).?.data;2024 const a_payload = a.castTag(.elem_ptr).?.data;
1937 const b_payload = b.castTag(.elem_ptr).?.data;2025 const b_payload = b.castTag(.elem_ptr).?.data;
1938 if (a_payload.index != b_payload.index) return false;2026 if (a_payload.index != b_payload.index) return false;
19392027
1940 return eql(a_payload.array_ptr, b_payload.array_ptr, ty);2028 return eql(a_payload.array_ptr, b_payload.array_ptr, ty, target);
1941 },2029 },
1942 .field_ptr => {2030 .field_ptr => {
1943 const a_payload = a.castTag(.field_ptr).?.data;2031 const a_payload = a.castTag(.field_ptr).?.data;
1944 const b_payload = b.castTag(.field_ptr).?.data;2032 const b_payload = b.castTag(.field_ptr).?.data;
1945 if (a_payload.field_index != b_payload.field_index) return false;2033 if (a_payload.field_index != b_payload.field_index) return false;
19462034
1947 return eql(a_payload.container_ptr, b_payload.container_ptr, ty);2035 return eql(a_payload.container_ptr, b_payload.container_ptr, ty, target);
1948 },2036 },
1949 .@"error" => {2037 .@"error" => {
1950 const a_name = a.castTag(.@"error").?.data.name;2038 const a_name = a.castTag(.@"error").?.data.name;
...@@ -1954,7 +2042,7 @@ pub const Value = extern union {...@@ -1954,7 +2042,7 @@ pub const Value = extern union {
1954 .eu_payload => {2042 .eu_payload => {
1955 const a_payload = a.castTag(.eu_payload).?.data;2043 const a_payload = a.castTag(.eu_payload).?.data;
1956 const b_payload = b.castTag(.eu_payload).?.data;2044 const b_payload = b.castTag(.eu_payload).?.data;
1957 return eql(a_payload, b_payload, ty.errorUnionPayload());2045 return eql(a_payload, b_payload, ty.errorUnionPayload(), target);
1958 },2046 },
1959 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2047 .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
1960 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),2048 .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"),
...@@ -1972,7 +2060,7 @@ pub const Value = extern union {...@@ -1972,7 +2060,7 @@ pub const Value = extern union {
1972 const types = ty.tupleFields().types;2060 const types = ty.tupleFields().types;
1973 assert(types.len == a_field_vals.len);2061 assert(types.len == a_field_vals.len);
1974 for (types) |field_ty, i| {2062 for (types) |field_ty, i| {
1975 if (!eql(a_field_vals[i], b_field_vals[i], field_ty)) return false;2063 if (!eql(a_field_vals[i], b_field_vals[i], field_ty, target)) return false;
1976 }2064 }
1977 return true;2065 return true;
1978 }2066 }
...@@ -1981,7 +2069,7 @@ pub const Value = extern union {...@@ -1981,7 +2069,7 @@ pub const Value = extern union {
1981 const fields = ty.structFields().values();2069 const fields = ty.structFields().values();
1982 assert(fields.len == a_field_vals.len);2070 assert(fields.len == a_field_vals.len);
1983 for (fields) |field, i| {2071 for (fields) |field, i| {
1984 if (!eql(a_field_vals[i], b_field_vals[i], field.ty)) return false;2072 if (!eql(a_field_vals[i], b_field_vals[i], field.ty, target)) return false;
1985 }2073 }
1986 return true;2074 return true;
1987 }2075 }
...@@ -1990,7 +2078,7 @@ pub const Value = extern union {...@@ -1990,7 +2078,7 @@ pub const Value = extern union {
1990 for (a_field_vals) |a_elem, i| {2078 for (a_field_vals) |a_elem, i| {
1991 const b_elem = b_field_vals[i];2079 const b_elem = b_field_vals[i];
19922080
1993 if (!eql(a_elem, b_elem, elem_ty)) return false;2081 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
1994 }2082 }
1995 return true;2083 return true;
1996 },2084 },
...@@ -2005,17 +2093,19 @@ pub const Value = extern union {...@@ -2005,17 +2093,19 @@ pub const Value = extern union {
2005 },2093 },
2006 .Auto => {2094 .Auto => {
2007 const tag_ty = ty.unionTagTypeHypothetical();2095 const tag_ty = ty.unionTagTypeHypothetical();
2008 if (!a_union.tag.eql(b_union.tag, tag_ty)) {2096 if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
2009 return false;2097 return false;
2010 }2098 }
2011 const active_field_ty = ty.unionFieldType(a_union.tag);2099 const active_field_ty = ty.unionFieldType(a_union.tag, target);
2012 return a_union.val.eql(b_union.val, active_field_ty);2100 return a_union.val.eql(b_union.val, active_field_ty, target);
2013 },2101 },
2014 }2102 }
2015 },2103 },
2016 else => {},2104 else => {},
2017 } else if (a_tag == .null_value or b_tag == .null_value) {2105 } else if (a_tag == .null_value or b_tag == .null_value) {
2018 return false;2106 return false;
2107 } else if (a_tag == .undef or b_tag == .undef) {
2108 return false;
2019 }2109 }
20202110
2021 if (a.pointerDecl()) |a_decl| {2111 if (a.pointerDecl()) |a_decl| {
...@@ -2034,7 +2124,7 @@ pub const Value = extern union {...@@ -2034,7 +2124,7 @@ pub const Value = extern union {
2034 var buf_b: ToTypeBuffer = undefined;2124 var buf_b: ToTypeBuffer = undefined;
2035 const a_type = a.toType(&buf_a);2125 const a_type = a.toType(&buf_a);
2036 const b_type = b.toType(&buf_b);2126 const b_type = b.toType(&buf_b);
2037 return a_type.eql(b_type);2127 return a_type.eql(b_type, target);
2038 },2128 },
2039 .Enum => {2129 .Enum => {
2040 var buf_a: Payload.U64 = undefined;2130 var buf_a: Payload.U64 = undefined;
...@@ -2043,7 +2133,7 @@ pub const Value = extern union {...@@ -2043,7 +2133,7 @@ pub const Value = extern union {
2043 const b_val = b.enumToInt(ty, &buf_b);2133 const b_val = b.enumToInt(ty, &buf_b);
2044 var buf_ty: Type.Payload.Bits = undefined;2134 var buf_ty: Type.Payload.Bits = undefined;
2045 const int_ty = ty.intTagType(&buf_ty);2135 const int_ty = ty.intTagType(&buf_ty);
2046 return eql(a_val, b_val, int_ty);2136 return eql(a_val, b_val, int_ty, target);
2047 },2137 },
2048 .Array, .Vector => {2138 .Array, .Vector => {
2049 const len = ty.arrayLen();2139 const len = ty.arrayLen();
...@@ -2054,7 +2144,7 @@ pub const Value = extern union {...@@ -2054,7 +2144,7 @@ pub const Value = extern union {
2054 while (i < len) : (i += 1) {2144 while (i < len) : (i += 1) {
2055 const a_elem = elemValueBuffer(a, i, &a_buf);2145 const a_elem = elemValueBuffer(a, i, &a_buf);
2056 const b_elem = elemValueBuffer(b, i, &b_buf);2146 const b_elem = elemValueBuffer(b, i, &b_buf);
2057 if (!eql(a_elem, b_elem, elem_ty)) return false;2147 if (!eql(a_elem, b_elem, elem_ty, target)) return false;
2058 }2148 }
2059 return true;2149 return true;
2060 },2150 },
...@@ -2070,15 +2160,15 @@ pub const Value = extern union {...@@ -2070,15 +2160,15 @@ pub const Value = extern union {
2070 if (a_nan or b_nan) {2160 if (a_nan or b_nan) {
2071 return a_nan and b_nan;2161 return a_nan and b_nan;
2072 }2162 }
2073 return order(a, b).compare(.eq);2163 return order(a, b, target).compare(.eq);
2074 },2164 },
2075 else => return order(a, b).compare(.eq),2165 else => return order(a, b, target).compare(.eq),
2076 }2166 }
2077 }2167 }
20782168
2079 /// This function is used by hash maps and so treats floating-point NaNs as equal2169 /// This function is used by hash maps and so treats floating-point NaNs as equal
2080 /// to each other, and not equal to other floating-point values.2170 /// to each other, and not equal to other floating-point values.
2081 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash) void {2171 pub fn hash(val: Value, ty: Type, hasher: *std.hash.Wyhash, target: Target) void {
2082 const zig_ty_tag = ty.zigTypeTag();2172 const zig_ty_tag = ty.zigTypeTag();
2083 std.hash.autoHash(hasher, zig_ty_tag);2173 std.hash.autoHash(hasher, zig_ty_tag);
2084 if (val.isUndef()) return;2174 if (val.isUndef()) return;
...@@ -2095,7 +2185,7 @@ pub const Value = extern union {...@@ -2095,7 +2185,7 @@ pub const Value = extern union {
20952185
2096 .Type => {2186 .Type => {
2097 var buf: ToTypeBuffer = undefined;2187 var buf: ToTypeBuffer = undefined;
2098 return val.toType(&buf).hashWithHasher(hasher);2188 return val.toType(&buf).hashWithHasher(hasher, target);
2099 },2189 },
2100 .Float, .ComptimeFloat => {2190 .Float, .ComptimeFloat => {
2101 // Normalize the float here because this hash must match eql semantics.2191 // Normalize the float here because this hash must match eql semantics.
...@@ -2116,11 +2206,11 @@ pub const Value = extern union {...@@ -2116,11 +2206,11 @@ pub const Value = extern union {
2116 const slice = val.castTag(.slice).?.data;2206 const slice = val.castTag(.slice).?.data;
2117 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2207 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2118 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2208 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
2119 hash(slice.ptr, ptr_ty, hasher);2209 hash(slice.ptr, ptr_ty, hasher, target);
2120 hash(slice.len, Type.usize, hasher);2210 hash(slice.len, Type.usize, hasher, target);
2121 },2211 },
21222212
2123 else => return hashPtr(val, hasher),2213 else => return hashPtr(val, hasher, target),
2124 },2214 },
2125 .Array, .Vector => {2215 .Array, .Vector => {
2126 const len = ty.arrayLen();2216 const len = ty.arrayLen();
...@@ -2129,14 +2219,14 @@ pub const Value = extern union {...@@ -2129,14 +2219,14 @@ pub const Value = extern union {
2129 var elem_value_buf: ElemValueBuffer = undefined;2219 var elem_value_buf: ElemValueBuffer = undefined;
2130 while (index < len) : (index += 1) {2220 while (index < len) : (index += 1) {
2131 const elem_val = val.elemValueBuffer(index, &elem_value_buf);2221 const elem_val = val.elemValueBuffer(index, &elem_value_buf);
2132 elem_val.hash(elem_ty, hasher);2222 elem_val.hash(elem_ty, hasher, target);
2133 }2223 }
2134 },2224 },
2135 .Struct => {2225 .Struct => {
2136 if (ty.isTupleOrAnonStruct()) {2226 if (ty.isTupleOrAnonStruct()) {
2137 const fields = ty.tupleFields();2227 const fields = ty.tupleFields();
2138 for (fields.values) |field_val, i| {2228 for (fields.values) |field_val, i| {
2139 field_val.hash(fields.types[i], hasher);2229 field_val.hash(fields.types[i], hasher, target);
2140 }2230 }
2141 return;2231 return;
2142 }2232 }
...@@ -2145,13 +2235,13 @@ pub const Value = extern union {...@@ -2145,13 +2235,13 @@ pub const Value = extern union {
2145 switch (val.tag()) {2235 switch (val.tag()) {
2146 .empty_struct_value => {2236 .empty_struct_value => {
2147 for (fields) |field| {2237 for (fields) |field| {
2148 field.default_val.hash(field.ty, hasher);2238 field.default_val.hash(field.ty, hasher, target);
2149 }2239 }
2150 },2240 },
2151 .aggregate => {2241 .aggregate => {
2152 const field_values = val.castTag(.aggregate).?.data;2242 const field_values = val.castTag(.aggregate).?.data;
2153 for (field_values) |field_val, i| {2243 for (field_values) |field_val, i| {
2154 field_val.hash(fields[i].ty, hasher);2244 field_val.hash(fields[i].ty, hasher, target);
2155 }2245 }
2156 },2246 },
2157 else => unreachable,2247 else => unreachable,
...@@ -2163,7 +2253,7 @@ pub const Value = extern union {...@@ -2163,7 +2253,7 @@ pub const Value = extern union {
2163 const sub_val = payload.data;2253 const sub_val = payload.data;
2164 var buffer: Type.Payload.ElemType = undefined;2254 var buffer: Type.Payload.ElemType = undefined;
2165 const sub_ty = ty.optionalChild(&buffer);2255 const sub_ty = ty.optionalChild(&buffer);
2166 sub_val.hash(sub_ty, hasher);2256 sub_val.hash(sub_ty, hasher, target);
2167 } else {2257 } else {
2168 std.hash.autoHash(hasher, false); // non-null2258 std.hash.autoHash(hasher, false); // non-null
2169 }2259 }
...@@ -2172,14 +2262,14 @@ pub const Value = extern union {...@@ -2172,14 +2262,14 @@ pub const Value = extern union {
2172 if (val.tag() == .@"error") {2262 if (val.tag() == .@"error") {
2173 std.hash.autoHash(hasher, false); // error2263 std.hash.autoHash(hasher, false); // error
2174 const sub_ty = ty.errorUnionSet();2264 const sub_ty = ty.errorUnionSet();
2175 val.hash(sub_ty, hasher);2265 val.hash(sub_ty, hasher, target);
2176 return;2266 return;
2177 }2267 }
21782268
2179 if (val.castTag(.eu_payload)) |payload| {2269 if (val.castTag(.eu_payload)) |payload| {
2180 std.hash.autoHash(hasher, true); // payload2270 std.hash.autoHash(hasher, true); // payload
2181 const sub_ty = ty.errorUnionPayload();2271 const sub_ty = ty.errorUnionPayload();
2182 payload.data.hash(sub_ty, hasher);2272 payload.data.hash(sub_ty, hasher, target);
2183 return;2273 return;
2184 } else unreachable;2274 } else unreachable;
2185 },2275 },
...@@ -2192,15 +2282,15 @@ pub const Value = extern union {...@@ -2192,15 +2282,15 @@ pub const Value = extern union {
2192 .Enum => {2282 .Enum => {
2193 var enum_space: Payload.U64 = undefined;2283 var enum_space: Payload.U64 = undefined;
2194 const int_val = val.enumToInt(ty, &enum_space);2284 const int_val = val.enumToInt(ty, &enum_space);
2195 hashInt(int_val, hasher);2285 hashInt(int_val, hasher, target);
2196 },2286 },
2197 .Union => {2287 .Union => {
2198 const union_obj = val.cast(Payload.Union).?.data;2288 const union_obj = val.cast(Payload.Union).?.data;
2199 if (ty.unionTagType()) |tag_ty| {2289 if (ty.unionTagType()) |tag_ty| {
2200 union_obj.tag.hash(tag_ty, hasher);2290 union_obj.tag.hash(tag_ty, hasher, target);
2201 }2291 }
2202 const active_field_ty = ty.unionFieldType(union_obj.tag);2292 const active_field_ty = ty.unionFieldType(union_obj.tag, target);
2203 union_obj.val.hash(active_field_ty, hasher);2293 union_obj.val.hash(active_field_ty, hasher, target);
2204 },2294 },
2205 .Fn => {2295 .Fn => {
2206 const func: *Module.Fn = val.castTag(.function).?.data;2296 const func: *Module.Fn = val.castTag(.function).?.data;
...@@ -2225,28 +2315,30 @@ pub const Value = extern union {...@@ -2225,28 +2315,30 @@ pub const Value = extern union {
22252315
2226 pub const ArrayHashContext = struct {2316 pub const ArrayHashContext = struct {
2227 ty: Type,2317 ty: Type,
2318 target: Target,
22282319
2229 pub fn hash(self: @This(), val: Value) u32 {2320 pub fn hash(self: @This(), val: Value) u32 {
2230 const other_context: HashContext = .{ .ty = self.ty };2321 const other_context: HashContext = .{ .ty = self.ty, .target = self.target };
2231 return @truncate(u32, other_context.hash(val));2322 return @truncate(u32, other_context.hash(val));
2232 }2323 }
2233 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {2324 pub fn eql(self: @This(), a: Value, b: Value, b_index: usize) bool {
2234 _ = b_index;2325 _ = b_index;
2235 return a.eql(b, self.ty);2326 return a.eql(b, self.ty, self.target);
2236 }2327 }
2237 };2328 };
22382329
2239 pub const HashContext = struct {2330 pub const HashContext = struct {
2240 ty: Type,2331 ty: Type,
2332 target: Target,
22412333
2242 pub fn hash(self: @This(), val: Value) u64 {2334 pub fn hash(self: @This(), val: Value) u64 {
2243 var hasher = std.hash.Wyhash.init(0);2335 var hasher = std.hash.Wyhash.init(0);
2244 val.hash(self.ty, &hasher);2336 val.hash(self.ty, &hasher, self.target);
2245 return hasher.final();2337 return hasher.final();
2246 }2338 }
22472339
2248 pub fn eql(self: @This(), a: Value, b: Value) bool {2340 pub fn eql(self: @This(), a: Value, b: Value) bool {
2249 return a.eql(b, self.ty);2341 return a.eql(b, self.ty, self.target);
2250 }2342 }
2251 };2343 };
22522344
...@@ -2296,16 +2388,16 @@ pub const Value = extern union {...@@ -2296,16 +2388,16 @@ pub const Value = extern union {
2296 };2388 };
2297 }2389 }
22982390
2299 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash) void {2391 fn hashInt(int_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2300 var buffer: BigIntSpace = undefined;2392 var buffer: BigIntSpace = undefined;
2301 const big = int_val.toBigInt(&buffer);2393 const big = int_val.toBigInt(&buffer, target);
2302 std.hash.autoHash(hasher, big.positive);2394 std.hash.autoHash(hasher, big.positive);
2303 for (big.limbs) |limb| {2395 for (big.limbs) |limb| {
2304 std.hash.autoHash(hasher, limb);2396 std.hash.autoHash(hasher, limb);
2305 }2397 }
2306 }2398 }
23072399
2308 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash) void {2400 fn hashPtr(ptr_val: Value, hasher: *std.hash.Wyhash, target: Target) void {
2309 switch (ptr_val.tag()) {2401 switch (ptr_val.tag()) {
2310 .decl_ref,2402 .decl_ref,
2311 .decl_ref_mut,2403 .decl_ref_mut,
...@@ -2319,25 +2411,25 @@ pub const Value = extern union {...@@ -2319,25 +2411,25 @@ pub const Value = extern union {
23192411
2320 .elem_ptr => {2412 .elem_ptr => {
2321 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2413 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2322 hashPtr(elem_ptr.array_ptr, hasher);2414 hashPtr(elem_ptr.array_ptr, hasher, target);
2323 std.hash.autoHash(hasher, Value.Tag.elem_ptr);2415 std.hash.autoHash(hasher, Value.Tag.elem_ptr);
2324 std.hash.autoHash(hasher, elem_ptr.index);2416 std.hash.autoHash(hasher, elem_ptr.index);
2325 },2417 },
2326 .field_ptr => {2418 .field_ptr => {
2327 const field_ptr = ptr_val.castTag(.field_ptr).?.data;2419 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
2328 std.hash.autoHash(hasher, Value.Tag.field_ptr);2420 std.hash.autoHash(hasher, Value.Tag.field_ptr);
2329 hashPtr(field_ptr.container_ptr, hasher);2421 hashPtr(field_ptr.container_ptr, hasher, target);
2330 std.hash.autoHash(hasher, field_ptr.field_index);2422 std.hash.autoHash(hasher, field_ptr.field_index);
2331 },2423 },
2332 .eu_payload_ptr => {2424 .eu_payload_ptr => {
2333 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;2425 const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
2334 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);2426 std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
2335 hashPtr(err_union_ptr.container_ptr, hasher);2427 hashPtr(err_union_ptr.container_ptr, hasher, target);
2336 },2428 },
2337 .opt_payload_ptr => {2429 .opt_payload_ptr => {
2338 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;2430 const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
2339 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);2431 std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
2340 hashPtr(opt_ptr.container_ptr, hasher);2432 hashPtr(opt_ptr.container_ptr, hasher, target);
2341 },2433 },
23422434
2343 .zero,2435 .zero,
...@@ -2349,7 +2441,7 @@ pub const Value = extern union {...@@ -2349,7 +2441,7 @@ pub const Value = extern union {
2349 .bool_false,2441 .bool_false,
2350 .bool_true,2442 .bool_true,
2351 .the_only_possible_value,2443 .the_only_possible_value,
2352 => return hashInt(ptr_val, hasher),2444 => return hashInt(ptr_val, hasher, target),
23532445
2354 else => unreachable,2446 else => unreachable,
2355 }2447 }
...@@ -2411,9 +2503,9 @@ pub const Value = extern union {...@@ -2411,9 +2503,9 @@ pub const Value = extern union {
2411 };2503 };
2412 }2504 }
24132505
2414 pub fn sliceLen(val: Value) u64 {2506 pub fn sliceLen(val: Value, target: Target) u64 {
2415 return switch (val.tag()) {2507 return switch (val.tag()) {
2416 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(),2508 .slice => val.castTag(.slice).?.data.len.toUnsignedInt(target),
2417 .decl_ref => {2509 .decl_ref => {
2418 const decl = val.castTag(.decl_ref).?.data;2510 const decl = val.castTag(.decl_ref).?.data;
2419 if (decl.ty.zigTypeTag() == .Array) {2511 if (decl.ty.zigTypeTag() == .Array) {
...@@ -2561,7 +2653,7 @@ pub const Value = extern union {...@@ -2561,7 +2653,7 @@ pub const Value = extern union {
2561 }2653 }
25622654
2563 /// Returns a pointer to the element value at the index.2655 /// Returns a pointer to the element value at the index.
2564 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {2656 pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize, target: Target) Allocator.Error!Value {
2565 const elem_ty = ty.elemType2();2657 const elem_ty = ty.elemType2();
2566 const ptr_val = switch (val.tag()) {2658 const ptr_val = switch (val.tag()) {
2567 .slice => val.castTag(.slice).?.data.ptr,2659 .slice => val.castTag(.slice).?.data.ptr,
...@@ -2570,7 +2662,7 @@ pub const Value = extern union {...@@ -2570,7 +2662,7 @@ pub const Value = extern union {
25702662
2571 if (ptr_val.tag() == .elem_ptr) {2663 if (ptr_val.tag() == .elem_ptr) {
2572 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2664 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
2573 if (elem_ptr.elem_ty.eql(elem_ty)) {2665 if (elem_ptr.elem_ty.eql(elem_ty, target)) {
2574 return Tag.elem_ptr.create(arena, .{2666 return Tag.elem_ptr.create(arena, .{
2575 .array_ptr = elem_ptr.array_ptr,2667 .array_ptr = elem_ptr.array_ptr,
2576 .elem_ty = elem_ptr.elem_ty,2668 .elem_ty = elem_ptr.elem_ty,
...@@ -2821,8 +2913,8 @@ pub const Value = extern union {...@@ -2821,8 +2913,8 @@ pub const Value = extern union {
28212913
2822 var lhs_space: Value.BigIntSpace = undefined;2914 var lhs_space: Value.BigIntSpace = undefined;
2823 var rhs_space: Value.BigIntSpace = undefined;2915 var rhs_space: Value.BigIntSpace = undefined;
2824 const lhs_bigint = lhs.toBigInt(&lhs_space);2916 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2825 const rhs_bigint = rhs.toBigInt(&rhs_space);2917 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2826 const limbs = try arena.alloc(2918 const limbs = try arena.alloc(
2827 std.math.big.Limb,2919 std.math.big.Limb,
2828 std.math.big.int.calcTwosCompLimbCount(info.bits),2920 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2865,7 +2957,7 @@ pub const Value = extern union {...@@ -2865,7 +2957,7 @@ pub const Value = extern union {
2865 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);2957 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
28662958
2867 if (ty.zigTypeTag() == .ComptimeInt) {2959 if (ty.zigTypeTag() == .ComptimeInt) {
2868 return intAdd(lhs, rhs, ty, arena);2960 return intAdd(lhs, rhs, ty, arena, target);
2869 }2961 }
28702962
2871 if (ty.isAnyFloat()) {2963 if (ty.isAnyFloat()) {
...@@ -2925,8 +3017,8 @@ pub const Value = extern union {...@@ -2925,8 +3017,8 @@ pub const Value = extern union {
29253017
2926 var lhs_space: Value.BigIntSpace = undefined;3018 var lhs_space: Value.BigIntSpace = undefined;
2927 var rhs_space: Value.BigIntSpace = undefined;3019 var rhs_space: Value.BigIntSpace = undefined;
2928 const lhs_bigint = lhs.toBigInt(&lhs_space);3020 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2929 const rhs_bigint = rhs.toBigInt(&rhs_space);3021 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2930 const limbs = try arena.alloc(3022 const limbs = try arena.alloc(
2931 std.math.big.Limb,3023 std.math.big.Limb,
2932 std.math.big.int.calcTwosCompLimbCount(info.bits),3024 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2947,8 +3039,8 @@ pub const Value = extern union {...@@ -2947,8 +3039,8 @@ pub const Value = extern union {
29473039
2948 var lhs_space: Value.BigIntSpace = undefined;3040 var lhs_space: Value.BigIntSpace = undefined;
2949 var rhs_space: Value.BigIntSpace = undefined;3041 var rhs_space: Value.BigIntSpace = undefined;
2950 const lhs_bigint = lhs.toBigInt(&lhs_space);3042 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
2951 const rhs_bigint = rhs.toBigInt(&rhs_space);3043 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
2952 const limbs = try arena.alloc(3044 const limbs = try arena.alloc(
2953 std.math.big.Limb,3045 std.math.big.Limb,
2954 std.math.big.int.calcTwosCompLimbCount(info.bits),3046 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -2991,7 +3083,7 @@ pub const Value = extern union {...@@ -2991,7 +3083,7 @@ pub const Value = extern union {
2991 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3083 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
29923084
2993 if (ty.zigTypeTag() == .ComptimeInt) {3085 if (ty.zigTypeTag() == .ComptimeInt) {
2994 return intSub(lhs, rhs, ty, arena);3086 return intSub(lhs, rhs, ty, arena, target);
2995 }3087 }
29963088
2997 if (ty.isAnyFloat()) {3089 if (ty.isAnyFloat()) {
...@@ -3035,8 +3127,8 @@ pub const Value = extern union {...@@ -3035,8 +3127,8 @@ pub const Value = extern union {
30353127
3036 var lhs_space: Value.BigIntSpace = undefined;3128 var lhs_space: Value.BigIntSpace = undefined;
3037 var rhs_space: Value.BigIntSpace = undefined;3129 var rhs_space: Value.BigIntSpace = undefined;
3038 const lhs_bigint = lhs.toBigInt(&lhs_space);3130 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3039 const rhs_bigint = rhs.toBigInt(&rhs_space);3131 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3040 const limbs = try arena.alloc(3132 const limbs = try arena.alloc(
3041 std.math.big.Limb,3133 std.math.big.Limb,
3042 std.math.big.int.calcTwosCompLimbCount(info.bits),3134 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3057,8 +3149,8 @@ pub const Value = extern union {...@@ -3057,8 +3149,8 @@ pub const Value = extern union {
30573149
3058 var lhs_space: Value.BigIntSpace = undefined;3150 var lhs_space: Value.BigIntSpace = undefined;
3059 var rhs_space: Value.BigIntSpace = undefined;3151 var rhs_space: Value.BigIntSpace = undefined;
3060 const lhs_bigint = lhs.toBigInt(&lhs_space);3152 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3061 const rhs_bigint = rhs.toBigInt(&rhs_space);3153 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3062 const limbs = try arena.alloc(3154 const limbs = try arena.alloc(
3063 std.math.big.Limb,3155 std.math.big.Limb,
3064 lhs_bigint.limbs.len + rhs_bigint.limbs.len,3156 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -3110,7 +3202,7 @@ pub const Value = extern union {...@@ -3110,7 +3202,7 @@ pub const Value = extern union {
3110 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3202 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
31113203
3112 if (ty.zigTypeTag() == .ComptimeInt) {3204 if (ty.zigTypeTag() == .ComptimeInt) {
3113 return intMul(lhs, rhs, ty, arena);3205 return intMul(lhs, rhs, ty, arena, target);
3114 }3206 }
31153207
3116 if (ty.isAnyFloat()) {3208 if (ty.isAnyFloat()) {
...@@ -3154,8 +3246,8 @@ pub const Value = extern union {...@@ -3154,8 +3246,8 @@ pub const Value = extern union {
31543246
3155 var lhs_space: Value.BigIntSpace = undefined;3247 var lhs_space: Value.BigIntSpace = undefined;
3156 var rhs_space: Value.BigIntSpace = undefined;3248 var rhs_space: Value.BigIntSpace = undefined;
3157 const lhs_bigint = lhs.toBigInt(&lhs_space);3249 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3158 const rhs_bigint = rhs.toBigInt(&rhs_space);3250 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3159 const limbs = try arena.alloc(3251 const limbs = try arena.alloc(
3160 std.math.big.Limb,3252 std.math.big.Limb,
3161 std.math.max(3253 std.math.max(
...@@ -3175,24 +3267,24 @@ pub const Value = extern union {...@@ -3175,24 +3267,24 @@ pub const Value = extern union {
3175 }3267 }
31763268
3177 /// Supports both floats and ints; handles undefined.3269 /// Supports both floats and ints; handles undefined.
3178 pub fn numberMax(lhs: Value, rhs: Value) Value {3270 pub fn numberMax(lhs: Value, rhs: Value, target: Target) Value {
3179 if (lhs.isUndef() or rhs.isUndef()) return undef;3271 if (lhs.isUndef() or rhs.isUndef()) return undef;
3180 if (lhs.isNan()) return rhs;3272 if (lhs.isNan()) return rhs;
3181 if (rhs.isNan()) return lhs;3273 if (rhs.isNan()) return lhs;
31823274
3183 return switch (order(lhs, rhs)) {3275 return switch (order(lhs, rhs, target)) {
3184 .lt => rhs,3276 .lt => rhs,
3185 .gt, .eq => lhs,3277 .gt, .eq => lhs,
3186 };3278 };
3187 }3279 }
31883280
3189 /// Supports both floats and ints; handles undefined.3281 /// Supports both floats and ints; handles undefined.
3190 pub fn numberMin(lhs: Value, rhs: Value) Value {3282 pub fn numberMin(lhs: Value, rhs: Value, target: Target) Value {
3191 if (lhs.isUndef() or rhs.isUndef()) return undef;3283 if (lhs.isUndef() or rhs.isUndef()) return undef;
3192 if (lhs.isNan()) return rhs;3284 if (lhs.isNan()) return rhs;
3193 if (rhs.isNan()) return lhs;3285 if (rhs.isNan()) return lhs;
31943286
3195 return switch (order(lhs, rhs)) {3287 return switch (order(lhs, rhs, target)) {
3196 .lt => lhs,3288 .lt => lhs,
3197 .gt, .eq => rhs,3289 .gt, .eq => rhs,
3198 };3290 };
...@@ -3224,7 +3316,7 @@ pub const Value = extern union {...@@ -3224,7 +3316,7 @@ pub const Value = extern union {
3224 // TODO is this a performance issue? maybe we should try the operation without3316 // TODO is this a performance issue? maybe we should try the operation without
3225 // resorting to BigInt first.3317 // resorting to BigInt first.
3226 var val_space: Value.BigIntSpace = undefined;3318 var val_space: Value.BigIntSpace = undefined;
3227 const val_bigint = val.toBigInt(&val_space);3319 const val_bigint = val.toBigInt(&val_space, target);
3228 const limbs = try arena.alloc(3320 const limbs = try arena.alloc(
3229 std.math.big.Limb,3321 std.math.big.Limb,
3230 std.math.big.int.calcTwosCompLimbCount(info.bits),3322 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3236,27 +3328,27 @@ pub const Value = extern union {...@@ -3236,27 +3328,27 @@ pub const Value = extern union {
3236 }3328 }
32373329
3238 /// operands must be (vectors of) integers; handles undefined scalars.3330 /// operands must be (vectors of) integers; handles undefined scalars.
3239 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3331 pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3240 if (ty.zigTypeTag() == .Vector) {3332 if (ty.zigTypeTag() == .Vector) {
3241 const result_data = try allocator.alloc(Value, ty.vectorLen());3333 const result_data = try allocator.alloc(Value, ty.vectorLen());
3242 for (result_data) |*scalar, i| {3334 for (result_data) |*scalar, i| {
3243 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3335 scalar.* = try bitwiseAndScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3244 }3336 }
3245 return Value.Tag.aggregate.create(allocator, result_data);3337 return Value.Tag.aggregate.create(allocator, result_data);
3246 }3338 }
3247 return bitwiseAndScalar(lhs, rhs, allocator);3339 return bitwiseAndScalar(lhs, rhs, allocator, target);
3248 }3340 }
32493341
3250 /// operands must be integers; handles undefined.3342 /// operands must be integers; handles undefined.
3251 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3343 pub fn bitwiseAndScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3252 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3344 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32533345
3254 // TODO is this a performance issue? maybe we should try the operation without3346 // TODO is this a performance issue? maybe we should try the operation without
3255 // resorting to BigInt first.3347 // resorting to BigInt first.
3256 var lhs_space: Value.BigIntSpace = undefined;3348 var lhs_space: Value.BigIntSpace = undefined;
3257 var rhs_space: Value.BigIntSpace = undefined;3349 var rhs_space: Value.BigIntSpace = undefined;
3258 const lhs_bigint = lhs.toBigInt(&lhs_space);3350 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3259 const rhs_bigint = rhs.toBigInt(&rhs_space);3351 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3260 const limbs = try arena.alloc(3352 const limbs = try arena.alloc(
3261 std.math.big.Limb,3353 std.math.big.Limb,
3262 // + 1 for negatives3354 // + 1 for negatives
...@@ -3283,38 +3375,38 @@ pub const Value = extern union {...@@ -3283,38 +3375,38 @@ pub const Value = extern union {
3283 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {3375 pub fn bitwiseNandScalar(lhs: Value, rhs: Value, ty: Type, arena: Allocator, target: Target) !Value {
3284 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3376 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
32853377
3286 const anded = try bitwiseAnd(lhs, rhs, ty, arena);3378 const anded = try bitwiseAnd(lhs, rhs, ty, arena, target);
32873379
3288 const all_ones = if (ty.isSignedInt())3380 const all_ones = if (ty.isSignedInt())
3289 try Value.Tag.int_i64.create(arena, -1)3381 try Value.Tag.int_i64.create(arena, -1)
3290 else3382 else
3291 try ty.maxInt(arena, target);3383 try ty.maxInt(arena, target);
32923384
3293 return bitwiseXor(anded, all_ones, ty, arena);3385 return bitwiseXor(anded, all_ones, ty, arena, target);
3294 }3386 }
32953387
3296 /// operands must be (vectors of) integers; handles undefined scalars.3388 /// operands must be (vectors of) integers; handles undefined scalars.
3297 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3389 pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3298 if (ty.zigTypeTag() == .Vector) {3390 if (ty.zigTypeTag() == .Vector) {
3299 const result_data = try allocator.alloc(Value, ty.vectorLen());3391 const result_data = try allocator.alloc(Value, ty.vectorLen());
3300 for (result_data) |*scalar, i| {3392 for (result_data) |*scalar, i| {
3301 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3393 scalar.* = try bitwiseOrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3302 }3394 }
3303 return Value.Tag.aggregate.create(allocator, result_data);3395 return Value.Tag.aggregate.create(allocator, result_data);
3304 }3396 }
3305 return bitwiseOrScalar(lhs, rhs, allocator);3397 return bitwiseOrScalar(lhs, rhs, allocator, target);
3306 }3398 }
33073399
3308 /// operands must be integers; handles undefined.3400 /// operands must be integers; handles undefined.
3309 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3401 pub fn bitwiseOrScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3310 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3402 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33113403
3312 // TODO is this a performance issue? maybe we should try the operation without3404 // TODO is this a performance issue? maybe we should try the operation without
3313 // resorting to BigInt first.3405 // resorting to BigInt first.
3314 var lhs_space: Value.BigIntSpace = undefined;3406 var lhs_space: Value.BigIntSpace = undefined;
3315 var rhs_space: Value.BigIntSpace = undefined;3407 var rhs_space: Value.BigIntSpace = undefined;
3316 const lhs_bigint = lhs.toBigInt(&lhs_space);3408 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3317 const rhs_bigint = rhs.toBigInt(&rhs_space);3409 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3318 const limbs = try arena.alloc(3410 const limbs = try arena.alloc(
3319 std.math.big.Limb,3411 std.math.big.Limb,
3320 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),3412 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len),
...@@ -3325,27 +3417,27 @@ pub const Value = extern union {...@@ -3325,27 +3417,27 @@ pub const Value = extern union {
3325 }3417 }
33263418
3327 /// operands must be (vectors of) integers; handles undefined scalars.3419 /// operands must be (vectors of) integers; handles undefined scalars.
3328 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3420 pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3329 if (ty.zigTypeTag() == .Vector) {3421 if (ty.zigTypeTag() == .Vector) {
3330 const result_data = try allocator.alloc(Value, ty.vectorLen());3422 const result_data = try allocator.alloc(Value, ty.vectorLen());
3331 for (result_data) |*scalar, i| {3423 for (result_data) |*scalar, i| {
3332 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3424 scalar.* = try bitwiseXorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3333 }3425 }
3334 return Value.Tag.aggregate.create(allocator, result_data);3426 return Value.Tag.aggregate.create(allocator, result_data);
3335 }3427 }
3336 return bitwiseXorScalar(lhs, rhs, allocator);3428 return bitwiseXorScalar(lhs, rhs, allocator, target);
3337 }3429 }
33383430
3339 /// operands must be integers; handles undefined.3431 /// operands must be integers; handles undefined.
3340 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator) !Value {3432 pub fn bitwiseXorScalar(lhs: Value, rhs: Value, arena: Allocator, target: Target) !Value {
3341 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);3433 if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
33423434
3343 // TODO is this a performance issue? maybe we should try the operation without3435 // TODO is this a performance issue? maybe we should try the operation without
3344 // resorting to BigInt first.3436 // resorting to BigInt first.
3345 var lhs_space: Value.BigIntSpace = undefined;3437 var lhs_space: Value.BigIntSpace = undefined;
3346 var rhs_space: Value.BigIntSpace = undefined;3438 var rhs_space: Value.BigIntSpace = undefined;
3347 const lhs_bigint = lhs.toBigInt(&lhs_space);3439 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3348 const rhs_bigint = rhs.toBigInt(&rhs_space);3440 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3349 const limbs = try arena.alloc(3441 const limbs = try arena.alloc(
3350 std.math.big.Limb,3442 std.math.big.Limb,
3351 // + 1 for negatives3443 // + 1 for negatives
...@@ -3356,24 +3448,24 @@ pub const Value = extern union {...@@ -3356,24 +3448,24 @@ pub const Value = extern union {
3356 return fromBigInt(arena, result_bigint.toConst());3448 return fromBigInt(arena, result_bigint.toConst());
3357 }3449 }
33583450
3359 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3451 pub fn intAdd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3360 if (ty.zigTypeTag() == .Vector) {3452 if (ty.zigTypeTag() == .Vector) {
3361 const result_data = try allocator.alloc(Value, ty.vectorLen());3453 const result_data = try allocator.alloc(Value, ty.vectorLen());
3362 for (result_data) |*scalar, i| {3454 for (result_data) |*scalar, i| {
3363 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3455 scalar.* = try intAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3364 }3456 }
3365 return Value.Tag.aggregate.create(allocator, result_data);3457 return Value.Tag.aggregate.create(allocator, result_data);
3366 }3458 }
3367 return intAddScalar(lhs, rhs, allocator);3459 return intAddScalar(lhs, rhs, allocator, target);
3368 }3460 }
33693461
3370 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3462 pub fn intAddScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3371 // TODO is this a performance issue? maybe we should try the operation without3463 // TODO is this a performance issue? maybe we should try the operation without
3372 // resorting to BigInt first.3464 // resorting to BigInt first.
3373 var lhs_space: Value.BigIntSpace = undefined;3465 var lhs_space: Value.BigIntSpace = undefined;
3374 var rhs_space: Value.BigIntSpace = undefined;3466 var rhs_space: Value.BigIntSpace = undefined;
3375 const lhs_bigint = lhs.toBigInt(&lhs_space);3467 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3376 const rhs_bigint = rhs.toBigInt(&rhs_space);3468 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3377 const limbs = try allocator.alloc(3469 const limbs = try allocator.alloc(
3378 std.math.big.Limb,3470 std.math.big.Limb,
3379 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,3471 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -3383,24 +3475,24 @@ pub const Value = extern union {...@@ -3383,24 +3475,24 @@ pub const Value = extern union {
3383 return fromBigInt(allocator, result_bigint.toConst());3475 return fromBigInt(allocator, result_bigint.toConst());
3384 }3476 }
33853477
3386 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3478 pub fn intSub(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3387 if (ty.zigTypeTag() == .Vector) {3479 if (ty.zigTypeTag() == .Vector) {
3388 const result_data = try allocator.alloc(Value, ty.vectorLen());3480 const result_data = try allocator.alloc(Value, ty.vectorLen());
3389 for (result_data) |*scalar, i| {3481 for (result_data) |*scalar, i| {
3390 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3482 scalar.* = try intSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3391 }3483 }
3392 return Value.Tag.aggregate.create(allocator, result_data);3484 return Value.Tag.aggregate.create(allocator, result_data);
3393 }3485 }
3394 return intSubScalar(lhs, rhs, allocator);3486 return intSubScalar(lhs, rhs, allocator, target);
3395 }3487 }
33963488
3397 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3489 pub fn intSubScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3398 // TODO is this a performance issue? maybe we should try the operation without3490 // TODO is this a performance issue? maybe we should try the operation without
3399 // resorting to BigInt first.3491 // resorting to BigInt first.
3400 var lhs_space: Value.BigIntSpace = undefined;3492 var lhs_space: Value.BigIntSpace = undefined;
3401 var rhs_space: Value.BigIntSpace = undefined;3493 var rhs_space: Value.BigIntSpace = undefined;
3402 const lhs_bigint = lhs.toBigInt(&lhs_space);3494 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3403 const rhs_bigint = rhs.toBigInt(&rhs_space);3495 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3404 const limbs = try allocator.alloc(3496 const limbs = try allocator.alloc(
3405 std.math.big.Limb,3497 std.math.big.Limb,
3406 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,3498 std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -3410,24 +3502,24 @@ pub const Value = extern union {...@@ -3410,24 +3502,24 @@ pub const Value = extern union {
3410 return fromBigInt(allocator, result_bigint.toConst());3502 return fromBigInt(allocator, result_bigint.toConst());
3411 }3503 }
34123504
3413 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3505 pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3414 if (ty.zigTypeTag() == .Vector) {3506 if (ty.zigTypeTag() == .Vector) {
3415 const result_data = try allocator.alloc(Value, ty.vectorLen());3507 const result_data = try allocator.alloc(Value, ty.vectorLen());
3416 for (result_data) |*scalar, i| {3508 for (result_data) |*scalar, i| {
3417 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3509 scalar.* = try intDivScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3418 }3510 }
3419 return Value.Tag.aggregate.create(allocator, result_data);3511 return Value.Tag.aggregate.create(allocator, result_data);
3420 }3512 }
3421 return intDivScalar(lhs, rhs, allocator);3513 return intDivScalar(lhs, rhs, allocator, target);
3422 }3514 }
34233515
3424 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3516 pub fn intDivScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3425 // TODO is this a performance issue? maybe we should try the operation without3517 // TODO is this a performance issue? maybe we should try the operation without
3426 // resorting to BigInt first.3518 // resorting to BigInt first.
3427 var lhs_space: Value.BigIntSpace = undefined;3519 var lhs_space: Value.BigIntSpace = undefined;
3428 var rhs_space: Value.BigIntSpace = undefined;3520 var rhs_space: Value.BigIntSpace = undefined;
3429 const lhs_bigint = lhs.toBigInt(&lhs_space);3521 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3430 const rhs_bigint = rhs.toBigInt(&rhs_space);3522 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3431 const limbs_q = try allocator.alloc(3523 const limbs_q = try allocator.alloc(
3432 std.math.big.Limb,3524 std.math.big.Limb,
3433 lhs_bigint.limbs.len,3525 lhs_bigint.limbs.len,
...@@ -3446,24 +3538,24 @@ pub const Value = extern union {...@@ -3446,24 +3538,24 @@ pub const Value = extern union {
3446 return fromBigInt(allocator, result_q.toConst());3538 return fromBigInt(allocator, result_q.toConst());
3447 }3539 }
34483540
3449 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3541 pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3450 if (ty.zigTypeTag() == .Vector) {3542 if (ty.zigTypeTag() == .Vector) {
3451 const result_data = try allocator.alloc(Value, ty.vectorLen());3543 const result_data = try allocator.alloc(Value, ty.vectorLen());
3452 for (result_data) |*scalar, i| {3544 for (result_data) |*scalar, i| {
3453 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3545 scalar.* = try intDivFloorScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3454 }3546 }
3455 return Value.Tag.aggregate.create(allocator, result_data);3547 return Value.Tag.aggregate.create(allocator, result_data);
3456 }3548 }
3457 return intDivFloorScalar(lhs, rhs, allocator);3549 return intDivFloorScalar(lhs, rhs, allocator, target);
3458 }3550 }
34593551
3460 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3552 pub fn intDivFloorScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3461 // TODO is this a performance issue? maybe we should try the operation without3553 // TODO is this a performance issue? maybe we should try the operation without
3462 // resorting to BigInt first.3554 // resorting to BigInt first.
3463 var lhs_space: Value.BigIntSpace = undefined;3555 var lhs_space: Value.BigIntSpace = undefined;
3464 var rhs_space: Value.BigIntSpace = undefined;3556 var rhs_space: Value.BigIntSpace = undefined;
3465 const lhs_bigint = lhs.toBigInt(&lhs_space);3557 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3466 const rhs_bigint = rhs.toBigInt(&rhs_space);3558 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3467 const limbs_q = try allocator.alloc(3559 const limbs_q = try allocator.alloc(
3468 std.math.big.Limb,3560 std.math.big.Limb,
3469 lhs_bigint.limbs.len,3561 lhs_bigint.limbs.len,
...@@ -3482,24 +3574,24 @@ pub const Value = extern union {...@@ -3482,24 +3574,24 @@ pub const Value = extern union {
3482 return fromBigInt(allocator, result_q.toConst());3574 return fromBigInt(allocator, result_q.toConst());
3483 }3575 }
34843576
3485 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3577 pub fn intRem(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3486 if (ty.zigTypeTag() == .Vector) {3578 if (ty.zigTypeTag() == .Vector) {
3487 const result_data = try allocator.alloc(Value, ty.vectorLen());3579 const result_data = try allocator.alloc(Value, ty.vectorLen());
3488 for (result_data) |*scalar, i| {3580 for (result_data) |*scalar, i| {
3489 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3581 scalar.* = try intRemScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3490 }3582 }
3491 return Value.Tag.aggregate.create(allocator, result_data);3583 return Value.Tag.aggregate.create(allocator, result_data);
3492 }3584 }
3493 return intRemScalar(lhs, rhs, allocator);3585 return intRemScalar(lhs, rhs, allocator, target);
3494 }3586 }
34953587
3496 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3588 pub fn intRemScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3497 // TODO is this a performance issue? maybe we should try the operation without3589 // TODO is this a performance issue? maybe we should try the operation without
3498 // resorting to BigInt first.3590 // resorting to BigInt first.
3499 var lhs_space: Value.BigIntSpace = undefined;3591 var lhs_space: Value.BigIntSpace = undefined;
3500 var rhs_space: Value.BigIntSpace = undefined;3592 var rhs_space: Value.BigIntSpace = undefined;
3501 const lhs_bigint = lhs.toBigInt(&lhs_space);3593 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3502 const rhs_bigint = rhs.toBigInt(&rhs_space);3594 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3503 const limbs_q = try allocator.alloc(3595 const limbs_q = try allocator.alloc(
3504 std.math.big.Limb,3596 std.math.big.Limb,
3505 lhs_bigint.limbs.len,3597 lhs_bigint.limbs.len,
...@@ -3520,24 +3612,24 @@ pub const Value = extern union {...@@ -3520,24 +3612,24 @@ pub const Value = extern union {
3520 return fromBigInt(allocator, result_r.toConst());3612 return fromBigInt(allocator, result_r.toConst());
3521 }3613 }
35223614
3523 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3615 pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3524 if (ty.zigTypeTag() == .Vector) {3616 if (ty.zigTypeTag() == .Vector) {
3525 const result_data = try allocator.alloc(Value, ty.vectorLen());3617 const result_data = try allocator.alloc(Value, ty.vectorLen());
3526 for (result_data) |*scalar, i| {3618 for (result_data) |*scalar, i| {
3527 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3619 scalar.* = try intModScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3528 }3620 }
3529 return Value.Tag.aggregate.create(allocator, result_data);3621 return Value.Tag.aggregate.create(allocator, result_data);
3530 }3622 }
3531 return intModScalar(lhs, rhs, allocator);3623 return intModScalar(lhs, rhs, allocator, target);
3532 }3624 }
35333625
3534 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3626 pub fn intModScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3535 // TODO is this a performance issue? maybe we should try the operation without3627 // TODO is this a performance issue? maybe we should try the operation without
3536 // resorting to BigInt first.3628 // resorting to BigInt first.
3537 var lhs_space: Value.BigIntSpace = undefined;3629 var lhs_space: Value.BigIntSpace = undefined;
3538 var rhs_space: Value.BigIntSpace = undefined;3630 var rhs_space: Value.BigIntSpace = undefined;
3539 const lhs_bigint = lhs.toBigInt(&lhs_space);3631 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3540 const rhs_bigint = rhs.toBigInt(&rhs_space);3632 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3541 const limbs_q = try allocator.alloc(3633 const limbs_q = try allocator.alloc(
3542 std.math.big.Limb,3634 std.math.big.Limb,
3543 lhs_bigint.limbs.len,3635 lhs_bigint.limbs.len,
...@@ -3658,24 +3750,24 @@ pub const Value = extern union {...@@ -3658,24 +3750,24 @@ pub const Value = extern union {
3658 }3750 }
3659 }3751 }
36603752
3661 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3753 pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3662 if (ty.zigTypeTag() == .Vector) {3754 if (ty.zigTypeTag() == .Vector) {
3663 const result_data = try allocator.alloc(Value, ty.vectorLen());3755 const result_data = try allocator.alloc(Value, ty.vectorLen());
3664 for (result_data) |*scalar, i| {3756 for (result_data) |*scalar, i| {
3665 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3757 scalar.* = try intMulScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3666 }3758 }
3667 return Value.Tag.aggregate.create(allocator, result_data);3759 return Value.Tag.aggregate.create(allocator, result_data);
3668 }3760 }
3669 return intMulScalar(lhs, rhs, allocator);3761 return intMulScalar(lhs, rhs, allocator, target);
3670 }3762 }
36713763
3672 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3764 pub fn intMulScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3673 // TODO is this a performance issue? maybe we should try the operation without3765 // TODO is this a performance issue? maybe we should try the operation without
3674 // resorting to BigInt first.3766 // resorting to BigInt first.
3675 var lhs_space: Value.BigIntSpace = undefined;3767 var lhs_space: Value.BigIntSpace = undefined;
3676 var rhs_space: Value.BigIntSpace = undefined;3768 var rhs_space: Value.BigIntSpace = undefined;
3677 const lhs_bigint = lhs.toBigInt(&lhs_space);3769 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3678 const rhs_bigint = rhs.toBigInt(&rhs_space);3770 const rhs_bigint = rhs.toBigInt(&rhs_space, target);
3679 const limbs = try allocator.alloc(3771 const limbs = try allocator.alloc(
3680 std.math.big.Limb,3772 std.math.big.Limb,
3681 lhs_bigint.limbs.len + rhs_bigint.limbs.len,3773 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
...@@ -3690,34 +3782,41 @@ pub const Value = extern union {...@@ -3690,34 +3782,41 @@ pub const Value = extern union {
3690 return fromBigInt(allocator, result_bigint.toConst());3782 return fromBigInt(allocator, result_bigint.toConst());
3691 }3783 }
36923784
3693 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {3785 pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
3694 if (ty.zigTypeTag() == .Vector) {3786 if (ty.zigTypeTag() == .Vector) {
3695 const result_data = try allocator.alloc(Value, ty.vectorLen());3787 const result_data = try allocator.alloc(Value, ty.vectorLen());
3696 for (result_data) |*scalar, i| {3788 for (result_data) |*scalar, i| {
3697 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits);3789 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, bits, target);
3698 }3790 }
3699 return Value.Tag.aggregate.create(allocator, result_data);3791 return Value.Tag.aggregate.create(allocator, result_data);
3700 }3792 }
3701 return intTruncScalar(val, allocator, signedness, bits);3793 return intTruncScalar(val, allocator, signedness, bits, target);
3702 }3794 }
37033795
3704 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.3796 /// This variant may vectorize on `bits`. Asserts that `bits` is a (vector of) `u16`.
3705 pub fn intTruncBitsAsValue(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: Value) !Value {3797 pub fn intTruncBitsAsValue(
3798 val: Value,
3799 ty: Type,
3800 allocator: Allocator,
3801 signedness: std.builtin.Signedness,
3802 bits: Value,
3803 target: Target,
3804 ) !Value {
3706 if (ty.zigTypeTag() == .Vector) {3805 if (ty.zigTypeTag() == .Vector) {
3707 const result_data = try allocator.alloc(Value, ty.vectorLen());3806 const result_data = try allocator.alloc(Value, ty.vectorLen());
3708 for (result_data) |*scalar, i| {3807 for (result_data) |*scalar, i| {
3709 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt()));3808 scalar.* = try intTruncScalar(val.indexVectorlike(i), allocator, signedness, @intCast(u16, bits.indexVectorlike(i).toUnsignedInt(target)), target);
3710 }3809 }
3711 return Value.Tag.aggregate.create(allocator, result_data);3810 return Value.Tag.aggregate.create(allocator, result_data);
3712 }3811 }
3713 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt()));3812 return intTruncScalar(val, allocator, signedness, @intCast(u16, bits.toUnsignedInt(target)), target);
3714 }3813 }
37153814
3716 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16) !Value {3815 pub fn intTruncScalar(val: Value, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, target: Target) !Value {
3717 if (bits == 0) return Value.zero;3816 if (bits == 0) return Value.zero;
37183817
3719 var val_space: Value.BigIntSpace = undefined;3818 var val_space: Value.BigIntSpace = undefined;
3720 const val_bigint = val.toBigInt(&val_space);3819 const val_bigint = val.toBigInt(&val_space, target);
37213820
3722 const limbs = try allocator.alloc(3821 const limbs = try allocator.alloc(
3723 std.math.big.Limb,3822 std.math.big.Limb,
...@@ -3729,23 +3828,23 @@ pub const Value = extern union {...@@ -3729,23 +3828,23 @@ pub const Value = extern union {
3729 return fromBigInt(allocator, result_bigint.toConst());3828 return fromBigInt(allocator, result_bigint.toConst());
3730 }3829 }
37313830
3732 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3831 pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3733 if (ty.zigTypeTag() == .Vector) {3832 if (ty.zigTypeTag() == .Vector) {
3734 const result_data = try allocator.alloc(Value, ty.vectorLen());3833 const result_data = try allocator.alloc(Value, ty.vectorLen());
3735 for (result_data) |*scalar, i| {3834 for (result_data) |*scalar, i| {
3736 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3835 scalar.* = try shlScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3737 }3836 }
3738 return Value.Tag.aggregate.create(allocator, result_data);3837 return Value.Tag.aggregate.create(allocator, result_data);
3739 }3838 }
3740 return shlScalar(lhs, rhs, allocator);3839 return shlScalar(lhs, rhs, allocator, target);
3741 }3840 }
37423841
3743 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3842 pub fn shlScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3744 // TODO is this a performance issue? maybe we should try the operation without3843 // TODO is this a performance issue? maybe we should try the operation without
3745 // resorting to BigInt first.3844 // resorting to BigInt first.
3746 var lhs_space: Value.BigIntSpace = undefined;3845 var lhs_space: Value.BigIntSpace = undefined;
3747 const lhs_bigint = lhs.toBigInt(&lhs_space);3846 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3748 const shift = @intCast(usize, rhs.toUnsignedInt());3847 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3749 const limbs = try allocator.alloc(3848 const limbs = try allocator.alloc(
3750 std.math.big.Limb,3849 std.math.big.Limb,
3751 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,3850 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -3768,8 +3867,8 @@ pub const Value = extern union {...@@ -3768,8 +3867,8 @@ pub const Value = extern union {
3768 ) !OverflowArithmeticResult {3867 ) !OverflowArithmeticResult {
3769 const info = ty.intInfo(target);3868 const info = ty.intInfo(target);
3770 var lhs_space: Value.BigIntSpace = undefined;3869 var lhs_space: Value.BigIntSpace = undefined;
3771 const lhs_bigint = lhs.toBigInt(&lhs_space);3870 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3772 const shift = @intCast(usize, rhs.toUnsignedInt());3871 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3773 const limbs = try allocator.alloc(3872 const limbs = try allocator.alloc(
3774 std.math.big.Limb,3873 std.math.big.Limb,
3775 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,3874 lhs_bigint.limbs.len + (shift / (@sizeOf(std.math.big.Limb) * 8)) + 1,
...@@ -3819,8 +3918,8 @@ pub const Value = extern union {...@@ -3819,8 +3918,8 @@ pub const Value = extern union {
3819 const info = ty.intInfo(target);3918 const info = ty.intInfo(target);
38203919
3821 var lhs_space: Value.BigIntSpace = undefined;3920 var lhs_space: Value.BigIntSpace = undefined;
3822 const lhs_bigint = lhs.toBigInt(&lhs_space);3921 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3823 const shift = @intCast(usize, rhs.toUnsignedInt());3922 const shift = @intCast(usize, rhs.toUnsignedInt(target));
3824 const limbs = try arena.alloc(3923 const limbs = try arena.alloc(
3825 std.math.big.Limb,3924 std.math.big.Limb,
3826 std.math.big.int.calcTwosCompLimbCount(info.bits),3925 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -3858,29 +3957,29 @@ pub const Value = extern union {...@@ -3858,29 +3957,29 @@ pub const Value = extern union {
3858 arena: Allocator,3957 arena: Allocator,
3859 target: Target,3958 target: Target,
3860 ) !Value {3959 ) !Value {
3861 const shifted = try lhs.shl(rhs, ty, arena);3960 const shifted = try lhs.shl(rhs, ty, arena, target);
3862 const int_info = ty.intInfo(target);3961 const int_info = ty.intInfo(target);
3863 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits);3962 const truncated = try shifted.intTrunc(ty, arena, int_info.signedness, int_info.bits, target);
3864 return truncated;3963 return truncated;
3865 }3964 }
38663965
3867 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator) !Value {3966 pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, target: Target) !Value {
3868 if (ty.zigTypeTag() == .Vector) {3967 if (ty.zigTypeTag() == .Vector) {
3869 const result_data = try allocator.alloc(Value, ty.vectorLen());3968 const result_data = try allocator.alloc(Value, ty.vectorLen());
3870 for (result_data) |*scalar, i| {3969 for (result_data) |*scalar, i| {
3871 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator);3970 scalar.* = try shrScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), allocator, target);
3872 }3971 }
3873 return Value.Tag.aggregate.create(allocator, result_data);3972 return Value.Tag.aggregate.create(allocator, result_data);
3874 }3973 }
3875 return shrScalar(lhs, rhs, allocator);3974 return shrScalar(lhs, rhs, allocator, target);
3876 }3975 }
38773976
3878 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator) !Value {3977 pub fn shrScalar(lhs: Value, rhs: Value, allocator: Allocator, target: Target) !Value {
3879 // TODO is this a performance issue? maybe we should try the operation without3978 // TODO is this a performance issue? maybe we should try the operation without
3880 // resorting to BigInt first.3979 // resorting to BigInt first.
3881 var lhs_space: Value.BigIntSpace = undefined;3980 var lhs_space: Value.BigIntSpace = undefined;
3882 const lhs_bigint = lhs.toBigInt(&lhs_space);3981 const lhs_bigint = lhs.toBigInt(&lhs_space, target);
3883 const shift = @intCast(usize, rhs.toUnsignedInt());3982 const shift = @intCast(usize, rhs.toUnsignedInt(target));
38843983
3885 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));3984 const result_limbs = lhs_bigint.limbs.len -| (shift / (@sizeOf(std.math.big.Limb) * 8));
3886 if (result_limbs == 0) {3985 if (result_limbs == 0) {
test/behavior.zig+1-1
...@@ -125,6 +125,7 @@ test {...@@ -125,6 +125,7 @@ test {
125 _ = @import("behavior/src.zig");125 _ = @import("behavior/src.zig");
126 _ = @import("behavior/struct.zig");126 _ = @import("behavior/struct.zig");
127 _ = @import("behavior/struct_contains_null_ptr_itself.zig");127 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
128 _ = @import("behavior/struct_contains_slice_of_itself.zig");
128 _ = @import("behavior/switch.zig");129 _ = @import("behavior/switch.zig");
129 _ = @import("behavior/switch_prong_err_enum.zig");130 _ = @import("behavior/switch_prong_err_enum.zig");
130 _ = @import("behavior/switch_prong_implicit_cast.zig");131 _ = @import("behavior/switch_prong_implicit_cast.zig");
...@@ -179,6 +180,5 @@ test {...@@ -179,6 +180,5 @@ test {
179 _ = @import("behavior/bugs/6781.zig");180 _ = @import("behavior/bugs/6781.zig");
180 _ = @import("behavior/bugs/7027.zig");181 _ = @import("behavior/bugs/7027.zig");
181 _ = @import("behavior/select.zig");182 _ = @import("behavior/select.zig");
182 _ = @import("behavior/struct_contains_slice_of_itself.zig");
183 }183 }
184}184}
test/behavior/struct_contains_slice_of_itself.zig+9
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const expect = @import("std").testing.expect;2const expect = @import("std").testing.expect;
23
3const Node = struct {4const Node = struct {
...@@ -11,6 +12,10 @@ const NodeAligned = struct {...@@ -11,6 +12,10 @@ const NodeAligned = struct {
11};12};
1213
13test "struct contains slice of itself" {14test "struct contains slice of itself" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18
14 var other_nodes = [_]Node{19 var other_nodes = [_]Node{
15 Node{20 Node{
16 .payload = 31,21 .payload = 31,
...@@ -48,6 +53,10 @@ test "struct contains slice of itself" {...@@ -48,6 +53,10 @@ test "struct contains slice of itself" {
48}53}
4954
50test "struct contains aligned slice of itself" {55test "struct contains aligned slice of itself" {
56 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
59
51 var other_nodes = [_]NodeAligned{60 var other_nodes = [_]NodeAligned{
52 NodeAligned{61 NodeAligned{
53 .payload = 31,62 .payload = 31,
test/stage2/x86_64.zig+1-1
...@@ -1166,7 +1166,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1166,7 +1166,7 @@ pub fn addCases(ctx: *TestContext) !void {
1166 \\ _ = x;1166 \\ _ = x;
1167 \\}1167 \\}
1168 , &[_][]const u8{1168 , &[_][]const u8{
1169 ":2:9: error: variable of type '@Type(.Null)' must be const or comptime",1169 ":2:9: error: variable of type '@TypeOf(null)' must be const or comptime",
1170 });1170 });
1171 }1171 }
11721172