authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-17 22:54:56-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-17 22:54:56-07:00
log66245ac834969b84548ec325ee20a6910456e5ec
tree8cc868711c42c16843e0a7f5bc18c7e3de9c4629
parent38b3d4b00a693dd91af578d06dfe4ac6071d4536

stage2: Module and Sema are compiling again

Next up is reworking the seam between the LazySrcLoc emitted by Sema and the byte offsets currently expected by codegen. And then the big one: updating astgen.zig to use the new memory layout.

12 files changed, 1119 insertions(+), 965 deletions(-)

BRANCH_TODO+3-85
...@@ -13,6 +13,9 @@ Merge TODO list:...@@ -13,6 +13,9 @@ Merge TODO list:
13 * finish implementing SrcLoc byteOffset function13 * finish implementing SrcLoc byteOffset function
14 * audit Module.zig for use of token_starts - it should only be when14 * audit Module.zig for use of token_starts - it should only be when
15 resolving LazySrcLoc15 resolving LazySrcLoc
16 * audit all the .unneeded src locations
17 * audit the calls in codegen toSrcLocWithDecl specifically if there is inlined function
18 calls from other files.
1619
1720
18Performance optimizations to look into:21Performance optimizations to look into:
...@@ -30,71 +33,6 @@ Random snippets of code that I deleted and need to make sure get...@@ -30,71 +33,6 @@ Random snippets of code that I deleted and need to make sure get
30re-integrated appropriately:33re-integrated appropriately:
3134
3235
33fn zirArg(mod: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst {
34 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
35 const param_index = b.instructions.items.len;
36 const param_count = fn_ty.fnParamLen();
37 if (param_index >= param_count) {
38 return mod.fail(scope, inst.base.src, "parameter index {d} outside list of length {d}", .{
39 param_index,
40 param_count,
41 });
42 }
43 const param_type = fn_ty.fnParamType(param_index);
44 const name = try scope.arena().dupeZ(u8, inst.positionals.name);
45 return mod.addArg(b, inst.base.src, param_type, name);
46}
47
48
49fn zirReturnVoid(mod: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
50 const tracy = trace(@src());
51 defer tracy.end();
52 const b = try mod.requireFunctionBlock(scope, inst.base.src);
53 if (b.inlining) |inlining| {
54 // We are inlining a function call; rewrite the `retvoid` as a `breakvoid`.
55 const void_inst = try mod.constVoid(scope, inst.base.src);
56 try inlining.merges.results.append(mod.gpa, void_inst);
57 const br = try mod.addBr(b, inst.base.src, inlining.merges.block_inst, void_inst);
58 return &br.base;
59 }
60
61 if (b.func) |func| {
62 // Need to emit a compile error if returning void is not allowed.
63 const void_inst = try mod.constVoid(scope, inst.base.src);
64 const fn_ty = func.owner_decl.typed_value.most_recent.typed_value.ty;
65 const casted_void = try mod.coerce(scope, fn_ty.fnReturnType(), void_inst);
66 if (casted_void.ty.zigTypeTag() != .Void) {
67 return mod.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, casted_void);
68 }
69 }
70 return mod.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid);
71}
72
73
74fn zirReturn(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
75 const tracy = trace(@src());
76 defer tracy.end();
77 const operand = try resolveInst(mod, scope, inst.positionals.operand);
78 const b = try mod.requireFunctionBlock(scope, inst.base.src);
79
80 if (b.inlining) |inlining| {
81 // We are inlining a function call; rewrite the `ret` as a `break`.
82 try inlining.merges.results.append(mod.gpa, operand);
83 const br = try mod.addBr(b, inst.base.src, inlining.merges.block_inst, operand);
84 return &br.base;
85 }
86
87 return mod.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand);
88}
89
90fn zirPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
91 const tracy = trace(@src());
92 defer tracy.end();
93 return mod.constInst(scope, primitive.base.src, primitive.positionals.tag.toTypedValue());
94}
95
96
97
9836
99 /// Each Decl gets its own string interning, in order to avoid contention when37 /// Each Decl gets its own string interning, in order to avoid contention when
100 /// using multiple threads to analyze Decls in parallel. Any particular Decl will only38 /// using multiple threads to analyze Decls in parallel. Any particular Decl will only
...@@ -106,23 +44,3 @@ fn zirPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) Inn...@@ -106,23 +44,3 @@ fn zirPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) Inn
10644
10745
10846
109
110pub fn errSrcLoc(mod: *Module, scope: *Scope, src: LazySrcLoc) SrcLoc {
111 const file_scope = scope.getFileScope();
112 switch (src) {
113 .byte_offset => |off| return .{
114 .file_scope = file_scope,
115 .byte_offset = off,
116 },
117 .token_offset => |off| {
118 @panic("TODO errSrcLoc for token_offset");
119 },
120 .node_offset => |off| {
121 @panic("TODO errSrcLoc for node_offset");
122 },
123 .node_offset_var_decl_ty => |off| {
124 @panic("TODO errSrcLoc for node_offset_var_decl_ty");
125 },
126 }
127}
128
lib/std/zig/string_literal.zig+1-1
...@@ -22,7 +22,7 @@ pub const Result = union(enum) {...@@ -22,7 +22,7 @@ pub const Result = union(enum) {
22 /// Invalid unicode escape at this index.22 /// Invalid unicode escape at this index.
23 invalid_unicode_escape: usize,23 invalid_unicode_escape: usize,
24 /// The left brace at this index is missing a matching right brace.24 /// The left brace at this index is missing a matching right brace.
25 missing_matching_brace: usize,25 missing_matching_rbrace: usize,
26 /// Expected unicode digits at this index.26 /// Expected unicode digits at this index.
27 expected_unicode_digits: usize,27 expected_unicode_digits: usize,
28};28};
src/Module.zig+307-108
...@@ -237,10 +237,10 @@ pub const Decl = struct {...@@ -237,10 +237,10 @@ pub const Decl = struct {
237 }237 }
238 }238 }
239239
240 pub fn srcLoc(decl: *const Decl) SrcLoc {240 pub fn srcLoc(decl: *Decl) SrcLoc {
241 return .{241 return .{
242 .decl = decl,242 .container = .{ .decl = decl },
243 .byte_offset = 0,243 .lazy = .{ .node_offset = 0 },
244 };244 };
245 }245 }
246246
...@@ -352,7 +352,7 @@ pub const Fn = struct {...@@ -352,7 +352,7 @@ pub const Fn = struct {
352352
353 /// For debugging purposes.353 /// For debugging purposes.
354 pub fn dump(func: *Fn, mod: Module) void {354 pub fn dump(func: *Fn, mod: Module) void {
355 zir.dumpFn(mod, func);355 ir.dumpFn(mod, func);
356 }356 }
357};357};
358358
...@@ -381,12 +381,12 @@ pub const Scope = struct {...@@ -381,12 +381,12 @@ pub const Scope = struct {
381 /// Returns the arena Allocator associated with the Decl of the Scope.381 /// Returns the arena Allocator associated with the Decl of the Scope.
382 pub fn arena(scope: *Scope) *Allocator {382 pub fn arena(scope: *Scope) *Allocator {
383 switch (scope.tag) {383 switch (scope.tag) {
384 .block => return scope.cast(Block).?.arena,384 .block => return scope.cast(Block).?.sema.arena,
385 .gen_zir => return scope.cast(GenZir).?.arena,385 .gen_zir => return scope.cast(GenZir).?.zir_code.arena,
386 .local_val => return scope.cast(LocalVal).?.gen_zir.arena,386 .local_val => return scope.cast(LocalVal).?.gen_zir.zir_code.arena,
387 .local_ptr => return scope.cast(LocalPtr).?.gen_zir.arena,387 .local_ptr => return scope.cast(LocalPtr).?.gen_zir.zir_code.arena,
388 .gen_suspend => return scope.cast(GenZir).?.arena,388 .gen_suspend => return scope.cast(GenZir).?.zir_code.arena,
389 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.arena,389 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.arena,
390 .file => unreachable,390 .file => unreachable,
391 .container => unreachable,391 .container => unreachable,
392 .decl_ref => unreachable,392 .decl_ref => unreachable,
...@@ -399,12 +399,12 @@ pub const Scope = struct {...@@ -399,12 +399,12 @@ pub const Scope = struct {
399399
400 pub fn ownerDecl(scope: *Scope) ?*Decl {400 pub fn ownerDecl(scope: *Scope) ?*Decl {
401 return switch (scope.tag) {401 return switch (scope.tag) {
402 .block => scope.cast(Block).?.owner_decl,402 .block => scope.cast(Block).?.sema.owner_decl,
403 .gen_zir => scope.cast(GenZir).?.zir_code.decl,403 .gen_zir => scope.cast(GenZir).?.zir_code.decl,
404 .local_val => scope.cast(LocalVal).?.gen_zir.decl,404 .local_val => scope.cast(LocalVal).?.gen_zir.zir_code.decl,
405 .local_ptr => scope.cast(LocalPtr).?.gen_zir.decl,405 .local_ptr => scope.cast(LocalPtr).?.gen_zir.zir_code.decl,
406 .gen_suspend => return scope.cast(GenZir).?.decl,406 .gen_suspend => return scope.cast(GenZir).?.zir_code.decl,
407 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.decl,407 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.decl,
408 .file => null,408 .file => null,
409 .container => null,409 .container => null,
410 .decl_ref => scope.cast(DeclRef).?.decl,410 .decl_ref => scope.cast(DeclRef).?.decl,
...@@ -415,10 +415,10 @@ pub const Scope = struct {...@@ -415,10 +415,10 @@ pub const Scope = struct {
415 return switch (scope.tag) {415 return switch (scope.tag) {
416 .block => scope.cast(Block).?.src_decl,416 .block => scope.cast(Block).?.src_decl,
417 .gen_zir => scope.cast(GenZir).?.zir_code.decl,417 .gen_zir => scope.cast(GenZir).?.zir_code.decl,
418 .local_val => scope.cast(LocalVal).?.gen_zir.decl,418 .local_val => scope.cast(LocalVal).?.gen_zir.zir_code.decl,
419 .local_ptr => scope.cast(LocalPtr).?.gen_zir.decl,419 .local_ptr => scope.cast(LocalPtr).?.gen_zir.zir_code.decl,
420 .gen_suspend => return scope.cast(GenZir).?.decl,420 .gen_suspend => return scope.cast(GenZir).?.zir_code.decl,
421 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.decl,421 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.decl,
422 .file => null,422 .file => null,
423 .container => null,423 .container => null,
424 .decl_ref => scope.cast(DeclRef).?.decl,424 .decl_ref => scope.cast(DeclRef).?.decl,
...@@ -463,11 +463,11 @@ pub const Scope = struct {...@@ -463,11 +463,11 @@ pub const Scope = struct {
463 .file => return &scope.cast(File).?.tree,463 .file => return &scope.cast(File).?.tree,
464 .block => return &scope.cast(Block).?.src_decl.container.file_scope.tree,464 .block => return &scope.cast(Block).?.src_decl.container.file_scope.tree,
465 .gen_zir => return &scope.cast(GenZir).?.decl.container.file_scope.tree,465 .gen_zir => return &scope.cast(GenZir).?.decl.container.file_scope.tree,
466 .local_val => return &scope.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,466 .local_val => return &scope.cast(LocalVal).?.gen_zir.zir_code.decl.container.file_scope.tree,
467 .local_ptr => return &scope.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,467 .local_ptr => return &scope.cast(LocalPtr).?.gen_zir.zir_code.decl.container.file_scope.tree,
468 .container => return &scope.cast(Container).?.file_scope.tree,468 .container => return &scope.cast(Container).?.file_scope.tree,
469 .gen_suspend => return &scope.cast(GenZir).?.decl.container.file_scope.tree,469 .gen_suspend => return &scope.cast(GenZir).?.decl.container.file_scope.tree,
470 .gen_nosuspend => return &scope.cast(Nosuspend).?.gen_zir.decl.container.file_scope.tree,470 .gen_nosuspend => return &scope.cast(Nosuspend).?.gen_zir.zir_code.decl.container.file_scope.tree,
471 .decl_ref => return &scope.cast(DeclRef).?.decl.container.file_scope.tree,471 .decl_ref => return &scope.cast(DeclRef).?.decl.container.file_scope.tree,
472 }472 }
473 }473 }
...@@ -529,7 +529,7 @@ pub const Scope = struct {...@@ -529,7 +529,7 @@ pub const Scope = struct {
529 .block => return @fieldParentPtr(Block, "base", cur).src_decl.container.file_scope,529 .block => return @fieldParentPtr(Block, "base", cur).src_decl.container.file_scope,
530 .gen_suspend => @fieldParentPtr(GenZir, "base", cur).parent,530 .gen_suspend => @fieldParentPtr(GenZir, "base", cur).parent,
531 .gen_nosuspend => @fieldParentPtr(Nosuspend, "base", cur).parent,531 .gen_nosuspend => @fieldParentPtr(Nosuspend, "base", cur).parent,
532 .decl_ref => @fieldParentPtr(DeclRef, "base", cur).decl.container.file_scope,532 .decl_ref => return @fieldParentPtr(DeclRef, "base", cur).decl.container.file_scope,
533 };533 };
534 }534 }
535 }535 }
...@@ -730,11 +730,6 @@ pub const Scope = struct {...@@ -730,11 +730,6 @@ pub const Scope = struct {
730 pub const Inlining = struct {730 pub const Inlining = struct {
731 /// Shared state among the entire inline/comptime call stack.731 /// Shared state among the entire inline/comptime call stack.
732 shared: *Shared,732 shared: *Shared,
733 /// We use this to count from 0 so that arg instructions know
734 /// which parameter index they are, without having to store
735 /// a parameter index with each arg instruction.
736 param_index: usize,
737 casted_args: []*ir.Inst,
738 merges: Merges,733 merges: Merges,
739734
740 pub const Shared = struct {735 pub const Shared = struct {
...@@ -762,16 +757,12 @@ pub const Scope = struct {...@@ -762,16 +757,12 @@ pub const Scope = struct {
762 pub fn makeSubBlock(parent: *Block) Block {757 pub fn makeSubBlock(parent: *Block) Block {
763 return .{758 return .{
764 .parent = parent,759 .parent = parent,
765 .inst_map = parent.inst_map,760 .sema = parent.sema,
766 .func = parent.func,
767 .owner_decl = parent.owner_decl,
768 .src_decl = parent.src_decl,761 .src_decl = parent.src_decl,
769 .instructions = .{},762 .instructions = .{},
770 .arena = parent.arena,
771 .label = null,763 .label = null,
772 .inlining = parent.inlining,764 .inlining = parent.inlining,
773 .is_comptime = parent.is_comptime,765 .is_comptime = parent.is_comptime,
774 .branch_quota = parent.branch_quota,
775 };766 };
776 }767 }
777768
...@@ -795,7 +786,7 @@ pub const Scope = struct {...@@ -795,7 +786,7 @@ pub const Scope = struct {
795 ty: Type,786 ty: Type,
796 comptime tag: ir.Inst.Tag,787 comptime tag: ir.Inst.Tag,
797 ) !*ir.Inst {788 ) !*ir.Inst {
798 const inst = try block.arena.create(tag.Type());789 const inst = try block.sema.arena.create(tag.Type());
799 inst.* = .{790 inst.* = .{
800 .base = .{791 .base = .{
801 .tag = tag,792 .tag = tag,
...@@ -814,7 +805,7 @@ pub const Scope = struct {...@@ -814,7 +805,7 @@ pub const Scope = struct {
814 tag: ir.Inst.Tag,805 tag: ir.Inst.Tag,
815 operand: *ir.Inst,806 operand: *ir.Inst,
816 ) !*ir.Inst {807 ) !*ir.Inst {
817 const inst = try block.arena.create(ir.Inst.UnOp);808 const inst = try block.sema.arena.create(ir.Inst.UnOp);
818 inst.* = .{809 inst.* = .{
819 .base = .{810 .base = .{
820 .tag = tag,811 .tag = tag,
...@@ -835,7 +826,7 @@ pub const Scope = struct {...@@ -835,7 +826,7 @@ pub const Scope = struct {
835 lhs: *ir.Inst,826 lhs: *ir.Inst,
836 rhs: *ir.Inst,827 rhs: *ir.Inst,
837 ) !*ir.Inst {828 ) !*ir.Inst {
838 const inst = try block.arena.create(ir.Inst.BinOp);829 const inst = try block.sema.arena.create(ir.Inst.BinOp);
839 inst.* = .{830 inst.* = .{
840 .base = .{831 .base = .{
841 .tag = tag,832 .tag = tag,
...@@ -854,7 +845,7 @@ pub const Scope = struct {...@@ -854,7 +845,7 @@ pub const Scope = struct {
854 target_block: *ir.Inst.Block,845 target_block: *ir.Inst.Block,
855 operand: *ir.Inst,846 operand: *ir.Inst,
856 ) !*ir.Inst.Br {847 ) !*ir.Inst.Br {
857 const inst = try scope_block.arena.create(ir.Inst.Br);848 const inst = try scope_block.sema.arena.create(ir.Inst.Br);
858 inst.* = .{849 inst.* = .{
859 .base = .{850 .base = .{
860 .tag = .br,851 .tag = .br,
...@@ -875,7 +866,7 @@ pub const Scope = struct {...@@ -875,7 +866,7 @@ pub const Scope = struct {
875 then_body: ir.Body,866 then_body: ir.Body,
876 else_body: ir.Body,867 else_body: ir.Body,
877 ) !*ir.Inst {868 ) !*ir.Inst {
878 const inst = try block.arena.create(ir.Inst.CondBr);869 const inst = try block.sema.arena.create(ir.Inst.CondBr);
879 inst.* = .{870 inst.* = .{
880 .base = .{871 .base = .{
881 .tag = .condbr,872 .tag = .condbr,
...@@ -897,7 +888,7 @@ pub const Scope = struct {...@@ -897,7 +888,7 @@ pub const Scope = struct {
897 func: *ir.Inst,888 func: *ir.Inst,
898 args: []const *ir.Inst,889 args: []const *ir.Inst,
899 ) !*ir.Inst {890 ) !*ir.Inst {
900 const inst = try block.arena.create(ir.Inst.Call);891 const inst = try block.sema.arena.create(ir.Inst.Call);
901 inst.* = .{892 inst.* = .{
902 .base = .{893 .base = .{
903 .tag = .call,894 .tag = .call,
...@@ -918,7 +909,7 @@ pub const Scope = struct {...@@ -918,7 +909,7 @@ pub const Scope = struct {
918 cases: []ir.Inst.SwitchBr.Case,909 cases: []ir.Inst.SwitchBr.Case,
919 else_body: ir.Body,910 else_body: ir.Body,
920 ) !*ir.Inst {911 ) !*ir.Inst {
921 const inst = try block.arena.create(ir.Inst.SwitchBr);912 const inst = try block.sema.arena.create(ir.Inst.SwitchBr);
922 inst.* = .{913 inst.* = .{
923 .base = .{914 .base = .{
924 .tag = .switchbr,915 .tag = .switchbr,
...@@ -946,7 +937,7 @@ pub const Scope = struct {...@@ -946,7 +937,7 @@ pub const Scope = struct {
946 zir_code: *WipZirCode,937 zir_code: *WipZirCode,
947 /// Keeps track of the list of instructions in this scope only. References938 /// Keeps track of the list of instructions in this scope only. References
948 /// to instructions in `zir_code`.939 /// to instructions in `zir_code`.
949 instructions: std.ArrayListUnmanaged(zir.Inst.Index) = .{},940 instructions: std.ArrayListUnmanaged(zir.Inst.Ref) = .{},
950 label: ?Label = null,941 label: ?Label = null,
951 break_block: zir.Inst.Index = 0,942 break_block: zir.Inst.Index = 0,
952 continue_block: zir.Inst.Index = 0,943 continue_block: zir.Inst.Index = 0,
...@@ -978,12 +969,12 @@ pub const Scope = struct {...@@ -978,12 +969,12 @@ pub const Scope = struct {
978 };969 };
979970
980 pub fn addFnTypeCc(gz: *GenZir, args: struct {971 pub fn addFnTypeCc(gz: *GenZir, args: struct {
981 param_types: []const zir.Inst.Index,972 param_types: []const zir.Inst.Ref,
982 ret_ty: zir.Inst.Index,973 ret_ty: zir.Inst.Ref,
983 cc: zir.Inst.Index,974 cc: zir.Inst.Ref,
984 }) !zir.Inst.Index {975 }) !zir.Inst.Index {
985 const gpa = gz.zir_code.gpa;976 const gpa = gz.zir_code.gpa;
986 try gz.instructions.ensureCapacity(gpa, gz.instructions.items + 1);977 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
987 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);978 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
988 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +979 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
989 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);980 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);
...@@ -994,7 +985,7 @@ pub const Scope = struct {...@@ -994,7 +985,7 @@ pub const Scope = struct {
994 }) catch unreachable; // Capacity is ensured above.985 }) catch unreachable; // Capacity is ensured above.
995 gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types);986 gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types);
996987
997 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);988 const new_index = gz.zir_code.instructions.len;
998 gz.zir_code.instructions.appendAssumeCapacity(.{989 gz.zir_code.instructions.appendAssumeCapacity(.{
999 .tag = .fn_type_cc,990 .tag = .fn_type_cc,
1000 .data = .{ .fn_type = .{991 .data = .{ .fn_type = .{
...@@ -1002,17 +993,18 @@ pub const Scope = struct {...@@ -1002,17 +993,18 @@ pub const Scope = struct {
1002 .payload_index = payload_index,993 .payload_index = payload_index,
1003 } },994 } },
1004 });995 });
1005 gz.instructions.appendAssumeCapacity(new_index);996 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1006 return new_index;997 gz.instructions.appendAssumeCapacity(result);
998 return result;
1007 }999 }
10081000
1009 pub fn addFnType(1001 pub fn addFnType(
1010 gz: *GenZir,1002 gz: *GenZir,
1011 ret_ty: zir.Inst.Index,1003 ret_ty: zir.Inst.Ref,
1012 param_types: []const zir.Inst.Index,1004 param_types: []const zir.Inst.Ref,
1013 ) !zir.Inst.Index {1005 ) !zir.Inst.Index {
1014 const gpa = gz.zir_code.gpa;1006 const gpa = gz.zir_code.gpa;
1015 try gz.instructions.ensureCapacity(gpa, gz.instructions.items + 1);1007 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1016 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);1008 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1017 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +1009 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
1018 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);1010 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);
...@@ -1022,7 +1014,7 @@ pub const Scope = struct {...@@ -1022,7 +1014,7 @@ pub const Scope = struct {
1022 }) catch unreachable; // Capacity is ensured above.1014 }) catch unreachable; // Capacity is ensured above.
1023 gz.zir_code.extra.appendSliceAssumeCapacity(param_types);1015 gz.zir_code.extra.appendSliceAssumeCapacity(param_types);
10241016
1025 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);1017 const new_index = gz.zir_code.instructions.len;
1026 gz.zir_code.instructions.appendAssumeCapacity(.{1018 gz.zir_code.instructions.appendAssumeCapacity(.{
1027 .tag = .fn_type_cc,1019 .tag = .fn_type_cc,
1028 .data = .{ .fn_type = .{1020 .data = .{ .fn_type = .{
...@@ -1030,29 +1022,118 @@ pub const Scope = struct {...@@ -1030,29 +1022,118 @@ pub const Scope = struct {
1030 .payload_index = payload_index,1022 .payload_index = payload_index,
1031 } },1023 } },
1032 });1024 });
1033 gz.instructions.appendAssumeCapacity(new_index);1025 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1034 return new_index;1026 gz.instructions.appendAssumeCapacity(result);
1027 return result;
1035 }1028 }
10361029
1037 pub fn addRetTok(1030 pub fn addRetTok(
1038 gz: *GenZir,1031 gz: *GenZir,
1039 operand: zir.Inst.Index,1032 operand: zir.Inst.Ref,
1040 src_tok: ast.TokenIndex,1033 /// Absolute token index. This function does the conversion to Decl offset.
1034 abs_tok_index: ast.TokenIndex,
1041 ) !zir.Inst.Index {1035 ) !zir.Inst.Index {
1042 const gpa = gz.zir_code.gpa;1036 const gpa = gz.zir_code.gpa;
1043 try gz.instructions.ensureCapacity(gpa, gz.instructions.items + 1);1037 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1044 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);1038 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
10451039
1046 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);1040 const new_index = gz.zir_code.instructions.len;
1047 gz.zir_code.instructions.appendAssumeCapacity(.{1041 gz.zir_code.instructions.appendAssumeCapacity(.{
1048 .tag = .ret_tok,1042 .tag = .ret_tok,
1049 .data = .{ .fn_type = .{1043 .data = .{ .fn_type = .{
1050 .operand = operand,1044 .operand = operand,
1051 .src_tok = src_tok,1045 .src_tok = abs_tok_index - gz.zir_code.decl.srcToken(),
1052 } },1046 } },
1053 });1047 });
1054 gz.instructions.appendAssumeCapacity(new_index);1048 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1055 return new_index;1049 gz.instructions.appendAssumeCapacity(result);
1050 return result;
1051 }
1052
1053 pub fn addInt(gz: *GenZir, integer: u64) !zir.Inst.Index {
1054 const gpa = gz.zir_code.gpa;
1055 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1056 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1057
1058 const new_index = gz.zir_code.instructions.len;
1059 gz.zir_code.instructions.appendAssumeCapacity(.{
1060 .tag = .int,
1061 .data = .{ .int = integer },
1062 });
1063 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1064 gz.instructions.appendAssumeCapacity(result);
1065 return result;
1066 }
1067
1068 pub fn addUnNode(
1069 gz: *GenZir,
1070 tag: zir.Inst.Tag,
1071 operand: zir.Inst.Ref,
1072 /// Absolute node index. This function does the conversion to offset from Decl.
1073 abs_node_index: ast.Node.Index,
1074 ) !zir.Inst.Ref {
1075 const gpa = gz.zir_code.gpa;
1076 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1077 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1078
1079 const new_index = gz.zir_code.instructions.len;
1080 gz.zir_code.instructions.appendAssumeCapacity(.{
1081 .tag = tag,
1082 .data = .{ .un_node = .{
1083 .operand = operand,
1084 .src_node = abs_node_index - gz.zir_code.decl.srcNode(),
1085 } },
1086 });
1087 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1088 gz.instructions.appendAssumeCapacity(result);
1089 return result;
1090 }
1091
1092 pub fn addUnTok(
1093 gz: *GenZir,
1094 tag: zir.Inst.Tag,
1095 operand: zir.Inst.Ref,
1096 /// Absolute token index. This function does the conversion to Decl offset.
1097 abs_tok_index: ast.TokenIndex,
1098 ) !zir.Inst.Ref {
1099 const gpa = gz.zir_code.gpa;
1100 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1101 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1102
1103 const new_index = gz.zir_code.instructions.len;
1104 gz.zir_code.instructions.appendAssumeCapacity(.{
1105 .tag = tag,
1106 .data = .{ .un_tok = .{
1107 .operand = operand,
1108 .src_tok = abs_tok_index - gz.zir_code.decl.srcToken(),
1109 } },
1110 });
1111 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1112 gz.instructions.appendAssumeCapacity(result);
1113 return result;
1114 }
1115
1116 pub fn addBin(
1117 gz: *GenZir,
1118 tag: zir.Inst.Tag,
1119 lhs: zir.Inst.Ref,
1120 rhs: zir.Inst.Ref,
1121 ) !zir.Inst.Ref {
1122 const gpa = gz.zir_code.gpa;
1123 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1124 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1125
1126 const new_index = gz.zir_code.instructions.len;
1127 gz.zir_code.instructions.appendAssumeCapacity(.{
1128 .tag = tag,
1129 .data = .{ .bin = .{
1130 .lhs = lhs,
1131 .rhs = rhs,
1132 } },
1133 });
1134 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1135 gz.instructions.appendAssumeCapacity(result);
1136 return result;
1056 }1137 }
1057 };1138 };
10581139
...@@ -1106,7 +1187,9 @@ pub const WipZirCode = struct {...@@ -1106,7 +1187,9 @@ pub const WipZirCode = struct {
1106 instructions: std.MultiArrayList(zir.Inst) = .{},1187 instructions: std.MultiArrayList(zir.Inst) = .{},
1107 string_bytes: std.ArrayListUnmanaged(u8) = .{},1188 string_bytes: std.ArrayListUnmanaged(u8) = .{},
1108 extra: std.ArrayListUnmanaged(u32) = .{},1189 extra: std.ArrayListUnmanaged(u32) = .{},
1109 arg_count: usize = 0,1190 /// The end of special indexes. `zir.Inst.Ref` subtracts against this number to convert
1191 /// to `zir.Inst.Index`. The default here is correct if there are 0 parameters.
1192 ref_start_index: usize = zir.const_inst_list.len,
1110 decl: *Decl,1193 decl: *Decl,
1111 gpa: *Allocator,1194 gpa: *Allocator,
1112 arena: *Allocator,1195 arena: *Allocator,
...@@ -1189,6 +1272,7 @@ pub const SrcLoc = struct {...@@ -1189,6 +1272,7 @@ pub const SrcLoc = struct {
11891272
1190 .byte_abs,1273 .byte_abs,
1191 .token_abs,1274 .token_abs,
1275 .node_abs,
1192 => src_loc.container.file_scope,1276 => src_loc.container.file_scope,
11931277
1194 .byte_offset,1278 .byte_offset,
...@@ -1201,6 +1285,13 @@ pub const SrcLoc = struct {...@@ -1201,6 +1285,13 @@ pub const SrcLoc = struct {
1201 .node_offset_builtin_call_argn,1285 .node_offset_builtin_call_argn,
1202 .node_offset_array_access_index,1286 .node_offset_array_access_index,
1203 .node_offset_slice_sentinel,1287 .node_offset_slice_sentinel,
1288 .node_offset_call_func,
1289 .node_offset_field_name,
1290 .node_offset_deref_ptr,
1291 .node_offset_asm_source,
1292 .node_offset_asm_ret_ty,
1293 .node_offset_if_cond,
1294 .node_offset_anyframe_type,
1204 => src_loc.container.decl.container.file_scope,1295 => src_loc.container.decl.container.file_scope,
1205 };1296 };
1206 }1297 }
...@@ -1218,6 +1309,13 @@ pub const SrcLoc = struct {...@@ -1218,6 +1309,13 @@ pub const SrcLoc = struct {
1218 const token_starts = tree.tokens.items(.start);1309 const token_starts = tree.tokens.items(.start);
1219 return token_starts[tok_index];1310 return token_starts[tok_index];
1220 },1311 },
1312 .node_abs => |node_index| {
1313 const file_scope = src_loc.container.file_scope;
1314 const tree = try mod.getAstTree(file_scope);
1315 const token_starts = tree.tokens.items(.start);
1316 const tok_index = tree.firstToken(node_index);
1317 return token_starts[tok_index];
1318 },
1221 .byte_offset => |byte_off| {1319 .byte_offset => |byte_off| {
1222 const decl = src_loc.container.decl;1320 const decl = src_loc.container.decl;
1223 return decl.srcByteOffset() + byte_off;1321 return decl.srcByteOffset() + byte_off;
...@@ -1244,6 +1342,13 @@ pub const SrcLoc = struct {...@@ -1244,6 +1342,13 @@ pub const SrcLoc = struct {
1244 .node_offset_builtin_call_argn => unreachable, // Handled specially in `Sema`.1342 .node_offset_builtin_call_argn => unreachable, // Handled specially in `Sema`.
1245 .node_offset_array_access_index => @panic("TODO"),1343 .node_offset_array_access_index => @panic("TODO"),
1246 .node_offset_slice_sentinel => @panic("TODO"),1344 .node_offset_slice_sentinel => @panic("TODO"),
1345 .node_offset_call_func => @panic("TODO"),
1346 .node_offset_field_name => @panic("TODO"),
1347 .node_offset_deref_ptr => @panic("TODO"),
1348 .node_offset_asm_source => @panic("TODO"),
1349 .node_offset_asm_ret_ty => @panic("TODO"),
1350 .node_offset_if_cond => @panic("TODO"),
1351 .node_offset_anyframe_type => @panic("TODO"),
1247 }1352 }
1248 }1353 }
1249};1354};
...@@ -1276,6 +1381,10 @@ pub const LazySrcLoc = union(enum) {...@@ -1276,6 +1381,10 @@ pub const LazySrcLoc = union(enum) {
1276 /// offset from 0. The source file is determined contextually.1381 /// offset from 0. The source file is determined contextually.
1277 /// Inside a `SrcLoc`, the `file_scope` union field will be active.1382 /// Inside a `SrcLoc`, the `file_scope` union field will be active.
1278 token_abs: u32,1383 token_abs: u32,
1384 /// The source location points to an AST node within a source file,
1385 /// offset from 0. The source file is determined contextually.
1386 /// Inside a `SrcLoc`, the `file_scope` union field will be active.
1387 node_abs: u32,
1279 /// The source location points to a byte offset within a source file,1388 /// The source location points to a byte offset within a source file,
1280 /// offset from the byte offset of the Decl within the file.1389 /// offset from the byte offset of the Decl within the file.
1281 /// The Decl is determined contextually.1390 /// The Decl is determined contextually.
...@@ -1322,6 +1431,48 @@ pub const LazySrcLoc = union(enum) {...@@ -1322,6 +1431,48 @@ pub const LazySrcLoc = union(enum) {
1322 /// to the sentinel expression.1431 /// to the sentinel expression.
1323 /// The Decl is determined contextually.1432 /// The Decl is determined contextually.
1324 node_offset_slice_sentinel: u32,1433 node_offset_slice_sentinel: u32,
1434 /// The source location points to the callee expression of a function
1435 /// call expression, found by taking this AST node index offset from the containing
1436 /// Decl AST node, which points to a function call AST node. Next, navigate
1437 /// to the callee expression.
1438 /// The Decl is determined contextually.
1439 node_offset_call_func: u32,
1440 /// The source location points to the field name of a field access expression,
1441 /// found by taking this AST node index offset from the containing
1442 /// Decl AST node, which points to a field access AST node. Next, navigate
1443 /// to the field name token.
1444 /// The Decl is determined contextually.
1445 node_offset_field_name: u32,
1446 /// The source location points to the pointer of a pointer deref expression,
1447 /// found by taking this AST node index offset from the containing
1448 /// Decl AST node, which points to a pointer deref AST node. Next, navigate
1449 /// to the pointer expression.
1450 /// The Decl is determined contextually.
1451 node_offset_deref_ptr: u32,
1452 /// The source location points to the assembly source code of an inline assembly
1453 /// expression, found by taking this AST node index offset from the containing
1454 /// Decl AST node, which points to inline assembly AST node. Next, navigate
1455 /// to the asm template source code.
1456 /// The Decl is determined contextually.
1457 node_offset_asm_source: u32,
1458 /// The source location points to the return type of an inline assembly
1459 /// expression, found by taking this AST node index offset from the containing
1460 /// Decl AST node, which points to inline assembly AST node. Next, navigate
1461 /// to the return type expression.
1462 /// The Decl is determined contextually.
1463 node_offset_asm_ret_ty: u32,
1464 /// The source location points to the condition expression of an if
1465 /// expression, found by taking this AST node index offset from the containing
1466 /// Decl AST node, which points to an if expression AST node. Next, navigate
1467 /// to the condition expression.
1468 /// The Decl is determined contextually.
1469 node_offset_if_cond: u32,
1470 /// The source location points to the type expression of an `anyframe->T`
1471 /// expression, found by taking this AST node index offset from the containing
1472 /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
1473 /// to the type expression.
1474 /// The Decl is determined contextually.
1475 node_offset_anyframe_type: u32,
13251476
1326 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.1477 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
1327 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {1478 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
...@@ -1330,6 +1481,7 @@ pub const LazySrcLoc = union(enum) {...@@ -1330,6 +1481,7 @@ pub const LazySrcLoc = union(enum) {
1330 .todo,1481 .todo,
1331 .byte_abs,1482 .byte_abs,
1332 .token_abs,1483 .token_abs,
1484 .node_abs,
1333 => .{1485 => .{
1334 .container = .{ .file_scope = scope.getFileScope() },1486 .container = .{ .file_scope = scope.getFileScope() },
1335 .lazy = lazy,1487 .lazy = lazy,
...@@ -1345,12 +1497,56 @@ pub const LazySrcLoc = union(enum) {...@@ -1345,12 +1497,56 @@ pub const LazySrcLoc = union(enum) {
1345 .node_offset_builtin_call_argn,1497 .node_offset_builtin_call_argn,
1346 .node_offset_array_access_index,1498 .node_offset_array_access_index,
1347 .node_offset_slice_sentinel,1499 .node_offset_slice_sentinel,
1500 .node_offset_call_func,
1501 .node_offset_field_name,
1502 .node_offset_deref_ptr,
1503 .node_offset_asm_source,
1504 .node_offset_asm_ret_ty,
1505 .node_offset_if_cond,
1506 .node_offset_anyframe_type,
1348 => .{1507 => .{
1349 .container = .{ .decl = scope.srcDecl().? },1508 .container = .{ .decl = scope.srcDecl().? },
1350 .lazy = lazy,1509 .lazy = lazy,
1351 },1510 },
1352 };1511 };
1353 }1512 }
1513
1514 /// Upgrade to a `SrcLoc` based on the `Decl` provided.
1515 pub fn toSrcLocWithDecl(lazy: LazySrcLoc, decl: *Decl) SrcLoc {
1516 return switch (lazy) {
1517 .unneeded,
1518 .todo,
1519 .byte_abs,
1520 .token_abs,
1521 .node_abs,
1522 => .{
1523 .container = .{ .file_scope = decl.getFileScope() },
1524 .lazy = lazy,
1525 },
1526
1527 .byte_offset,
1528 .token_offset,
1529 .node_offset,
1530 .node_offset_var_decl_ty,
1531 .node_offset_for_cond,
1532 .node_offset_builtin_call_arg0,
1533 .node_offset_builtin_call_arg1,
1534 .node_offset_builtin_call_argn,
1535 .node_offset_array_access_index,
1536 .node_offset_slice_sentinel,
1537 .node_offset_call_func,
1538 .node_offset_field_name,
1539 .node_offset_deref_ptr,
1540 .node_offset_asm_source,
1541 .node_offset_asm_ret_ty,
1542 .node_offset_if_cond,
1543 .node_offset_anyframe_type,
1544 => .{
1545 .container = .{ .decl = decl },
1546 .lazy = lazy,
1547 },
1548 };
1549 }
1354};1550};
13551551
1356pub const InnerError = error{ OutOfMemory, AnalysisFail };1552pub const InnerError = error{ OutOfMemory, AnalysisFail };
...@@ -2255,7 +2451,7 @@ fn astgenAndSemaVarDecl(...@@ -2255,7 +2451,7 @@ fn astgenAndSemaVarDecl(
2255 return type_changed;2451 return type_changed;
2256}2452}
22572453
2258fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void {2454pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void {
2259 try depender.dependencies.ensureCapacity(mod.gpa, depender.dependencies.items().len + 1);2455 try depender.dependencies.ensureCapacity(mod.gpa, depender.dependencies.items().len + 1);
2260 try dependee.dependants.ensureCapacity(mod.gpa, dependee.dependants.items().len + 1);2456 try dependee.dependants.ensureCapacity(mod.gpa, dependee.dependants.items().len + 1);
22612457
...@@ -3144,8 +3340,8 @@ pub fn lookupDeclName(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Dec...@@ -3144,8 +3340,8 @@ pub fn lookupDeclName(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Dec
3144 return mod.decl_table.get(name_hash);3340 return mod.decl_table.get(name_hash);
3145}3341}
31463342
3147fn makeIntType(mod: *Module, scope: *Scope, signed: bool, bits: u16) !Type {3343pub fn makeIntType(arena: *Allocator, signed: bool, bits: u16) !Type {
3148 const int_payload = try scope.arena().create(Type.Payload.Bits);3344 const int_payload = try arena.create(Type.Payload.Bits);
3149 int_payload.* = .{3345 int_payload.* = .{
3150 .base = .{3346 .base = .{
3151 .tag = if (signed) .int_signed else .int_unsigned,3347 .tag = if (signed) .int_signed else .int_unsigned,
...@@ -3252,45 +3448,51 @@ pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) In...@@ -3252,45 +3448,51 @@ pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) In
3252 if (inlining.shared.caller) |func| {3448 if (inlining.shared.caller) |func| {
3253 func.state = .sema_failure;3449 func.state = .sema_failure;
3254 } else {3450 } else {
3255 block.owner_decl.analysis = .sema_failure;3451 block.sema.owner_decl.analysis = .sema_failure;
3256 block.owner_decl.generation = mod.generation;3452 block.sema.owner_decl.generation = mod.generation;
3257 }3453 }
3258 } else {3454 } else {
3259 if (block.func) |func| {3455 if (block.sema.func) |func| {
3260 func.state = .sema_failure;3456 func.state = .sema_failure;
3261 } else {3457 } else {
3262 block.owner_decl.analysis = .sema_failure;3458 block.sema.owner_decl.analysis = .sema_failure;
3263 block.owner_decl.generation = mod.generation;3459 block.sema.owner_decl.generation = mod.generation;
3264 }3460 }
3265 }3461 }
3266 mod.failed_decls.putAssumeCapacityNoClobber(block.owner_decl, err_msg);3462 mod.failed_decls.putAssumeCapacityNoClobber(block.sema.owner_decl, err_msg);
3267 },3463 },
3268 .gen_zir, .gen_suspend => {3464 .gen_zir, .gen_suspend => {
3269 const gen_zir = scope.cast(Scope.GenZir).?;3465 const gen_zir = scope.cast(Scope.GenZir).?;
3270 gen_zir.decl.analysis = .sema_failure;3466 gen_zir.zir_code.decl.analysis = .sema_failure;
3271 gen_zir.decl.generation = mod.generation;3467 gen_zir.zir_code.decl.generation = mod.generation;
3272 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);3468 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
3273 },3469 },
3274 .local_val => {3470 .local_val => {
3275 const gen_zir = scope.cast(Scope.LocalVal).?.gen_zir;3471 const gen_zir = scope.cast(Scope.LocalVal).?.gen_zir;
3276 gen_zir.decl.analysis = .sema_failure;3472 gen_zir.zir_code.decl.analysis = .sema_failure;
3277 gen_zir.decl.generation = mod.generation;3473 gen_zir.zir_code.decl.generation = mod.generation;
3278 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);3474 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
3279 },3475 },
3280 .local_ptr => {3476 .local_ptr => {
3281 const gen_zir = scope.cast(Scope.LocalPtr).?.gen_zir;3477 const gen_zir = scope.cast(Scope.LocalPtr).?.gen_zir;
3282 gen_zir.decl.analysis = .sema_failure;3478 gen_zir.zir_code.decl.analysis = .sema_failure;
3283 gen_zir.decl.generation = mod.generation;3479 gen_zir.zir_code.decl.generation = mod.generation;
3284 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);3480 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
3285 },3481 },
3286 .gen_nosuspend => {3482 .gen_nosuspend => {
3287 const gen_zir = scope.cast(Scope.Nosuspend).?.gen_zir;3483 const gen_zir = scope.cast(Scope.Nosuspend).?.gen_zir;
3288 gen_zir.decl.analysis = .sema_failure;3484 gen_zir.zir_code.decl.analysis = .sema_failure;
3289 gen_zir.decl.generation = mod.generation;3485 gen_zir.zir_code.decl.generation = mod.generation;
3290 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);3486 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
3291 },3487 },
3292 .file => unreachable,3488 .file => unreachable,
3293 .container => unreachable,3489 .container => unreachable,
3490 .decl_ref => {
3491 const decl_ref = scope.cast(Scope.DeclRef).?;
3492 decl_ref.decl.analysis = .sema_failure;
3493 decl_ref.decl.generation = mod.generation;
3494 mod.failed_decls.putAssumeCapacityNoClobber(decl_ref.decl, err_msg);
3495 },
3294 }3496 }
3295 return error.AnalysisFail;3497 return error.AnalysisFail;
3296}3498}
...@@ -3344,14 +3546,12 @@ pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {...@@ -3344,14 +3546,12 @@ pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
3344}3546}
33453547
3346pub fn floatAdd(3548pub fn floatAdd(
3347 mod: *Module,3549 arena: *Allocator,
3348 scope: *Scope,
3349 float_type: Type,3550 float_type: Type,
3350 src: LazySrcLoc,3551 src: LazySrcLoc,
3351 lhs: Value,3552 lhs: Value,
3352 rhs: Value,3553 rhs: Value,
3353) !Value {3554) !Value {
3354 const arena = scope.arena();
3355 switch (float_type.tag()) {3555 switch (float_type.tag()) {
3356 .f16 => {3556 .f16 => {
3357 @panic("TODO add __trunctfhf2 to compiler-rt");3557 @panic("TODO add __trunctfhf2 to compiler-rt");
...@@ -3379,14 +3579,12 @@ pub fn floatAdd(...@@ -3379,14 +3579,12 @@ pub fn floatAdd(
3379}3579}
33803580
3381pub fn floatSub(3581pub fn floatSub(
3382 mod: *Module,3582 arena: *Allocator,
3383 scope: *Scope,
3384 float_type: Type,3583 float_type: Type,
3385 src: LazySrcLoc,3584 src: LazySrcLoc,
3386 lhs: Value,3585 lhs: Value,
3387 rhs: Value,3586 rhs: Value,
3388) !Value {3587) !Value {
3389 const arena = scope.arena();
3390 switch (float_type.tag()) {3588 switch (float_type.tag()) {
3391 .f16 => {3589 .f16 => {
3392 @panic("TODO add __trunctfhf2 to compiler-rt");3590 @panic("TODO add __trunctfhf2 to compiler-rt");
...@@ -3584,7 +3782,6 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode {...@@ -3584,7 +3782,6 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode {
3584pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex) InnerError![]const u8 {3782pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex) InnerError![]const u8 {
3585 const tree = scope.tree();3783 const tree = scope.tree();
3586 const token_tags = tree.tokens.items(.tag);3784 const token_tags = tree.tokens.items(.tag);
3587 const token_starts = tree.tokens.items(.start);
3588 assert(token_tags[token] == .identifier);3785 assert(token_tags[token] == .identifier);
3589 const ident_name = tree.tokenSlice(token);3786 const ident_name = tree.tokenSlice(token);
3590 if (!mem.startsWith(u8, ident_name, "@")) {3787 if (!mem.startsWith(u8, ident_name, "@")) {
...@@ -3592,7 +3789,7 @@ pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex)...@@ -3592,7 +3789,7 @@ pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex)
3592 }3789 }
3593 var buf = std.ArrayList(u8).init(mod.gpa);3790 var buf = std.ArrayList(u8).init(mod.gpa);
3594 defer buf.deinit();3791 defer buf.deinit();
3595 try parseStrLit(mod, scope, buf, ident_name, 1);3792 try parseStrLit(mod, scope, token, &buf, ident_name, 1);
3596 return buf.toOwnedSlice();3793 return buf.toOwnedSlice();
3597}3794}
35983795
...@@ -3607,13 +3804,12 @@ pub fn appendIdentStr(...@@ -3607,13 +3804,12 @@ pub fn appendIdentStr(
3607) InnerError!void {3804) InnerError!void {
3608 const tree = scope.tree();3805 const tree = scope.tree();
3609 const token_tags = tree.tokens.items(.tag);3806 const token_tags = tree.tokens.items(.tag);
3610 const token_starts = tree.tokens.items(.start);
3611 assert(token_tags[token] == .identifier);3807 assert(token_tags[token] == .identifier);
3612 const ident_name = tree.tokenSlice(token);3808 const ident_name = tree.tokenSlice(token);
3613 if (!mem.startsWith(u8, ident_name, "@")) {3809 if (!mem.startsWith(u8, ident_name, "@")) {
3614 return buf.appendSlice(ident_name);3810 return buf.appendSlice(ident_name);
3615 } else {3811 } else {
3616 return parseStrLit(scope, buf, ident_name, 1);3812 return parseStrLit(scope, token, buf, ident_name, 1);
3617 }3813 }
3618}3814}
36193815
...@@ -3621,57 +3817,60 @@ pub fn appendIdentStr(...@@ -3621,57 +3817,60 @@ pub fn appendIdentStr(
3621pub fn parseStrLit(3817pub fn parseStrLit(
3622 mod: *Module,3818 mod: *Module,
3623 scope: *Scope,3819 scope: *Scope,
3624 buf: *ArrayList(u8),3820 token: ast.TokenIndex,
3821 buf: *std.ArrayList(u8),
3625 bytes: []const u8,3822 bytes: []const u8,
3626 offset: usize,3823 offset: u32,
3627) InnerError!void {3824) InnerError!void {
3825 const tree = scope.tree();
3826 const token_starts = tree.tokens.items(.start);
3628 const raw_string = bytes[offset..];3827 const raw_string = bytes[offset..];
3629 switch (try std.zig.string_literal.parseAppend(buf, raw_string)) {3828 switch (try std.zig.string_literal.parseAppend(buf, raw_string)) {
3630 .success => return,3829 .success => return,
3631 .invalid_character => |bad_index| {3830 .invalid_character => |bad_index| {
3632 return mod.fail(3831 return mod.failOff(
3633 scope,3832 scope,
3634 token_starts[token] + offset + bad_index,3833 token_starts[token] + offset + @intCast(u32, bad_index),
3635 "invalid string literal character: '{c}'",3834 "invalid string literal character: '{c}'",
3636 .{raw_string[bad_index]},3835 .{raw_string[bad_index]},
3637 );3836 );
3638 },3837 },
3639 .expected_hex_digits => |bad_index| {3838 .expected_hex_digits => |bad_index| {
3640 return mod.fail(3839 return mod.failOff(
3641 scope,3840 scope,
3642 token_starts[token] + offset + bad_index,3841 token_starts[token] + offset + @intCast(u32, bad_index),
3643 "expected hex digits after '\\x'",3842 "expected hex digits after '\\x'",
3644 .{},3843 .{},
3645 );3844 );
3646 },3845 },
3647 .invalid_hex_escape => |bad_index| {3846 .invalid_hex_escape => |bad_index| {
3648 return mod.fail(3847 return mod.failOff(
3649 scope,3848 scope,
3650 token_starts[token] + offset + bad_index,3849 token_starts[token] + offset + @intCast(u32, bad_index),
3651 "invalid hex digit: '{c}'",3850 "invalid hex digit: '{c}'",
3652 .{raw_string[bad_index]},3851 .{raw_string[bad_index]},
3653 );3852 );
3654 },3853 },
3655 .invalid_unicode_escape => |bad_index| {3854 .invalid_unicode_escape => |bad_index| {
3656 return mod.fail(3855 return mod.failOff(
3657 scope,3856 scope,
3658 token_starts[token] + offset + bad_index,3857 token_starts[token] + offset + @intCast(u32, bad_index),
3659 "invalid unicode digit: '{c}'",3858 "invalid unicode digit: '{c}'",
3660 .{raw_string[bad_index]},3859 .{raw_string[bad_index]},
3661 );3860 );
3662 },3861 },
3663 .missing_matching_brace => |bad_index| {3862 .missing_matching_rbrace => |bad_index| {
3664 return mod.fail(3863 return mod.failOff(
3665 scope,3864 scope,
3666 token_starts[token] + offset + bad_index,3865 token_starts[token] + offset + @intCast(u32, bad_index),
3667 "missing matching '}}' character",3866 "missing matching '}}' character",
3668 .{},3867 .{},
3669 );3868 );
3670 },3869 },
3671 .expected_unicode_digits => |bad_index| {3870 .expected_unicode_digits => |bad_index| {
3672 return mod.fail(3871 return mod.failOff(
3673 scope,3872 scope,
3674 token_starts[token] + offset + bad_index,3873 token_starts[token] + offset + @intCast(u32, bad_index),
3675 "expected unicode digits after '\\u'",3874 "expected unicode digits after '\\u'",
3676 .{},3875 .{},
3677 );3876 );
src/Sema.zig+679-588
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
6//! This is the the heart of the Zig compiler.6//! This is the the heart of the Zig compiler.
77
8mod: *Module,8mod: *Module,
9/// Same as `mod.gpa`.9/// Alias to `mod.gpa`.
10gpa: *Allocator,10gpa: *Allocator,
11/// Points to the arena allocator of the Decl.11/// Points to the arena allocator of the Decl.
12arena: *Allocator,12arena: *Allocator,
...@@ -53,22 +53,6 @@ const InnerError = Module.InnerError;...@@ -53,22 +53,6 @@ const InnerError = Module.InnerError;
53const Decl = Module.Decl;53const Decl = Module.Decl;
54const LazySrcLoc = Module.LazySrcLoc;54const LazySrcLoc = Module.LazySrcLoc;
5555
56// TODO when memory layout of TZIR is reworked, this can be simplified.
57const const_tzir_inst_list = blk: {
58 var result: [zir.const_inst_list.len]ir.Inst.Const = undefined;
59 for (result) |*tzir_const, i| {
60 tzir_const.* = .{
61 .base = .{
62 .tag = .constant,
63 .ty = zir.const_inst_list[i].ty,
64 .src = 0,
65 },
66 .val = zir.const_inst_list[i].val,
67 };
68 }
69 break :blk result;
70};
71
72pub fn root(sema: *Sema, root_block: *Scope.Block) !void {56pub fn root(sema: *Sema, root_block: *Scope.Block) !void {
73 const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len];57 const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len];
74 return sema.analyzeBody(root_block, root_body);58 return sema.analyzeBody(root_block, root_body);
...@@ -246,27 +230,26 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde...@@ -246,27 +230,26 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde
246 }230 }
247}231}
248232
249pub fn resolveInst(sema: *Sema, block: *Scope.Block, zir_ref: zir.Inst.Ref) *const ir.Inst {233/// TODO when we rework TZIR memory layout, this function will no longer have a possible error.
234pub fn resolveInst(sema: *Sema, zir_ref: zir.Inst.Ref) error{OutOfMemory}!*ir.Inst {
250 var i = zir_ref;235 var i = zir_ref;
251236
252 // First section of indexes correspond to a set number of constant values.237 // First section of indexes correspond to a set number of constant values.
253 if (i < const_tzir_inst_list.len) {238 if (i < zir.const_inst_list.len) {
254 return &const_tzir_inst_list[i];239 // TODO when we rework TZIR memory layout, this function can be as simple as:
240 // if (zir_ref < zir.const_inst_list.len + sema.param_count)
241 // return zir_ref;
242 // Until then we allocate memory for a new, mutable `ir.Inst` to match what
243 // TZIR expects.
244 return sema.mod.constInst(sema.arena, .unneeded, zir.const_inst_list[i]);
255 }245 }
256 i -= const_tzir_inst_list.len;246 i -= zir.const_inst_list.len;
257247
258 // Next section of indexes correspond to function parameters, if any.248 // Next section of indexes correspond to function parameters, if any.
259 if (block.inlining) |inlining| {249 if (i < sema.param_inst_list.len) {
260 if (i < inlining.casted_args.len) {250 return sema.param_inst_list[i];
261 return inlining.casted_args[i];
262 }
263 i -= inlining.casted_args.len;
264 } else {
265 if (i < sema.param_inst_list.len) {
266 return sema.param_inst_list[i];
267 }
268 i -= sema.param_inst_list.len;
269 }251 }
252 i -= sema.param_inst_list.len;
270253
271 // Finally, the last section of indexes refers to the map of ZIR=>TZIR.254 // Finally, the last section of indexes refers to the map of ZIR=>TZIR.
272 return sema.inst_map[i];255 return sema.inst_map[i];
...@@ -278,17 +261,17 @@ fn resolveConstString(...@@ -278,17 +261,17 @@ fn resolveConstString(
278 src: LazySrcLoc,261 src: LazySrcLoc,
279 zir_ref: zir.Inst.Ref,262 zir_ref: zir.Inst.Ref,
280) ![]u8 {263) ![]u8 {
281 const tzir_inst = sema.resolveInst(block, zir_ref);264 const tzir_inst = try sema.resolveInst(zir_ref);
282 const wanted_type = Type.initTag(.const_slice_u8);265 const wanted_type = Type.initTag(.const_slice_u8);
283 const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst);266 const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst, src);
284 const val = try sema.resolveConstValue(block, src, coerced_inst);267 const val = try sema.resolveConstValue(block, src, coerced_inst);
285 return val.toAllocatedBytes(sema.arena);268 return val.toAllocatedBytes(sema.arena);
286}269}
287270
288fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: zir.Inst.Ref) !Type {271fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: zir.Inst.Ref) !Type {
289 const tzir_inst = sema.resolveInt(block, zir_ref);272 const tzir_inst = try sema.resolveInst(zir_ref);
290 const wanted_type = Type.initTag(.@"type");273 const wanted_type = Type.initTag(.@"type");
291 const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst);274 const coerced_inst = try sema.coerce(block, wanted_type, tzir_inst, src);
292 const val = try sema.resolveConstValue(block, src, coerced_inst);275 const val = try sema.resolveConstValue(block, src, coerced_inst);
293 return val.toType(sema.arena);276 return val.toType(sema.arena);
294}277}
...@@ -319,7 +302,7 @@ fn resolveAlreadyCoercedInt(...@@ -319,7 +302,7 @@ fn resolveAlreadyCoercedInt(
319 comptime Int: type,302 comptime Int: type,
320) !Int {303) !Int {
321 comptime assert(@typeInfo(Int).Int.bits <= 64);304 comptime assert(@typeInfo(Int).Int.bits <= 64);
322 const tzir_inst = sema.resolveInst(block, zir_ref);305 const tzir_inst = try sema.resolveInst(zir_ref);
323 const val = try sema.resolveConstValue(block, src, tzir_inst);306 const val = try sema.resolveConstValue(block, src, tzir_inst);
324 switch (@typeInfo(Int).Int.signedness) {307 switch (@typeInfo(Int).Int.signedness) {
325 .signed => return @intCast(Int, val.toSignedInt()),308 .signed => return @intCast(Int, val.toSignedInt()),
...@@ -334,8 +317,8 @@ fn resolveInt(...@@ -334,8 +317,8 @@ fn resolveInt(
334 zir_ref: zir.Inst.Ref,317 zir_ref: zir.Inst.Ref,
335 dest_type: Type,318 dest_type: Type,
336) !u64 {319) !u64 {
337 const tzir_inst = sema.resolveInst(block, zir_ref);320 const tzir_inst = try sema.resolveInst(zir_ref);
338 const coerced = try sema.coerce(scope, dest_type, tzir_inst);321 const coerced = try sema.coerce(block, dest_type, tzir_inst, src);
339 const val = try sema.resolveConstValue(block, src, coerced);322 const val = try sema.resolveConstValue(block, src, coerced);
340323
341 return val.toUnsignedInt();324 return val.toUnsignedInt();
...@@ -347,7 +330,7 @@ fn resolveInstConst(...@@ -347,7 +330,7 @@ fn resolveInstConst(
347 src: LazySrcLoc,330 src: LazySrcLoc,
348 zir_ref: zir.Inst.Ref,331 zir_ref: zir.Inst.Ref,
349) InnerError!TypedValue {332) InnerError!TypedValue {
350 const tzir_inst = sema.resolveInst(block, zir_ref);333 const tzir_inst = try sema.resolveInst(zir_ref);
351 const val = try sema.resolveConstValue(block, src, tzir_inst);334 const val = try sema.resolveConstValue(block, src, tzir_inst);
352 return TypedValue{335 return TypedValue{
353 .ty = tzir_inst.ty,336 .ty = tzir_inst.ty,
...@@ -355,42 +338,46 @@ fn resolveInstConst(...@@ -355,42 +338,46 @@ fn resolveInstConst(
355 };338 };
356}339}
357340
358fn zirConst(sema: *Sema, block: *Scope.Block, const_inst: zir.Inst.Index) InnerError!*Inst {341fn zirConst(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
359 const tracy = trace(@src());342 const tracy = trace(@src());
360 defer tracy.end();343 defer tracy.end();
344
345 const tv_ptr = sema.code.instructions.items(.data)[inst].@"const";
361 // Move the TypedValue from old memory to new memory. This allows freeing the ZIR instructions346 // Move the TypedValue from old memory to new memory. This allows freeing the ZIR instructions
362 // after analysis.347 // after analysis. This happens, for example, with variable declaration initialization
363 const typed_value_copy = try const_inst.positionals.typed_value.copy(sema.arena);348 // expressions.
364 return sema.mod.constInst(scope, const_inst.base.src, typed_value_copy);349 const typed_value_copy = try tv_ptr.copy(sema.arena);
350 return sema.mod.constInst(sema.arena, .unneeded, typed_value_copy);
365}351}
366352
367fn zirBitcastRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {353fn zirBitcastRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
368 const tracy = trace(@src());354 const tracy = trace(@src());
369 defer tracy.end();355 defer tracy.end();
370 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zir_sema.zirBitcastRef", .{});356 return sema.mod.fail(&block.base, sema.src, "TODO implement zir_sema.zirBitcastRef", .{});
371}357}
372358
373fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {359fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
374 const tracy = trace(@src());360 const tracy = trace(@src());
375 defer tracy.end();361 defer tracy.end();
376 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zir_sema.zirBitcastResultPtr", .{});362 return sema.mod.fail(&block.base, sema.src, "TODO implement zir_sema.zirBitcastResultPtr", .{});
377}363}
378364
379fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {365fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
380 const tracy = trace(@src());366 const tracy = trace(@src());
381 defer tracy.end();367 defer tracy.end();
382 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirCoerceResultPtr", .{});368 return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{});
383}369}
384370
385fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {371fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
386 const tracy = trace(@src());372 const tracy = trace(@src());
387 defer tracy.end();373 defer tracy.end();
388374
389 try sema.requireFunctionBlock(block, inst.base.src);375 const src: LazySrcLoc = .unneeded;
390 const fn_ty = block.func.?.owner_decl.typed_value.most_recent.typed_value.ty;376 try sema.requireFunctionBlock(block, src);
377 const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
391 const ret_type = fn_ty.fnReturnType();378 const ret_type = fn_ty.fnReturnType();
392 const ptr_type = try sema.mod.simplePtrType(sema.arena, ret_type, true, .One);379 const ptr_type = try sema.mod.simplePtrType(sema.arena, ret_type, true, .One);
393 return block.addNoOp(inst.base.src, ptr_type, .alloc);380 return block.addNoOp(src, ptr_type, .alloc);
394}381}
395382
396fn zirRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {383fn zirRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -398,17 +385,19 @@ fn zirRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In...@@ -398,17 +385,19 @@ fn zirRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In
398 defer tracy.end();385 defer tracy.end();
399386
400 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;387 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
401 const operand = sema.resolveInst(block, inst_data.operand);388 const operand = try sema.resolveInst(inst_data.operand);
402 return sema.analyzeRef(block, inst_data.src(), operand);389 return sema.analyzeRef(block, inst_data.src(), operand);
403}390}
404391
405fn zirRetType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {392fn zirRetType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
406 const tracy = trace(@src());393 const tracy = trace(@src());
407 defer tracy.end();394 defer tracy.end();
408 try sema.requireFunctionBlock(block, inst.base.src);395
409 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;396 const src: LazySrcLoc = .unneeded;
397 try sema.requireFunctionBlock(block, src);
398 const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
410 const ret_type = fn_ty.fnReturnType();399 const ret_type = fn_ty.fnReturnType();
411 return sema.mod.constType(sema.arena, inst.base.src, ret_type);400 return sema.mod.constType(sema.arena, src, ret_type);
412}401}
413402
414fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {403fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -416,7 +405,7 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) I...@@ -416,7 +405,7 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) I
416 defer tracy.end();405 defer tracy.end();
417406
418 const inst_data = sema.code.instructions.items(.data)[inst].un_node;407 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
419 const operand = sema.resolveInst(block, inst_data.operand);408 const operand = try sema.resolveInst(inst_data.operand);
420 const src = inst_data.src();409 const src = inst_data.src();
421 switch (operand.ty.zigTypeTag()) {410 switch (operand.ty.zigTypeTag()) {
422 .Void, .NoReturn => return sema.mod.constVoid(sema.arena, .unneeded),411 .Void, .NoReturn => return sema.mod.constVoid(sema.arena, .unneeded),
...@@ -429,7 +418,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde...@@ -429,7 +418,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde
429 defer tracy.end();418 defer tracy.end();
430419
431 const inst_data = sema.code.instructions.items(.data)[inst].un_node;420 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
432 const operand = sema.resolveInst(block, inst_data.operand);421 const operand = try sema.resolveInst(inst_data.operand);
433 const src = inst_data.src();422 const src = inst_data.src();
434 switch (operand.ty.zigTypeTag()) {423 switch (operand.ty.zigTypeTag()) {
435 .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}),424 .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}),
...@@ -442,7 +431,8 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -442,7 +431,8 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
442 defer tracy.end();431 defer tracy.end();
443432
444 const inst_data = sema.code.instructions.items(.data)[inst].un_node;433 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
445 const array_ptr = sema.resolveInst(block, inst_data.operand);434 const src = inst_data.src();
435 const array_ptr = try sema.resolveInst(inst_data.operand);
446436
447 const elem_ty = array_ptr.ty.elemType();437 const elem_ty = array_ptr.ty.elemType();
448 if (!elem_ty.isIndexable()) {438 if (!elem_ty.isIndexable()) {
...@@ -454,7 +444,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -454,7 +444,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
454 "type '{}' does not support indexing",444 "type '{}' does not support indexing",
455 .{elem_ty},445 .{elem_ty},
456 );446 );
457 errdefer msg.destroy(mod.gpa);447 errdefer msg.destroy(sema.gpa);
458 try sema.mod.errNote(448 try sema.mod.errNote(
459 &block.base,449 &block.base,
460 cond_src,450 cond_src,
...@@ -464,10 +454,10 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -464,10 +454,10 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
464 );454 );
465 break :msg msg;455 break :msg msg;
466 };456 };
467 return mod.failWithOwnedErrorMsg(scope, msg);457 return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
468 }458 }
469 const result_ptr = try sema.namedFieldPtr(block, inst.base.src, array_ptr, "len", inst.base.src);459 const result_ptr = try sema.namedFieldPtr(block, src, array_ptr, "len", src);
470 return sema.analyzeDeref(block, inst.base.src, result_ptr, result_ptr.src);460 return sema.analyzeDeref(block, src, result_ptr, result_ptr.src);
471}461}
472462
473fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {463fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -505,6 +495,10 @@ fn zirAllocInferred(...@@ -505,6 +495,10 @@ fn zirAllocInferred(
505) InnerError!*Inst {495) InnerError!*Inst {
506 const tracy = trace(@src());496 const tracy = trace(@src());
507 defer tracy.end();497 defer tracy.end();
498
499 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
500 const src = inst_data.src();
501
508 const val_payload = try sema.arena.create(Value.Payload.InferredAlloc);502 const val_payload = try sema.arena.create(Value.Payload.InferredAlloc);
509 val_payload.* = .{503 val_payload.* = .{
510 .data = .{},504 .data = .{},
...@@ -513,11 +507,11 @@ fn zirAllocInferred(...@@ -513,11 +507,11 @@ fn zirAllocInferred(
513 // not needed in the case of constant values. However here, we plan to "downgrade"507 // not needed in the case of constant values. However here, we plan to "downgrade"
514 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append508 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append
515 // to the block even though it is currently a `.constant`.509 // to the block even though it is currently a `.constant`.
516 const result = try sema.mod.constInst(scope, inst.base.src, .{510 const result = try sema.mod.constInst(sema.arena, src, .{
517 .ty = inferred_alloc_ty,511 .ty = inferred_alloc_ty,
518 .val = Value.initPayload(&val_payload.base),512 .val = Value.initPayload(&val_payload.base),
519 });513 });
520 try sema.requireFunctionBlock(block, inst.base.src);514 try sema.requireFunctionBlock(block, src);
521 try block.instructions.append(sema.gpa, result);515 try block.instructions.append(sema.gpa, result);
522 return result;516 return result;
523}517}
...@@ -532,7 +526,7 @@ fn zirResolveInferredAlloc(...@@ -532,7 +526,7 @@ fn zirResolveInferredAlloc(
532526
533 const inst_data = sema.code.instructions.items(.data)[inst].un_node;527 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
534 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };528 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
535 const ptr = sema.resolveInst(block, inst_data.operand);529 const ptr = try sema.resolveInst(inst_data.operand);
536 const ptr_val = ptr.castTag(.constant).?.val;530 const ptr_val = ptr.castTag(.constant).?.val;
537 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;531 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;
538 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;532 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;
...@@ -563,14 +557,15 @@ fn zirStoreToBlockPtr(...@@ -563,14 +557,15 @@ fn zirStoreToBlockPtr(
563 defer tracy.end();557 defer tracy.end();
564558
565 const bin_inst = sema.code.instructions.items(.data)[inst].bin;559 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
566 const ptr = sema.resolveInst(bin_inst.lhs);560 const ptr = try sema.resolveInst(bin_inst.lhs);
567 const value = sema.resolveInst(bin_inst.rhs);561 const value = try sema.resolveInst(bin_inst.rhs);
568 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);562 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);
569 // TODO detect when this store should be done at compile-time. For example,563 // TODO detect when this store should be done at compile-time. For example,
570 // if expressions should force it when the condition is compile-time known.564 // if expressions should force it when the condition is compile-time known.
565 const src: LazySrcLoc = .unneeded;
571 try sema.requireRuntimeBlock(block, src);566 try sema.requireRuntimeBlock(block, src);
572 const bitcasted_ptr = try block.addUnOp(inst.base.src, ptr_ty, .bitcast, ptr);567 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
573 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);568 return sema.storePtr(block, src, bitcasted_ptr, value);
574}569}
575570
576fn zirStoreToInferredPtr(571fn zirStoreToInferredPtr(
...@@ -581,9 +576,10 @@ fn zirStoreToInferredPtr(...@@ -581,9 +576,10 @@ fn zirStoreToInferredPtr(
581 const tracy = trace(@src());576 const tracy = trace(@src());
582 defer tracy.end();577 defer tracy.end();
583578
579 const src: LazySrcLoc = .unneeded;
584 const bin_inst = sema.code.instructions.items(.data)[inst].bin;580 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
585 const ptr = sema.resolveInst(bin_inst.lhs);581 const ptr = try sema.resolveInst(bin_inst.lhs);
586 const value = sema.resolveInst(bin_inst.rhs);582 const value = try sema.resolveInst(bin_inst.rhs);
587 const inferred_alloc = ptr.castTag(.constant).?.val.castTag(.inferred_alloc).?;583 const inferred_alloc = ptr.castTag(.constant).?.val.castTag(.inferred_alloc).?;
588 // Add the stored instruction to the set we will use to resolve peer types584 // Add the stored instruction to the set we will use to resolve peer types
589 // for the inferred allocation.585 // for the inferred allocation.
...@@ -591,8 +587,8 @@ fn zirStoreToInferredPtr(...@@ -591,8 +587,8 @@ fn zirStoreToInferredPtr(
591 // Create a runtime bitcast instruction with exactly the type the pointer wants.587 // Create a runtime bitcast instruction with exactly the type the pointer wants.
592 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);588 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);
593 try sema.requireRuntimeBlock(block, src);589 try sema.requireRuntimeBlock(block, src);
594 const bitcasted_ptr = try block.addUnOp(inst.base.src, ptr_ty, .bitcast, ptr);590 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
595 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);591 return sema.storePtr(block, src, bitcasted_ptr, value);
596}592}
597593
598fn zirSetEvalBranchQuota(594fn zirSetEvalBranchQuota(
...@@ -614,17 +610,18 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*...@@ -614,17 +610,18 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
614 defer tracy.end();610 defer tracy.end();
615611
616 const bin_inst = sema.code.instructions.items(.data)[inst].bin;612 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
617 const ptr = sema.resolveInst(bin_inst.lhs);613 const ptr = try sema.resolveInst(bin_inst.lhs);
618 const value = sema.resolveInst(bin_inst.rhs);614 const value = try sema.resolveInst(bin_inst.rhs);
619 return mod.storePtr(scope, inst.base.src, ptr, value);615 return sema.storePtr(block, .unneeded, ptr, value);
620}616}
621617
622fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {618fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
623 const tracy = trace(@src());619 const tracy = trace(@src());
624 defer tracy.end();620 defer tracy.end();
625621
622 const src: LazySrcLoc = .todo;
626 const inst_data = sema.code.instructions.items(.data)[inst].param_type;623 const inst_data = sema.code.instructions.items(.data)[inst].param_type;
627 const fn_inst = sema.resolveInst(inst_data.callee);624 const fn_inst = try sema.resolveInst(inst_data.callee);
628 const param_index = inst_data.param_index;625 const param_index = inst_data.param_index;
629626
630 const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) {627 const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) {
...@@ -640,9 +637,9 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr...@@ -640,9 +637,9 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr
640 const param_count = fn_ty.fnParamLen();637 const param_count = fn_ty.fnParamLen();
641 if (param_index >= param_count) {638 if (param_index >= param_count) {
642 if (fn_ty.fnIsVarArgs()) {639 if (fn_ty.fnIsVarArgs()) {
643 return sema.mod.constType(sema.arena, inst.base.src, Type.initTag(.var_args_param));640 return sema.mod.constType(sema.arena, src, Type.initTag(.var_args_param));
644 }641 }
645 return sema.mod.fail(&block.base, inst.base.src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{642 return sema.mod.fail(&block.base, src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{
646 param_index,643 param_index,
647 fn_ty,644 fn_ty,
648 param_count,645 param_count,
...@@ -651,20 +648,25 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr...@@ -651,20 +648,25 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr
651648
652 // TODO support generic functions649 // TODO support generic functions
653 const param_type = fn_ty.fnParamType(param_index);650 const param_type = fn_ty.fnParamType(param_index);
654 return sema.mod.constType(sema.arena, inst.base.src, param_type);651 return sema.mod.constType(sema.arena, src, param_type);
655}652}
656653
657fn zirStr(sema: *Sema, block: *Scope.Block, str_inst: zir.Inst.Index) InnerError!*Inst {654fn zirStr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
658 const tracy = trace(@src());655 const tracy = trace(@src());
659 defer tracy.end();656 defer tracy.end();
660657
661 // The bytes references memory inside the ZIR module, which is fine. Multiple658 const zir_bytes = sema.code.instructions.items(.data)[inst].str.get(sema.code);
662 // anonymous Decls may have strings which point to within the same ZIR module.659
663 const bytes = sema.code.instructions.items(.data)[inst].str.get(sema.code);660 // `zir_bytes` references memory inside the ZIR module, which can get deallocated
661 // after semantic analysis is complete, for example in the case of the initialization
662 // expression of a variable declaration. We need the memory to be in the new
663 // anonymous Decl's arena.
664664
665 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);665 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
666 errdefer new_decl_arena.deinit();666 errdefer new_decl_arena.deinit();
667667
668 const bytes = try new_decl_arena.allocator.dupe(u8, zir_bytes);
669
668 const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len);670 const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len);
669 const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, bytes);671 const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, bytes);
670672
...@@ -679,7 +681,8 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In...@@ -679,7 +681,8 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In
679 const tracy = trace(@src());681 const tracy = trace(@src());
680 defer tracy.end();682 defer tracy.end();
681683
682 return mod.constIntBig(scope, inst.base.src, Type.initTag(.comptime_int), inst.positionals.int);684 const int = sema.code.instructions.items(.data)[inst].int;
685 return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int);
683}686}
684687
685fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {688fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -694,8 +697,8 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner...@@ -694,8 +697,8 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
694}697}
695698
696fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {699fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
697 var managed = mod.compile_log_text.toManaged(mod.gpa);700 var managed = sema.mod.compile_log_text.toManaged(sema.gpa);
698 defer mod.compile_log_text = managed.moveToUnmanaged();701 defer sema.mod.compile_log_text = managed.moveToUnmanaged();
699 const writer = managed.writer();702 const writer = managed.writer();
700703
701 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;704 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
...@@ -703,7 +706,7 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -703,7 +706,7 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
703 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {706 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {
704 if (i != 0) try writer.print(", ", .{});707 if (i != 0) try writer.print(", ", .{});
705708
706 const arg = sema.resolveInst(block, arg_ref);709 const arg = try sema.resolveInst(arg_ref);
707 if (arg.value()) |val| {710 if (arg.value()) |val| {
708 try writer.print("@as({}, {})", .{ arg.ty, val });711 try writer.print("@as({}, {})", .{ arg.ty, val });
709 } else {712 } else {
...@@ -712,12 +715,9 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -712,12 +715,9 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
712 }715 }
713 try writer.print("\n", .{});716 try writer.print("\n", .{});
714717
715 const gop = try mod.compile_log_decls.getOrPut(mod.gpa, scope.ownerDecl().?);718 const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl);
716 if (!gop.found_existing) {719 if (!gop.found_existing) {
717 gop.entry.value = .{720 gop.entry.value = inst_data.src().toSrcLoc(&block.base);
718 .file_scope = block.getFileScope(),
719 .lazy = inst_data.src(),
720 };
721 }721 }
722 return sema.mod.constVoid(sema.arena, .unneeded);722 return sema.mod.constVoid(sema.arena, .unneeded);
723}723}
...@@ -726,6 +726,11 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -726,6 +726,11 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE
726 const tracy = trace(@src());726 const tracy = trace(@src());
727 defer tracy.end();727 defer tracy.end();
728728
729 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
730 const src = inst_data.src();
731 const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index);
732 const body = sema.code.extra[extra.end..][0..extra.data.operands_len];
733
729 // Reserve space for a Loop instruction so that generated Break instructions can734 // Reserve space for a Loop instruction so that generated Break instructions can
730 // point to it, even if it doesn't end up getting used because the code ends up being735 // point to it, even if it doesn't end up getting used because the code ends up being
731 // comptime evaluated.736 // comptime evaluated.
...@@ -734,52 +739,57 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -734,52 +739,57 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE
734 .base = .{739 .base = .{
735 .tag = Inst.Loop.base_tag,740 .tag = Inst.Loop.base_tag,
736 .ty = Type.initTag(.noreturn),741 .ty = Type.initTag(.noreturn),
737 .src = inst.base.src,742 .src = src,
738 },743 },
739 .body = undefined,744 .body = undefined,
740 };745 };
741746
742 var child_block: Scope.Block = .{747 var child_block: Scope.Block = .{
743 .parent = parent_block,748 .parent = parent_block,
744 .inst_table = parent_block.inst_table,749 .sema = sema,
745 .func = parent_block.func,
746 .owner_decl = parent_block.owner_decl,
747 .src_decl = parent_block.src_decl,750 .src_decl = parent_block.src_decl,
748 .instructions = .{},751 .instructions = .{},
749 .arena = sema.arena,
750 .inlining = parent_block.inlining,752 .inlining = parent_block.inlining,
751 .is_comptime = parent_block.is_comptime,753 .is_comptime = parent_block.is_comptime,
752 .branch_quota = parent_block.branch_quota,
753 };754 };
754 defer child_block.instructions.deinit(mod.gpa);755 defer child_block.instructions.deinit(sema.gpa);
755756
756 try sema.analyzeBody(&child_block, inst.positionals.body);757 try sema.analyzeBody(&child_block, body);
757758
758 // Loop repetition is implied so the last instruction may or may not be a noreturn instruction.759 // Loop repetition is implied so the last instruction may or may not be a noreturn instruction.
759760
760 try parent_block.instructions.append(mod.gpa, &loop_inst.base);761 try parent_block.instructions.append(sema.gpa, &loop_inst.base);
761 loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items) };762 loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items) };
762 return &loop_inst.base;763 return &loop_inst.base;
763}764}
764765
765fn zirBlockFlat(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index, is_comptime: bool) InnerError!*Inst {766fn zirBlockFlat(
767 sema: *Sema,
768 parent_block: *Scope.Block,
769 inst: zir.Inst.Index,
770 is_comptime: bool,
771) InnerError!*Inst {
766 const tracy = trace(@src());772 const tracy = trace(@src());
767 defer tracy.end();773 defer tracy.end();
768774
775 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
776 const src = inst_data.src();
777 const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index);
778 const body = sema.code.extra[extra.end..][0..extra.data.operands_len];
779
769 var child_block = parent_block.makeSubBlock();780 var child_block = parent_block.makeSubBlock();
770 defer child_block.instructions.deinit(mod.gpa);781 defer child_block.instructions.deinit(sema.gpa);
771 child_block.is_comptime = child_block.is_comptime or is_comptime;782 child_block.is_comptime = child_block.is_comptime or is_comptime;
772783
773 try sema.analyzeBody(&child_block, inst.positionals.body);784 try sema.analyzeBody(&child_block, body);
774785
775 // Move the analyzed instructions into the parent block arena.786 // Move the analyzed instructions into the parent block arena.
776 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items);787 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items);
777 try parent_block.instructions.appendSlice(mod.gpa, copied_instructions);788 try parent_block.instructions.appendSlice(sema.gpa, copied_instructions);
778789
779 // The result of a flat block is the last instruction.790 // The result of a flat block is the last instruction.
780 const zir_inst_list = inst.positionals.body.instructions;791 const last_zir_inst = body[body.len - 1];
781 const last_zir_inst = zir_inst_list[zir_inst_list.len - 1];792 return sema.resolveInst(last_zir_inst);
782 return sema.inst_map[last_zir_inst];
783}793}
784794
785fn zirBlock(795fn zirBlock(
...@@ -791,6 +801,11 @@ fn zirBlock(...@@ -791,6 +801,11 @@ fn zirBlock(
791 const tracy = trace(@src());801 const tracy = trace(@src());
792 defer tracy.end();802 defer tracy.end();
793803
804 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
805 const src = inst_data.src();
806 const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index);
807 const body = sema.code.extra[extra.end..][0..extra.data.operands_len];
808
794 // Reserve space for a Block instruction so that generated Break instructions can809 // Reserve space for a Block instruction so that generated Break instructions can
795 // point to it, even if it doesn't end up getting used because the code ends up being810 // point to it, even if it doesn't end up getting used because the code ends up being
796 // comptime evaluated.811 // comptime evaluated.
...@@ -799,19 +814,16 @@ fn zirBlock(...@@ -799,19 +814,16 @@ fn zirBlock(
799 .base = .{814 .base = .{
800 .tag = Inst.Block.base_tag,815 .tag = Inst.Block.base_tag,
801 .ty = undefined, // Set after analysis.816 .ty = undefined, // Set after analysis.
802 .src = inst.base.src,817 .src = src,
803 },818 },
804 .body = undefined,819 .body = undefined,
805 };820 };
806821
807 var child_block: Scope.Block = .{822 var child_block: Scope.Block = .{
808 .parent = parent_block,823 .parent = parent_block,
809 .inst_table = parent_block.inst_table,824 .sema = sema,
810 .func = parent_block.func,
811 .owner_decl = parent_block.owner_decl,
812 .src_decl = parent_block.src_decl,825 .src_decl = parent_block.src_decl,
813 .instructions = .{},826 .instructions = .{},
814 .arena = sema.arena,
815 // TODO @as here is working around a stage1 miscompilation bug :(827 // TODO @as here is working around a stage1 miscompilation bug :(
816 .label = @as(?Scope.Block.Label, Scope.Block.Label{828 .label = @as(?Scope.Block.Label, Scope.Block.Label{
817 .zir_block = inst,829 .zir_block = inst,
...@@ -823,17 +835,16 @@ fn zirBlock(...@@ -823,17 +835,16 @@ fn zirBlock(
823 }),835 }),
824 .inlining = parent_block.inlining,836 .inlining = parent_block.inlining,
825 .is_comptime = is_comptime or parent_block.is_comptime,837 .is_comptime = is_comptime or parent_block.is_comptime,
826 .branch_quota = parent_block.branch_quota,
827 };838 };
828 const merges = &child_block.label.?.merges;839 const merges = &child_block.label.?.merges;
829840
830 defer child_block.instructions.deinit(mod.gpa);841 defer child_block.instructions.deinit(sema.gpa);
831 defer merges.results.deinit(mod.gpa);842 defer merges.results.deinit(sema.gpa);
832 defer merges.br_list.deinit(mod.gpa);843 defer merges.br_list.deinit(sema.gpa);
833844
834 try sema.analyzeBody(&child_block, inst.positionals.body);845 try sema.analyzeBody(&child_block, body);
835846
836 return analyzeBlockBody(mod, scope, &child_block, merges);847 return sema.analyzeBlockBody(parent_block, &child_block, merges);
837}848}
838849
839fn analyzeBlockBody(850fn analyzeBlockBody(
...@@ -853,7 +864,7 @@ fn analyzeBlockBody(...@@ -853,7 +864,7 @@ fn analyzeBlockBody(
853 // No need for a block instruction. We can put the new instructions864 // No need for a block instruction. We can put the new instructions
854 // directly into the parent block.865 // directly into the parent block.
855 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items);866 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items);
856 try parent_block.instructions.appendSlice(mod.gpa, copied_instructions);867 try parent_block.instructions.appendSlice(sema.gpa, copied_instructions);
857 return copied_instructions[copied_instructions.len - 1];868 return copied_instructions[copied_instructions.len - 1];
858 }869 }
859 if (merges.results.items.len == 1) {870 if (merges.results.items.len == 1) {
...@@ -864,7 +875,7 @@ fn analyzeBlockBody(...@@ -864,7 +875,7 @@ fn analyzeBlockBody(
864 // No need for a block instruction. We can put the new instructions directly875 // No need for a block instruction. We can put the new instructions directly
865 // into the parent block. Here we omit the break instruction.876 // into the parent block. Here we omit the break instruction.
866 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items[0..last_inst_index]);877 const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items[0..last_inst_index]);
867 try parent_block.instructions.appendSlice(mod.gpa, copied_instructions);878 try parent_block.instructions.appendSlice(sema.gpa, copied_instructions);
868 return merges.results.items[0];879 return merges.results.items[0];
869 }880 }
870 }881 }
...@@ -874,7 +885,7 @@ fn analyzeBlockBody(...@@ -874,7 +885,7 @@ fn analyzeBlockBody(
874885
875 // Need to set the type and emit the Block instruction. This allows machine code generation886 // Need to set the type and emit the Block instruction. This allows machine code generation
876 // to emit a jump instruction to after the block when it encounters the break.887 // to emit a jump instruction to after the block when it encounters the break.
877 try parent_block.instructions.append(mod.gpa, &merges.block_inst.base);888 try parent_block.instructions.append(sema.gpa, &merges.block_inst.base);
878 const resolved_ty = try sema.resolvePeerTypes(parent_block, merges.results.items);889 const resolved_ty = try sema.resolvePeerTypes(parent_block, merges.results.items);
879 merges.block_inst.base.ty = resolved_ty;890 merges.block_inst.base.ty = resolved_ty;
880 merges.block_inst.body = .{891 merges.block_inst.body = .{
...@@ -888,8 +899,8 @@ fn analyzeBlockBody(...@@ -888,8 +899,8 @@ fn analyzeBlockBody(
888 continue;899 continue;
889 }900 }
890 var coerce_block = parent_block.makeSubBlock();901 var coerce_block = parent_block.makeSubBlock();
891 defer coerce_block.instructions.deinit(mod.gpa);902 defer coerce_block.instructions.deinit(sema.gpa);
892 const coerced_operand = try sema.coerce(&coerce_block.base, resolved_ty, br.operand);903 const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, .todo);
893 // If no instructions were produced, such as in the case of a coercion of a904 // If no instructions were produced, such as in the case of a coercion of a
894 // constant value to a new type, we can simply point the br operand to it.905 // constant value to a new type, we can simply point the br operand to it.
895 if (coerce_block.instructions.items.len == 0) {906 if (coerce_block.instructions.items.len == 0) {
...@@ -921,8 +932,10 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -921,8 +932,10 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
921 const tracy = trace(@src());932 const tracy = trace(@src());
922 defer tracy.end();933 defer tracy.end();
923934
935 const src_node = sema.code.instructions.items(.data)[inst].node;
936 const src: LazySrcLoc = .{ .node_offset = src_node };
924 try sema.requireRuntimeBlock(block, src);937 try sema.requireRuntimeBlock(block, src);
925 return block.addNoOp(inst.base.src, Type.initTag(.void), .breakpoint);938 return block.addNoOp(src, Type.initTag(.void), .breakpoint);
926}939}
927940
928fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {941fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -930,9 +943,9 @@ fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*...@@ -930,9 +943,9 @@ fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
930 defer tracy.end();943 defer tracy.end();
931944
932 const bin_inst = sema.code.instructions.items(.data)[inst].bin;945 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
933 const operand = sema.resolveInst(block, bin_inst.rhs);946 const operand = try sema.resolveInst(bin_inst.rhs);
934 const zir_block = bin_inst.lhs;947 const zir_block = bin_inst.lhs;
935 return analyzeBreak(mod, block, sema.src, zir_block, operand);948 return sema.analyzeBreak(block, sema.src, zir_block, operand);
936}949}
937950
938fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {951fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -942,25 +955,25 @@ fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner...@@ -942,25 +955,25 @@ fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
942 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;955 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
943 const zir_block = inst_data.operand;956 const zir_block = inst_data.operand;
944 const void_inst = try sema.mod.constVoid(sema.arena, .unneeded);957 const void_inst = try sema.mod.constVoid(sema.arena, .unneeded);
945 return analyzeBreak(mod, block, inst_data.src(), zir_block, void_inst);958 return sema.analyzeBreak(block, inst_data.src(), zir_block, void_inst);
946}959}
947960
948fn analyzeBreak(961fn analyzeBreak(
949 sema: *Sema,962 sema: *Sema,
950 block: *Scope.Block,963 start_block: *Scope.Block,
951 src: LazySrcLoc,964 src: LazySrcLoc,
952 zir_block: zir.Inst.Index,965 zir_block: zir.Inst.Index,
953 operand: *Inst,966 operand: *Inst,
954) InnerError!*Inst {967) InnerError!*Inst {
955 var opt_block = scope.cast(Scope.Block);968 var block = start_block;
956 while (opt_block) |block| {969 while (true) {
957 if (block.label) |*label| {970 if (block.label) |*label| {
958 if (label.zir_block == zir_block) {971 if (label.zir_block == zir_block) {
959 try sema.requireFunctionBlock(block, src);972 try sema.requireFunctionBlock(block, src);
960 // Here we add a br instruction, but we over-allocate a little bit973 // Here we add a br instruction, but we over-allocate a little bit
961 // (if necessary) to make it possible to convert the instruction into974 // (if necessary) to make it possible to convert the instruction into
962 // a br_block_flat instruction later.975 // a br_block_flat instruction later.
963 const br = @ptrCast(*Inst.Br, try b.arena.alignedAlloc(976 const br = @ptrCast(*Inst.Br, try sema.arena.alignedAlloc(
964 u8,977 u8,
965 Inst.convertable_br_align,978 Inst.convertable_br_align,
966 Inst.convertable_br_size,979 Inst.convertable_br_size,
...@@ -974,21 +987,21 @@ fn analyzeBreak(...@@ -974,21 +987,21 @@ fn analyzeBreak(
974 .operand = operand,987 .operand = operand,
975 .block = label.merges.block_inst,988 .block = label.merges.block_inst,
976 };989 };
977 try b.instructions.append(mod.gpa, &br.base);990 try block.instructions.append(sema.gpa, &br.base);
978 try label.merges.results.append(mod.gpa, operand);991 try label.merges.results.append(sema.gpa, operand);
979 try label.merges.br_list.append(mod.gpa, br);992 try label.merges.br_list.append(sema.gpa, br);
980 return &br.base;993 return &br.base;
981 }994 }
982 }995 }
983 opt_block = block.parent;996 block = block.parent.?;
984 } else unreachable;997 }
985}998}
986999
987fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1000fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
988 const tracy = trace(@src());1001 const tracy = trace(@src());
989 defer tracy.end();1002 defer tracy.end();
9901003
991 if (b.is_comptime) {1004 if (block.is_comptime) {
992 return sema.mod.constVoid(sema.arena, .unneeded);1005 return sema.mod.constVoid(sema.arena, .unneeded);
993 }1006 }
9941007
...@@ -1048,9 +1061,9 @@ fn analyzeCall(...@@ -1048,9 +1061,9 @@ fn analyzeCall(
1048 func_src: LazySrcLoc,1061 func_src: LazySrcLoc,
1049 call_src: LazySrcLoc,1062 call_src: LazySrcLoc,
1050 modifier: std.builtin.CallOptions.Modifier,1063 modifier: std.builtin.CallOptions.Modifier,
1051 zir_args: []const Ref,1064 zir_args: []const zir.Inst.Ref,
1052) InnerError!*ir.Inst {1065) InnerError!*ir.Inst {
1053 const func = sema.resolveInst(zir_func);1066 const func = try sema.resolveInst(zir_func);
10541067
1055 if (func.ty.zigTypeTag() != .Fn)1068 if (func.ty.zigTypeTag() != .Fn)
1056 return sema.mod.fail(&block.base, func_src, "type '{}' not a function", .{func.ty});1069 return sema.mod.fail(&block.base, func_src, "type '{}' not a function", .{func.ty});
...@@ -1091,20 +1104,20 @@ fn analyzeCall(...@@ -1091,20 +1104,20 @@ fn analyzeCall(
1091 return sema.mod.fail(&block.base, call_src, "TODO implement comptime function calls", .{});1104 return sema.mod.fail(&block.base, call_src, "TODO implement comptime function calls", .{});
1092 }1105 }
1093 if (modifier != .auto) {1106 if (modifier != .auto) {
1094 return sema.mod.fail(&block.base, call_src, "TODO implement call with modifier {}", .{inst.positionals.modifier});1107 return sema.mod.fail(&block.base, call_src, "TODO implement call with modifier {}", .{modifier});
1095 }1108 }
10961109
1097 // TODO handle function calls of generic functions1110 // TODO handle function calls of generic functions
1098 const casted_args = try sema.arena.alloc(*Inst, zir_args.len);1111 const casted_args = try sema.arena.alloc(*Inst, zir_args.len);
1099 for (zir_args) |zir_arg, i| {1112 for (zir_args) |zir_arg, i| {
1100 // the args are already casted to the result of a param type instruction.1113 // the args are already casted to the result of a param type instruction.
1101 casted_args[i] = sema.resolveInst(block, zir_arg);1114 casted_args[i] = try sema.resolveInst(zir_arg);
1102 }1115 }
11031116
1104 const ret_type = func.ty.fnReturnType();1117 const ret_type = func.ty.fnReturnType();
11051118
1106 try sema.requireFunctionBlock(block, call_src);1119 try sema.requireFunctionBlock(block, call_src);
1107 const is_comptime_call = b.is_comptime or modifier == .compile_time;1120 const is_comptime_call = block.is_comptime or modifier == .compile_time;
1108 const is_inline_call = is_comptime_call or modifier == .always_inline or1121 const is_inline_call = is_comptime_call or modifier == .always_inline or
1109 func.ty.fnCallingConvention() == .Inline;1122 func.ty.fnCallingConvention() == .Inline;
1110 if (is_inline_call) {1123 if (is_inline_call) {
...@@ -1135,70 +1148,75 @@ fn analyzeCall(...@@ -1135,70 +1148,75 @@ fn analyzeCall(
1135 // Otherwise we pass on the shared data from the parent scope.1148 // Otherwise we pass on the shared data from the parent scope.
1136 var shared_inlining: Scope.Block.Inlining.Shared = .{1149 var shared_inlining: Scope.Block.Inlining.Shared = .{
1137 .branch_count = 0,1150 .branch_count = 0,
1138 .caller = b.func,1151 .caller = sema.func,
1139 };1152 };
1140 // This one is shared among sub-blocks within the same callee, but not1153 // This one is shared among sub-blocks within the same callee, but not
1141 // shared among the entire inline/comptime call stack.1154 // shared among the entire inline/comptime call stack.
1142 var inlining: Scope.Block.Inlining = .{1155 var inlining: Scope.Block.Inlining = .{
1143 .shared = if (b.inlining) |inlining| inlining.shared else &shared_inlining,1156 .shared = if (block.inlining) |inlining| inlining.shared else &shared_inlining,
1144 .param_index = 0,
1145 .casted_args = casted_args,
1146 .merges = .{1157 .merges = .{
1147 .results = .{},1158 .results = .{},
1148 .br_list = .{},1159 .br_list = .{},
1149 .block_inst = block_inst,1160 .block_inst = block_inst,
1150 },1161 },
1151 };1162 };
1152 var inst_table = Scope.Block.InstTable.init(mod.gpa);1163 var inline_sema: Sema = .{
1153 defer inst_table.deinit();1164 .mod = sema.mod,
1165 .gpa = sema.mod.gpa,
1166 .arena = sema.arena,
1167 .code = module_fn.zir,
1168 .inst_map = try sema.gpa.alloc(*ir.Inst, module_fn.zir.instructions.len),
1169 .owner_decl = sema.owner_decl,
1170 .func = module_fn,
1171 .param_inst_list = casted_args,
1172 };
1173 defer sema.gpa.free(inline_sema.inst_map);
11541174
1155 var child_block: Scope.Block = .{1175 var child_block: Scope.Block = .{
1156 .parent = null,1176 .parent = null,
1157 .inst_table = &inst_table,1177 .sema = &inline_sema,
1158 .func = module_fn,
1159 .owner_decl = scope.ownerDecl().?,
1160 .src_decl = module_fn.owner_decl,1178 .src_decl = module_fn.owner_decl,
1161 .instructions = .{},1179 .instructions = .{},
1162 .arena = sema.arena,
1163 .label = null,1180 .label = null,
1164 .inlining = &inlining,1181 .inlining = &inlining,
1165 .is_comptime = is_comptime_call,1182 .is_comptime = is_comptime_call,
1166 .branch_quota = b.branch_quota,
1167 };1183 };
11681184
1169 const merges = &child_block.inlining.?.merges;1185 const merges = &child_block.inlining.?.merges;
11701186
1171 defer child_block.instructions.deinit(mod.gpa);1187 defer child_block.instructions.deinit(sema.gpa);
1172 defer merges.results.deinit(mod.gpa);1188 defer merges.results.deinit(sema.gpa);
1173 defer merges.br_list.deinit(mod.gpa);1189 defer merges.br_list.deinit(sema.gpa);
11741190
1175 try mod.emitBackwardBranch(&child_block, call_src);1191 try sema.emitBackwardBranch(&child_block, call_src);
11761192
1177 // This will have return instructions analyzed as break instructions to1193 // This will have return instructions analyzed as break instructions to
1178 // the block_inst above.1194 // the block_inst above.
1179 try sema.analyzeBody(&child_block, module_fn.zir);1195 try sema.root(&child_block);
11801196
1181 return analyzeBlockBody(mod, scope, &child_block, merges);1197 return sema.analyzeBlockBody(block, &child_block, merges);
1182 }1198 }
11831199
1184 return block.addCall(call_src, ret_type, func, casted_args);1200 return block.addCall(call_src, ret_type, func, casted_args);
1185}1201}
11861202
1187fn zirIntType(sema: *Sema, block: *Scope.Block, inttype: zir.Inst.Index) InnerError!*Inst {1203fn zirIntType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1188 const tracy = trace(@src());1204 const tracy = trace(@src());
1189 defer tracy.end();1205 defer tracy.end();
1190 return sema.mod.fail(&block.base, inttype.base.src, "TODO implement inttype", .{});1206
1207 return sema.mod.fail(&block.base, sema.src, "TODO implement inttype", .{});
1191}1208}
11921209
1193fn zirOptionalType(sema: *Sema, block: *Scope.Block, optional: zir.Inst.Index) InnerError!*Inst {1210fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1194 const tracy = trace(@src());1211 const tracy = trace(@src());
1195 defer tracy.end();1212 defer tracy.end();
11961213
1197 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1214 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1198 const child_type = try sema.resolveType(block, inst_data.operand);1215 const src = inst_data.src();
1199 const opt_type = try mod.optionalType(sema.arena, child_type);1216 const child_type = try sema.resolveType(block, src, inst_data.operand);
1217 const opt_type = try sema.mod.optionalType(sema.arena, child_type);
12001218
1201 return sema.mod.constType(sema.arena, inst_data.src(), opt_type);1219 return sema.mod.constType(sema.arena, src, opt_type);
1202}1220}
12031221
1204fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1222fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1206,32 +1224,39 @@ fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: zir.Inst.I...@@ -1206,32 +1224,39 @@ fn zirOptionalTypeFromPtrElem(sema: *Sema, block: *Scope.Block, inst: zir.Inst.I
1206 defer tracy.end();1224 defer tracy.end();
12071225
1208 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1226 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1209 const ptr = sema.resolveInst(block, inst_data.operand);1227 const ptr = try sema.resolveInst(inst_data.operand);
1210 const elem_ty = ptr.ty.elemType();1228 const elem_ty = ptr.ty.elemType();
1211 const opt_ty = try mod.optionalType(sema.arena, elem_ty);1229 const opt_ty = try sema.mod.optionalType(sema.arena, elem_ty);
12121230
1213 return sema.mod.constType(sema.arena, inst_data.src(), opt_ty);1231 return sema.mod.constType(sema.arena, inst_data.src(), opt_ty);
1214}1232}
12151233
1216fn zirArrayType(sema: *Sema, block: *Scope.Block, array: zir.Inst.Index) InnerError!*Inst {1234fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1217 const tracy = trace(@src());1235 const tracy = trace(@src());
1218 defer tracy.end();1236 defer tracy.end();
1237
1219 // TODO these should be lazily evaluated1238 // TODO these should be lazily evaluated
1220 const len = try resolveInstConst(mod, scope, array.positionals.lhs);1239 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1221 const elem_type = try sema.resolveType(block, array.positionals.rhs);1240 const len = try sema.resolveInstConst(block, .unneeded, bin_inst.lhs);
1241 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
1242 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type);
12221243
1223 return sema.mod.constType(sema.arena, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), null, elem_type));1244 return sema.mod.constType(sema.arena, .unneeded, array_ty);
1224}1245}
12251246
1226fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, array: zir.Inst.Index) InnerError!*Inst {1247fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1227 const tracy = trace(@src());1248 const tracy = trace(@src());
1228 defer tracy.end();1249 defer tracy.end();
1250
1229 // TODO these should be lazily evaluated1251 // TODO these should be lazily evaluated
1230 const len = try resolveInstConst(mod, scope, array.positionals.len);1252 const inst_data = sema.code.instructions.items(.data)[inst].array_type_sentinel;
1231 const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);1253 const len = try sema.resolveInstConst(block, .unneeded, inst_data.len);
1232 const elem_type = try sema.resolveType(block, array.positionals.elem_type);1254 const extra = sema.code.extraData(zir.Inst.ArrayTypeSentinel, inst_data.payload_index).data;
1255 const sentinel = try sema.resolveInstConst(block, .unneeded, extra.sentinel);
1256 const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type);
1257 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type);
12331258
1234 return sema.mod.constType(sema.arena, array.base.src, try mod.arrayType(scope, len.val.toUnsignedInt(), sentinel.val, elem_type));1259 return sema.mod.constType(sema.arena, .unneeded, array_ty);
1235}1260}
12361261
1237fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1262fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1239,14 +1264,15 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn...@@ -1239,14 +1264,15 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
1239 defer tracy.end();1264 defer tracy.end();
12401265
1241 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1266 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1242 const error_union = try sema.resolveType(block, bin_inst.lhs);1267 const error_union = try sema.resolveType(block, .unneeded, bin_inst.lhs);
1243 const payload = try sema.resolveType(block, bin_inst.rhs);1268 const payload = try sema.resolveType(block, .unneeded, bin_inst.rhs);
12441269
1245 if (error_union.zigTypeTag() != .ErrorSet) {1270 if (error_union.zigTypeTag() != .ErrorSet) {
1246 return sema.mod.fail(&block.base, inst.base.src, "expected error set type, found {}", .{error_union.elemType()});1271 return sema.mod.fail(&block.base, .todo, "expected error set type, found {}", .{error_union.elemType()});
1247 }1272 }
1273 const err_union_ty = try sema.mod.errorUnionType(sema.arena, error_union, payload);
12481274
1249 return sema.mod.constType(sema.arena, inst.base.src, try mod.errorUnionType(scope, error_union, payload));1275 return sema.mod.constType(sema.arena, .unneeded, err_union_ty);
1250}1276}
12511277
1252fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1278fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1266,8 +1292,10 @@ fn zirErrorSet(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1266,8 +1292,10 @@ fn zirErrorSet(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1266 const tracy = trace(@src());1292 const tracy = trace(@src());
1267 defer tracy.end();1293 defer tracy.end();
12681294
1295 if (true) @panic("TODO update zirErrorSet in zir-memory-layout branch");
1296
1269 // The owner Decl arena will store the hashmap.1297 // The owner Decl arena will store the hashmap.
1270 var new_decl_arena = std.heap.ArenaAllocator.init(mod.gpa);1298 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
1271 errdefer new_decl_arena.deinit();1299 errdefer new_decl_arena.deinit();
12721300
1273 const payload = try new_decl_arena.allocator.create(Value.Payload.ErrorSet);1301 const payload = try new_decl_arena.allocator.create(Value.Payload.ErrorSet);
...@@ -1281,28 +1309,31 @@ fn zirErrorSet(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1281,28 +1309,31 @@ fn zirErrorSet(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1281 try payload.data.fields.ensureCapacity(&new_decl_arena.allocator, @intCast(u32, inst.positionals.fields.len));1309 try payload.data.fields.ensureCapacity(&new_decl_arena.allocator, @intCast(u32, inst.positionals.fields.len));
12821310
1283 for (inst.positionals.fields) |field_name| {1311 for (inst.positionals.fields) |field_name| {
1284 const entry = try mod.getErrorValue(field_name);1312 const entry = try sema.mod.getErrorValue(field_name);
1285 if (payload.data.fields.fetchPutAssumeCapacity(entry.key, {})) |_| {1313 if (payload.data.fields.fetchPutAssumeCapacity(entry.key, {})) |_| {
1286 return sema.mod.fail(&block.base, inst.base.src, "duplicate error: '{s}'", .{field_name});1314 return sema.mod.fail(&block.base, inst.base.src, "duplicate error: '{s}'", .{field_name});
1287 }1315 }
1288 }1316 }
1289 // TODO create name in format "error:line:column"1317 // TODO create name in format "error:line:column"
1290 const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{1318 const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{
1291 .ty = Type.initTag(.type),1319 .ty = Type.initTag(.type),
1292 .val = Value.initPayload(&payload.base),1320 .val = Value.initPayload(&payload.base),
1293 });1321 });
1294 payload.data.decl = new_decl;1322 payload.data.decl = new_decl;
1295 return mod.analyzeDeclVal(scope, inst.base.src, new_decl);1323 return sema.analyzeDeclVal(block, inst.base.src, new_decl);
1296}1324}
12971325
1298fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1326fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1299 const tracy = trace(@src());1327 const tracy = trace(@src());
1300 defer tracy.end();1328 defer tracy.end();
13011329
1330 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1331 const src = inst_data.src();
1332
1302 // Create an anonymous error set type with only this error value, and return the value.1333 // Create an anonymous error set type with only this error value, and return the value.
1303 const entry = try mod.getErrorValue(inst.positionals.name);1334 const entry = try sema.mod.getErrorValue(inst_data.get(sema.code));
1304 const result_type = try Type.Tag.error_set_single.create(sema.arena, entry.key);1335 const result_type = try Type.Tag.error_set_single.create(sema.arena, entry.key);
1305 return sema.mod.constInst(scope, inst.base.src, .{1336 return sema.mod.constInst(sema.arena, src, .{
1306 .ty = result_type,1337 .ty = result_type,
1307 .val = try Value.Tag.@"error".create(sema.arena, .{1338 .val = try Value.Tag.@"error".create(sema.arena, .{
1308 .name = entry.key,1339 .name = entry.key,
...@@ -1314,9 +1345,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn...@@ -1314,9 +1345,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
1314 const tracy = trace(@src());1345 const tracy = trace(@src());
1315 defer tracy.end();1346 defer tracy.end();
13161347
1348 if (true) @panic("TODO update zirMergeErrorSets in zir-memory-layout branch");
1349
1317 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1350 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1318 const lhs_ty = try sema.resolveType(block, bin_inst.lhs);1351 const lhs_ty = try sema.resolveType(block, .unneeded, bin_inst.lhs);
1319 const rhs_ty = try sema.resolveType(block, bin_inst.rhs);1352 const rhs_ty = try sema.resolveType(block, .unneeded, bin_inst.rhs);
1320 if (rhs_ty.zigTypeTag() != .ErrorSet)1353 if (rhs_ty.zigTypeTag() != .ErrorSet)
1321 return sema.mod.fail(&block.base, inst.positionals.rhs.src, "expected error set type, found {}", .{rhs_ty});1354 return sema.mod.fail(&block.base, inst.positionals.rhs.src, "expected error set type, found {}", .{rhs_ty});
1322 if (lhs_ty.zigTypeTag() != .ErrorSet)1355 if (lhs_ty.zigTypeTag() != .ErrorSet)
...@@ -1324,12 +1357,12 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn...@@ -1324,12 +1357,12 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
13241357
1325 // anything merged with anyerror is anyerror1358 // anything merged with anyerror is anyerror
1326 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror)1359 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror)
1327 return sema.mod.constInst(scope, inst.base.src, .{1360 return sema.mod.constInst(sema.arena, inst.base.src, .{
1328 .ty = Type.initTag(.type),1361 .ty = Type.initTag(.type),
1329 .val = Value.initTag(.anyerror_type),1362 .val = Value.initTag(.anyerror_type),
1330 });1363 });
1331 // The declarations arena will store the hashmap.1364 // The declarations arena will store the hashmap.
1332 var new_decl_arena = std.heap.ArenaAllocator.init(mod.gpa);1365 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
1333 errdefer new_decl_arena.deinit();1366 errdefer new_decl_arena.deinit();
13341367
1335 const payload = try new_decl_arena.allocator.create(Value.Payload.ErrorSet);1368 const payload = try new_decl_arena.allocator.create(Value.Payload.ErrorSet);
...@@ -1380,21 +1413,23 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn...@@ -1380,21 +1413,23 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
1380 else => unreachable,1413 else => unreachable,
1381 }1414 }
1382 // TODO create name in format "error:line:column"1415 // TODO create name in format "error:line:column"
1383 const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{1416 const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{
1384 .ty = Type.initTag(.type),1417 .ty = Type.initTag(.type),
1385 .val = Value.initPayload(&payload.base),1418 .val = Value.initPayload(&payload.base),
1386 });1419 });
1387 payload.data.decl = new_decl;1420 payload.data.decl = new_decl;
13881421
1389 return mod.analyzeDeclVal(scope, inst.base.src, new_decl);1422 return sema.analyzeDeclVal(block, inst.base.src, new_decl);
1390}1423}
13911424
1392fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, zir_inst: zir.Inst.Index) InnerError!*Inst {1425fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1393 const tracy = trace(@src());1426 const tracy = trace(@src());
1394 defer tracy.end();1427 defer tracy.end();
13951428
1396 const duped_name = try sema.arena.dupe(u8, inst.positionals.name);1429 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1397 return sema.mod.constInst(scope, inst.base.src, .{1430 const src = inst_data.src();
1431 const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code));
1432 return sema.mod.constInst(sema.arena, src, .{
1398 .ty = Type.initTag(.enum_literal),1433 .ty = Type.initTag(.enum_literal),
1399 .val = try Value.Tag.enum_literal.create(sema.arena, duped_name),1434 .val = try Value.Tag.enum_literal.create(sema.arena, duped_name),
1400 });1435 });
...@@ -1411,7 +1446,7 @@ fn zirOptionalPayloadPtr(...@@ -1411,7 +1446,7 @@ fn zirOptionalPayloadPtr(
1411 defer tracy.end();1446 defer tracy.end();
14121447
1413 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1448 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1414 const optional_ptr = sema.resolveInst(block, inst_data.operand);1449 const optional_ptr = try sema.resolveInst(inst_data.operand);
1415 assert(optional_ptr.ty.zigTypeTag() == .Pointer);1450 assert(optional_ptr.ty.zigTypeTag() == .Pointer);
1416 const src = inst_data.src();1451 const src = inst_data.src();
14171452
...@@ -1429,7 +1464,7 @@ fn zirOptionalPayloadPtr(...@@ -1429,7 +1464,7 @@ fn zirOptionalPayloadPtr(
1429 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});1464 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
1430 }1465 }
1431 // The same Value represents the pointer to the optional and the payload.1466 // The same Value represents the pointer to the optional and the payload.
1432 return sema.mod.constInst(scope, src, .{1467 return sema.mod.constInst(sema.arena, src, .{
1433 .ty = child_pointer,1468 .ty = child_pointer,
1434 .val = pointer_val,1469 .val = pointer_val,
1435 });1470 });
...@@ -1438,7 +1473,7 @@ fn zirOptionalPayloadPtr(...@@ -1438,7 +1473,7 @@ fn zirOptionalPayloadPtr(
1438 try sema.requireRuntimeBlock(block, src);1473 try sema.requireRuntimeBlock(block, src);
1439 if (safety_check and block.wantSafety()) {1474 if (safety_check and block.wantSafety()) {
1440 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null_ptr, optional_ptr);1475 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null_ptr, optional_ptr);
1441 try mod.addSafetyCheck(b, is_non_null, .unwrap_null);1476 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
1442 }1477 }
1443 return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr);1478 return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr);
1444}1479}
...@@ -1455,7 +1490,7 @@ fn zirOptionalPayload(...@@ -1455,7 +1490,7 @@ fn zirOptionalPayload(
14551490
1456 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1491 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1457 const src = inst_data.src();1492 const src = inst_data.src();
1458 const operand = sema.resolveInst(block, inst_data.operand);1493 const operand = try sema.resolveInst(inst_data.operand);
1459 const opt_type = operand.ty;1494 const opt_type = operand.ty;
1460 if (opt_type.zigTypeTag() != .Optional) {1495 if (opt_type.zigTypeTag() != .Optional) {
1461 return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});1496 return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});
...@@ -1467,7 +1502,7 @@ fn zirOptionalPayload(...@@ -1467,7 +1502,7 @@ fn zirOptionalPayload(
1467 if (val.isNull()) {1502 if (val.isNull()) {
1468 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});1503 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
1469 }1504 }
1470 return sema.mod.constInst(scope, src, .{1505 return sema.mod.constInst(sema.arena, src, .{
1471 .ty = child_type,1506 .ty = child_type,
1472 .val = val,1507 .val = val,
1473 });1508 });
...@@ -1476,7 +1511,7 @@ fn zirOptionalPayload(...@@ -1476,7 +1511,7 @@ fn zirOptionalPayload(
1476 try sema.requireRuntimeBlock(block, src);1511 try sema.requireRuntimeBlock(block, src);
1477 if (safety_check and block.wantSafety()) {1512 if (safety_check and block.wantSafety()) {
1478 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null, operand);1513 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null, operand);
1479 try mod.addSafetyCheck(b, is_non_null, .unwrap_null);1514 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
1480 }1515 }
1481 return block.addUnOp(src, child_type, .optional_payload, operand);1516 return block.addUnOp(src, child_type, .optional_payload, operand);
1482}1517}
...@@ -1493,7 +1528,7 @@ fn zirErrUnionPayload(...@@ -1493,7 +1528,7 @@ fn zirErrUnionPayload(
14931528
1494 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1529 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1495 const src = inst_data.src();1530 const src = inst_data.src();
1496 const operand = sema.resolveInst(block, inst_data.operand);1531 const operand = try sema.resolveInst(inst_data.operand);
1497 if (operand.ty.zigTypeTag() != .ErrorUnion)1532 if (operand.ty.zigTypeTag() != .ErrorUnion)
1498 return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty});1533 return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty});
14991534
...@@ -1502,7 +1537,7 @@ fn zirErrUnionPayload(...@@ -1502,7 +1537,7 @@ fn zirErrUnionPayload(
1502 return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name});1537 return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name});
1503 }1538 }
1504 const data = val.castTag(.error_union).?.data;1539 const data = val.castTag(.error_union).?.data;
1505 return sema.mod.constInst(scope, src, .{1540 return sema.mod.constInst(sema.arena, src, .{
1506 .ty = operand.ty.castTag(.error_union).?.data.payload,1541 .ty = operand.ty.castTag(.error_union).?.data.payload,
1507 .val = data,1542 .val = data,
1508 });1543 });
...@@ -1510,7 +1545,7 @@ fn zirErrUnionPayload(...@@ -1510,7 +1545,7 @@ fn zirErrUnionPayload(
1510 try sema.requireRuntimeBlock(block, src);1545 try sema.requireRuntimeBlock(block, src);
1511 if (safety_check and block.wantSafety()) {1546 if (safety_check and block.wantSafety()) {
1512 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);1547 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);
1513 try mod.addSafetyCheck(b, is_non_err, .unwrap_errunion);1548 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
1514 }1549 }
1515 return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_payload, operand);1550 return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_payload, operand);
1516}1551}
...@@ -1527,7 +1562,7 @@ fn zirErrUnionPayloadPtr(...@@ -1527,7 +1562,7 @@ fn zirErrUnionPayloadPtr(
15271562
1528 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1563 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1529 const src = inst_data.src();1564 const src = inst_data.src();
1530 const operand = sema.resolveInst(block, inst_data.operand);1565 const operand = try sema.resolveInst(inst_data.operand);
1531 assert(operand.ty.zigTypeTag() == .Pointer);1566 assert(operand.ty.zigTypeTag() == .Pointer);
15321567
1533 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)1568 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
...@@ -1542,7 +1577,7 @@ fn zirErrUnionPayloadPtr(...@@ -1542,7 +1577,7 @@ fn zirErrUnionPayloadPtr(
1542 }1577 }
1543 const data = val.castTag(.error_union).?.data;1578 const data = val.castTag(.error_union).?.data;
1544 // The same Value represents the pointer to the error union and the payload.1579 // The same Value represents the pointer to the error union and the payload.
1545 return sema.mod.constInst(scope, src, .{1580 return sema.mod.constInst(sema.arena, src, .{
1546 .ty = operand_pointer_ty,1581 .ty = operand_pointer_ty,
1547 .val = try Value.Tag.ref_val.create(1582 .val = try Value.Tag.ref_val.create(
1548 sema.arena,1583 sema.arena,
...@@ -1554,7 +1589,7 @@ fn zirErrUnionPayloadPtr(...@@ -1554,7 +1589,7 @@ fn zirErrUnionPayloadPtr(
1554 try sema.requireRuntimeBlock(block, src);1589 try sema.requireRuntimeBlock(block, src);
1555 if (safety_check and block.wantSafety()) {1590 if (safety_check and block.wantSafety()) {
1556 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);1591 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);
1557 try mod.addSafetyCheck(b, is_non_err, .unwrap_errunion);1592 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
1558 }1593 }
1559 return block.addUnOp(src, operand_pointer_ty, .unwrap_errunion_payload_ptr, operand);1594 return block.addUnOp(src, operand_pointer_ty, .unwrap_errunion_payload_ptr, operand);
1560}1595}
...@@ -1566,14 +1601,14 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner...@@ -1566,14 +1601,14 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
15661601
1567 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1602 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1568 const src = inst_data.src();1603 const src = inst_data.src();
1569 const operand = sema.resolveInst(block, inst_data.operand);1604 const operand = try sema.resolveInst(inst_data.operand);
1570 if (operand.ty.zigTypeTag() != .ErrorUnion)1605 if (operand.ty.zigTypeTag() != .ErrorUnion)
1571 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});1606 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
15721607
1573 if (operand.value()) |val| {1608 if (operand.value()) |val| {
1574 assert(val.getError() != null);1609 assert(val.getError() != null);
1575 const data = val.castTag(.error_union).?.data;1610 const data = val.castTag(.error_union).?.data;
1576 return sema.mod.constInst(scope, src, .{1611 return sema.mod.constInst(sema.arena, src, .{
1577 .ty = operand.ty.castTag(.error_union).?.data.error_set,1612 .ty = operand.ty.castTag(.error_union).?.data.error_set,
1578 .val = data,1613 .val = data,
1579 });1614 });
...@@ -1590,7 +1625,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -1590,7 +1625,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
15901625
1591 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1626 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1592 const src = inst_data.src();1627 const src = inst_data.src();
1593 const operand = sema.resolveInst(block, inst_data.operand);1628 const operand = try sema.resolveInst(inst_data.operand);
1594 assert(operand.ty.zigTypeTag() == .Pointer);1629 assert(operand.ty.zigTypeTag() == .Pointer);
15951630
1596 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)1631 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
...@@ -1600,7 +1635,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In...@@ -1600,7 +1635,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
1600 const val = try pointer_val.pointerDeref(sema.arena);1635 const val = try pointer_val.pointerDeref(sema.arena);
1601 assert(val.getError() != null);1636 assert(val.getError() != null);
1602 const data = val.castTag(.error_union).?.data;1637 const data = val.castTag(.error_union).?.data;
1603 return sema.mod.constInst(scope, src, .{1638 return sema.mod.constInst(sema.arena, src, .{
1604 .ty = operand.ty.elemType().castTag(.error_union).?.data.error_set,1639 .ty = operand.ty.elemType().castTag(.error_union).?.data.error_set,
1605 .val = data,1640 .val = data,
1606 });1641 });
...@@ -1616,7 +1651,7 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde...@@ -1616,7 +1651,7 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde
16161651
1617 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;1652 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1618 const src = inst_data.src();1653 const src = inst_data.src();
1619 const operand = sema.resolveInst(block, inst_data.operand);1654 const operand = try sema.resolveInst(inst_data.operand);
1620 if (operand.ty.zigTypeTag() != .ErrorUnion)1655 if (operand.ty.zigTypeTag() != .ErrorUnion)
1621 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});1656 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
1622 if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) {1657 if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) {
...@@ -1651,7 +1686,7 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args:...@@ -1651,7 +1686,7 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args:
1651 const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index);1686 const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index);
1652 const param_types = sema.code.extra[extra.end..][0..extra.data.param_types_len];1687 const param_types = sema.code.extra[extra.end..][0..extra.data.param_types_len];
16531688
1654 const cc_tv = try resolveInstConst(mod, scope, extra.data.cc);1689 const cc_tv = try sema.resolveInstConst(block, .todo, extra.data.cc);
1655 // TODO once we're capable of importing and analyzing decls from1690 // TODO once we're capable of importing and analyzing decls from
1656 // std.builtin, this needs to change1691 // std.builtin, this needs to change
1657 const cc_str = cc_tv.val.castTag(.enum_literal).?.data;1692 const cc_str = cc_tv.val.castTag(.enum_literal).?.data;
...@@ -1676,7 +1711,7 @@ fn fnTypeCommon(...@@ -1676,7 +1711,7 @@ fn fnTypeCommon(
1676 cc: std.builtin.CallingConvention,1711 cc: std.builtin.CallingConvention,
1677 var_args: bool,1712 var_args: bool,
1678) InnerError!*Inst {1713) InnerError!*Inst {
1679 const return_type = try sema.resolveType(block, zir_return_type);1714 const return_type = try sema.resolveType(block, src, zir_return_type);
16801715
1681 // Hot path for some common function types.1716 // Hot path for some common function types.
1682 if (zir_param_types.len == 0 and !var_args) {1717 if (zir_param_types.len == 0 and !var_args) {
...@@ -1699,7 +1734,7 @@ fn fnTypeCommon(...@@ -1699,7 +1734,7 @@ fn fnTypeCommon(
16991734
1700 const param_types = try sema.arena.alloc(Type, zir_param_types.len);1735 const param_types = try sema.arena.alloc(Type, zir_param_types.len);
1701 for (zir_param_types) |param_type, i| {1736 for (zir_param_types) |param_type, i| {
1702 const resolved = try sema.resolveType(block, param_type);1737 const resolved = try sema.resolveType(block, src, param_type);
1703 // TODO skip for comptime params1738 // TODO skip for comptime params
1704 if (!resolved.isValidVarType(false)) {1739 if (!resolved.isValidVarType(false)) {
1705 return sema.mod.fail(&block.base, .todo, "parameter of type '{}' must be declared comptime", .{resolved});1740 return sema.mod.fail(&block.base, .todo, "parameter of type '{}' must be declared comptime", .{resolved});
...@@ -1721,9 +1756,9 @@ fn zirAs(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Ins...@@ -1721,9 +1756,9 @@ fn zirAs(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Ins
1721 defer tracy.end();1756 defer tracy.end();
17221757
1723 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1758 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1724 const dest_type = try sema.resolveType(block, bin_inst.lhs);1759 const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs);
1725 const tzir_inst = sema.resolveInst(block, bin_inst.rhs);1760 const tzir_inst = try sema.resolveInst(bin_inst.rhs);
1726 return sema.coerce(scope, dest_type, tzir_inst);1761 return sema.coerce(block, dest_type, tzir_inst, .todo);
1727}1762}
17281763
1729fn zirPtrtoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1764fn zirPtrtoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1731,7 +1766,7 @@ fn zirPtrtoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1731,7 +1766,7 @@ fn zirPtrtoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1731 defer tracy.end();1766 defer tracy.end();
17321767
1733 const inst_data = sema.code.instructions.items(.data)[inst].un_node;1768 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1734 const ptr = sema.resolveInst(block, inst_data.operand);1769 const ptr = try sema.resolveInst(inst_data.operand);
1735 if (ptr.ty.zigTypeTag() != .Pointer) {1770 if (ptr.ty.zigTypeTag() != .Pointer) {
1736 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };1771 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1737 return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty});1772 return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty});
...@@ -1752,7 +1787,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1752,7 +1787,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1752 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };1787 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
1753 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;1788 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;
1754 const field_name = sema.code.string_bytes[extra.field_name_start..][0..extra.field_name_len];1789 const field_name = sema.code.string_bytes[extra.field_name_start..][0..extra.field_name_len];
1755 const object = sema.resolveInst(block, extra.lhs);1790 const object = try sema.resolveInst(extra.lhs);
1756 const object_ptr = try sema.analyzeRef(block, src, object);1791 const object_ptr = try sema.analyzeRef(block, src, object);
1757 const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);1792 const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
1758 return sema.analyzeDeref(block, src, result_ptr, result_ptr.src);1793 return sema.analyzeDeref(block, src, result_ptr, result_ptr.src);
...@@ -1767,7 +1802,7 @@ fn zirFieldPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1767,7 +1802,7 @@ fn zirFieldPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1767 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };1802 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
1768 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;1803 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;
1769 const field_name = sema.code.string_bytes[extra.field_name_start..][0..extra.field_name_len];1804 const field_name = sema.code.string_bytes[extra.field_name_start..][0..extra.field_name_len];
1770 const object_ptr = sema.resolveInst(block, extra.lhs);1805 const object_ptr = try sema.resolveInst(extra.lhs);
1771 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);1806 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
1772}1807}
17731808
...@@ -1779,7 +1814,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne...@@ -1779,7 +1814,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne
1779 const src = inst_data.src();1814 const src = inst_data.src();
1780 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };1815 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1781 const extra = sema.code.extraData(zir.Inst.FieldNamed, inst_data.payload_index).data;1816 const extra = sema.code.extraData(zir.Inst.FieldNamed, inst_data.payload_index).data;
1782 const object = sema.resolveInst(block, extra.lhs);1817 const object = try sema.resolveInst(extra.lhs);
1783 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);1818 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);
1784 const object_ptr = try sema.analyzeRef(block, src, object);1819 const object_ptr = try sema.analyzeRef(block, src, object);
1785 const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);1820 const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
...@@ -1794,7 +1829,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne...@@ -1794,7 +1829,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne
1794 const src = inst_data.src();1829 const src = inst_data.src();
1795 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };1830 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1796 const extra = sema.code.extraData(zir.Inst.FieldNamed, inst_data.payload_index).data;1831 const extra = sema.code.extraData(zir.Inst.FieldNamed, inst_data.payload_index).data;
1797 const object_ptr = sema.resolveInst(block, extra.lhs);1832 const object_ptr = try sema.resolveInst(extra.lhs);
1798 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);1833 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);
1799 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);1834 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
1800}1835}
...@@ -1803,40 +1838,43 @@ fn zirIntcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -1803,40 +1838,43 @@ fn zirIntcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
1803 const tracy = trace(@src());1838 const tracy = trace(@src());
1804 defer tracy.end();1839 defer tracy.end();
18051840
1806 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1841 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1807 const dest_type = try sema.resolveType(block, bin_inst.lhs);1842 const src = inst_data.src();
1808 const operand = sema.resolveInst(bin_inst.rhs);1843 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1844 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1845 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1846
1847 const dest_type = try sema.resolveType(block, dest_ty_src, extra.lhs);
1848 const operand = try sema.resolveInst(extra.rhs);
18091849
1810 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {1850 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {
1811 .ComptimeInt => true,1851 .ComptimeInt => true,
1812 .Int => false,1852 .Int => false,
1813 else => return mod.fail(1853 else => return sema.mod.fail(
1814 scope,1854 &block.base,
1815 inst.positionals.lhs.src,1855 dest_ty_src,
1816 "expected integer type, found '{}'",1856 "expected integer type, found '{}'",
1817 .{1857 .{dest_type},
1818 dest_type,
1819 },
1820 ),1858 ),
1821 };1859 };
18221860
1823 switch (operand.ty.zigTypeTag()) {1861 switch (operand.ty.zigTypeTag()) {
1824 .ComptimeInt, .Int => {},1862 .ComptimeInt, .Int => {},
1825 else => return mod.fail(1863 else => return sema.mod.fail(
1826 scope,1864 &block.base,
1827 inst.positionals.rhs.src,1865 operand_src,
1828 "expected integer type, found '{}'",1866 "expected integer type, found '{}'",
1829 .{operand.ty},1867 .{operand.ty},
1830 ),1868 ),
1831 }1869 }
18321870
1833 if (operand.value() != null) {1871 if (operand.value() != null) {
1834 return sema.coerce(scope, dest_type, operand);1872 return sema.coerce(block, dest_type, operand, operand_src);
1835 } else if (dest_is_comptime_int) {1873 } else if (dest_is_comptime_int) {
1836 return sema.mod.fail(&block.base, inst.base.src, "unable to cast runtime value to 'comptime_int'", .{});1874 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{});
1837 }1875 }
18381876
1839 return sema.mod.fail(&block.base, inst.base.src, "TODO implement analyze widen or shorten int", .{});1877 return sema.mod.fail(&block.base, src, "TODO implement analyze widen or shorten int", .{});
1840}1878}
18411879
1842fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1880fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1844,49 +1882,52 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -1844,49 +1882,52 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
1844 defer tracy.end();1882 defer tracy.end();
18451883
1846 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1884 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1847 const dest_type = try sema.resolveType(block, bin_inst.lhs);1885 const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs);
1848 const operand = sema.resolveInst(bin_inst.rhs);1886 const operand = try sema.resolveInst(bin_inst.rhs);
1849 return mod.bitcast(scope, dest_type, operand);1887 return sema.bitcast(block, dest_type, operand);
1850}1888}
18511889
1852fn zirFloatcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1890fn zirFloatcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1853 const tracy = trace(@src());1891 const tracy = trace(@src());
1854 defer tracy.end();1892 defer tracy.end();
18551893
1856 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1894 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1857 const dest_type = try sema.resolveType(block, bin_inst.lhs);1895 const src = inst_data.src();
1858 const operand = sema.resolveInst(bin_inst.rhs);1896 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1897 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1898 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1899
1900 const dest_type = try sema.resolveType(block, dest_ty_src, extra.lhs);
1901 const operand = try sema.resolveInst(extra.rhs);
18591902
1860 const dest_is_comptime_float = switch (dest_type.zigTypeTag()) {1903 const dest_is_comptime_float = switch (dest_type.zigTypeTag()) {
1861 .ComptimeFloat => true,1904 .ComptimeFloat => true,
1862 .Float => false,1905 .Float => false,
1863 else => return mod.fail(1906 else => return sema.mod.fail(
1864 scope,1907 &block.base,
1865 inst.positionals.lhs.src,1908 dest_ty_src,
1866 "expected float type, found '{}'",1909 "expected float type, found '{}'",
1867 .{1910 .{dest_type},
1868 dest_type,
1869 },
1870 ),1911 ),
1871 };1912 };
18721913
1873 switch (operand.ty.zigTypeTag()) {1914 switch (operand.ty.zigTypeTag()) {
1874 .ComptimeFloat, .Float, .ComptimeInt => {},1915 .ComptimeFloat, .Float, .ComptimeInt => {},
1875 else => return mod.fail(1916 else => return sema.mod.fail(
1876 scope,1917 &block.base,
1877 inst.positionals.rhs.src,1918 operand_src,
1878 "expected float type, found '{}'",1919 "expected float type, found '{}'",
1879 .{operand.ty},1920 .{operand.ty},
1880 ),1921 ),
1881 }1922 }
18821923
1883 if (operand.value() != null) {1924 if (operand.value() != null) {
1884 return sema.coerce(scope, dest_type, operand);1925 return sema.coerce(block, dest_type, operand, operand_src);
1885 } else if (dest_is_comptime_float) {1926 } else if (dest_is_comptime_float) {
1886 return sema.mod.fail(&block.base, inst.base.src, "unable to cast runtime value to 'comptime_float'", .{});1927 return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_float'", .{});
1887 }1928 }
18881929
1889 return sema.mod.fail(&block.base, inst.base.src, "TODO implement analyze widen or shorten float", .{});1930 return sema.mod.fail(&block.base, src, "TODO implement analyze widen or shorten float", .{});
1890}1931}
18911932
1892fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1933fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -1894,9 +1935,9 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -1894,9 +1935,9 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
1894 defer tracy.end();1935 defer tracy.end();
18951936
1896 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1937 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1897 const array = sema.resolveInst(block, bin_inst.lhs);1938 const array = try sema.resolveInst(bin_inst.lhs);
1898 const array_ptr = try sema.analyzeRef(block, sema.src, array);1939 const array_ptr = try sema.analyzeRef(block, sema.src, array);
1899 const elem_index = sema.resolveInst(block, bin_inst.rhs);1940 const elem_index = try sema.resolveInst(bin_inst.rhs);
1900 const result_ptr = try sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);1941 const result_ptr = try sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);
1901 return sema.analyzeDeref(block, sema.src, result_ptr, sema.src);1942 return sema.analyzeDeref(block, sema.src, result_ptr, sema.src);
1902}1943}
...@@ -1909,9 +1950,9 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -1909,9 +1950,9 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
1909 const src = inst_data.src();1950 const src = inst_data.src();
1910 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };1951 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
1911 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;1952 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1912 const array = sema.resolveInst(block, extra.lhs);1953 const array = try sema.resolveInst(extra.lhs);
1913 const array_ptr = try sema.analyzeRef(block, src, array);1954 const array_ptr = try sema.analyzeRef(block, src, array);
1914 const elem_index = sema.resolveInst(block, extra.rhs);1955 const elem_index = try sema.resolveInst(extra.rhs);
1915 const result_ptr = try sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);1956 const result_ptr = try sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);
1916 return sema.analyzeDeref(block, src, result_ptr, src);1957 return sema.analyzeDeref(block, src, result_ptr, src);
1917}1958}
...@@ -1921,8 +1962,8 @@ fn zirElemPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -1921,8 +1962,8 @@ fn zirElemPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
1921 defer tracy.end();1962 defer tracy.end();
19221963
1923 const bin_inst = sema.code.instructions.items(.data)[inst].bin;1964 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1924 const array_ptr = sema.resolveInst(block, bin_inst.lhs);1965 const array_ptr = try sema.resolveInst(bin_inst.lhs);
1925 const elem_index = sema.resolveInst(block, bin_inst.rhs);1966 const elem_index = try sema.resolveInst(bin_inst.rhs);
1926 return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);1967 return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);
1927}1968}
19281969
...@@ -1934,8 +1975,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -1934,8 +1975,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
1934 const src = inst_data.src();1975 const src = inst_data.src();
1935 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };1976 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
1936 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;1977 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1937 const array_ptr = sema.resolveInst(block, extra.lhs);1978 const array_ptr = try sema.resolveInst(extra.lhs);
1938 const elem_index = sema.resolveInst(block, extra.rhs);1979 const elem_index = try sema.resolveInst(extra.rhs);
1939 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);1980 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);
1940}1981}
19411982
...@@ -1946,8 +1987,8 @@ fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -1946,8 +1987,8 @@ fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
1946 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1987 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1947 const src = inst_data.src();1988 const src = inst_data.src();
1948 const extra = sema.code.extraData(zir.Inst.SliceStart, inst_data.payload_index).data;1989 const extra = sema.code.extraData(zir.Inst.SliceStart, inst_data.payload_index).data;
1949 const array_ptr = sema.resolveInst(extra.lhs);1990 const array_ptr = try sema.resolveInst(extra.lhs);
1950 const start = sema.resolveInst(extra.start);1991 const start = try sema.resolveInst(extra.start);
19511992
1952 return sema.analyzeSlice(block, src, array_ptr, start, null, null, .unneeded);1993 return sema.analyzeSlice(block, src, array_ptr, start, null, null, .unneeded);
1953}1994}
...@@ -1959,9 +2000,9 @@ fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -1959,9 +2000,9 @@ fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
1959 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2000 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1960 const src = inst_data.src();2001 const src = inst_data.src();
1961 const extra = sema.code.extraData(zir.Inst.SliceEnd, inst_data.payload_index).data;2002 const extra = sema.code.extraData(zir.Inst.SliceEnd, inst_data.payload_index).data;
1962 const array_ptr = sema.resolveInst(extra.lhs);2003 const array_ptr = try sema.resolveInst(extra.lhs);
1963 const start = sema.resolveInst(extra.start);2004 const start = try sema.resolveInst(extra.start);
1964 const end = sema.resolveInst(extra.end);2005 const end = try sema.resolveInst(extra.end);
19652006
1966 return sema.analyzeSlice(block, src, array_ptr, start, end, null, .unneeded);2007 return sema.analyzeSlice(block, src, array_ptr, start, end, null, .unneeded);
1967}2008}
...@@ -1974,21 +2015,22 @@ fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne...@@ -1974,21 +2015,22 @@ fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne
1974 const src = inst_data.src();2015 const src = inst_data.src();
1975 const sentinel_src: LazySrcLoc = .{ .node_offset_slice_sentinel = inst_data.src_node };2016 const sentinel_src: LazySrcLoc = .{ .node_offset_slice_sentinel = inst_data.src_node };
1976 const extra = sema.code.extraData(zir.Inst.SliceSentinel, inst_data.payload_index).data;2017 const extra = sema.code.extraData(zir.Inst.SliceSentinel, inst_data.payload_index).data;
1977 const array_ptr = sema.resolveInst(extra.lhs);2018 const array_ptr = try sema.resolveInst(extra.lhs);
1978 const start = sema.resolveInst(extra.start);2019 const start = try sema.resolveInst(extra.start);
1979 const end = sema.resolveInst(extra.end);2020 const end = try sema.resolveInst(extra.end);
1980 const sentinel = sema.resolveInst(extra.sentinel);2021 const sentinel = try sema.resolveInst(extra.sentinel);
19812022
1982 return sema.analyzeSlice(block, inst.base.src, array_ptr, start, end, sentinel, sentinel_src);2023 return sema.analyzeSlice(block, src, array_ptr, start, end, sentinel, sentinel_src);
1983}2024}
19842025
1985fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2026fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1986 const tracy = trace(@src());2027 const tracy = trace(@src());
1987 defer tracy.end();2028 defer tracy.end();
19882029
2030 const src: LazySrcLoc = .todo;
1989 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2031 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1990 const start = sema.resolveInst(bin_inst.lhs);2032 const start = try sema.resolveInst(bin_inst.lhs);
1991 const end = sema.resolveInst(bin_inst.rhs);2033 const end = try sema.resolveInst(bin_inst.rhs);
19922034
1993 switch (start.ty.zigTypeTag()) {2035 switch (start.ty.zigTypeTag()) {
1994 .Int, .ComptimeInt => {},2036 .Int, .ComptimeInt => {},
...@@ -2002,7 +2044,7 @@ fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -2002,7 +2044,7 @@ fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
2002 const start_val = start.value().?;2044 const start_val = start.value().?;
2003 const end_val = end.value().?;2045 const end_val = end.value().?;
2004 if (start_val.compare(.gte, end_val)) {2046 if (start_val.compare(.gte, end_val)) {
2005 return sema.mod.fail(&block.base, inst.base.src, "range start value must be smaller than the end value", .{});2047 return sema.mod.fail(&block.base, src, "range start value must be smaller than the end value", .{});
2006 }2048 }
2007 return sema.mod.constVoid(sema.arena, .unneeded);2049 return sema.mod.constVoid(sema.arena, .unneeded);
2008}2050}
...@@ -2018,32 +2060,32 @@ fn zirSwitchBr(...@@ -2018,32 +2060,32 @@ fn zirSwitchBr(
20182060
2019 if (true) @panic("TODO rework with zir-memory-layout in mind");2061 if (true) @panic("TODO rework with zir-memory-layout in mind");
20202062
2021 const target_ptr = sema.resolveInst(block, inst.positionals.target);2063 const target_ptr = try sema.resolveInst(inst.positionals.target);
2022 const target = if (ref)2064 const target = if (ref)
2023 try sema.analyzeDeref(block, inst.base.src, target_ptr, inst.positionals.target.src)2065 try sema.analyzeDeref(parent_block, inst.base.src, target_ptr, inst.positionals.target.src)
2024 else2066 else
2025 target_ptr;2067 target_ptr;
2026 try validateSwitch(mod, scope, target, inst);2068 try sema.validateSwitch(parent_block, target, inst);
20272069
2028 if (try mod.resolveDefinedValue(scope, target)) |target_val| {2070 if (try sema.resolveDefinedValue(parent_block, inst.base.src, target)) |target_val| {
2029 for (inst.positionals.cases) |case| {2071 for (inst.positionals.cases) |case| {
2030 const resolved = sema.resolveInst(block, case.item);2072 const resolved = try sema.resolveInst(case.item);
2031 const casted = try sema.coerce(scope, target.ty, resolved);2073 const casted = try sema.coerce(block, target.ty, resolved, resolved_src);
2032 const item = try sema.resolveConstValue(parent_block, case_src, casted);2074 const item = try sema.resolveConstValue(parent_block, case_src, casted);
20332075
2034 if (target_val.eql(item)) {2076 if (target_val.eql(item)) {
2035 try sema.analyzeBody(scope.cast(Scope.Block).?, case.body);2077 try sema.analyzeBody(parent_block, case.body);
2036 return mod.constNoReturn(scope, inst.base.src);2078 return sema.mod.constNoReturn(sema.arena, inst.base.src);
2037 }2079 }
2038 }2080 }
2039 try sema.analyzeBody(scope.cast(Scope.Block).?, inst.positionals.else_body);2081 try sema.analyzeBody(parent_block, inst.positionals.else_body);
2040 return mod.constNoReturn(scope, inst.base.src);2082 return sema.mod.constNoReturn(sema.arena, inst.base.src);
2041 }2083 }
20422084
2043 if (inst.positionals.cases.len == 0) {2085 if (inst.positionals.cases.len == 0) {
2044 // no cases just analyze else_branch2086 // no cases just analyze else_branch
2045 try sema.analyzeBody(scope.cast(Scope.Block).?, inst.positionals.else_body);2087 try sema.analyzeBody(parent_block, inst.positionals.else_body);
2046 return mod.constNoReturn(scope, inst.base.src);2088 return sema.mod.constNoReturn(sema.arena, inst.base.src);
2047 }2089 }
20482090
2049 try sema.requireRuntimeBlock(parent_block, inst.base.src);2091 try sema.requireRuntimeBlock(parent_block, inst.base.src);
...@@ -2051,24 +2093,20 @@ fn zirSwitchBr(...@@ -2051,24 +2093,20 @@ fn zirSwitchBr(
20512093
2052 var case_block: Scope.Block = .{2094 var case_block: Scope.Block = .{
2053 .parent = parent_block,2095 .parent = parent_block,
2054 .inst_table = parent_block.inst_table,2096 .sema = sema,
2055 .func = parent_block.func,
2056 .owner_decl = parent_block.owner_decl,
2057 .src_decl = parent_block.src_decl,2097 .src_decl = parent_block.src_decl,
2058 .instructions = .{},2098 .instructions = .{},
2059 .arena = sema.arena,
2060 .inlining = parent_block.inlining,2099 .inlining = parent_block.inlining,
2061 .is_comptime = parent_block.is_comptime,2100 .is_comptime = parent_block.is_comptime,
2062 .branch_quota = parent_block.branch_quota,
2063 };2101 };
2064 defer case_block.instructions.deinit(mod.gpa);2102 defer case_block.instructions.deinit(sema.gpa);
20652103
2066 for (inst.positionals.cases) |case, i| {2104 for (inst.positionals.cases) |case, i| {
2067 // Reset without freeing.2105 // Reset without freeing.
2068 case_block.instructions.items.len = 0;2106 case_block.instructions.items.len = 0;
20692107
2070 const resolved = sema.resolveInst(block, case.item);2108 const resolved = try sema.resolveInst(case.item);
2071 const casted = try sema.coerce(scope, target.ty, resolved);2109 const casted = try sema.coerce(block, target.ty, resolved, resolved_src);
2072 const item = try sema.resolveConstValue(parent_block, case_src, casted);2110 const item = try sema.resolveConstValue(parent_block, case_src, casted);
20732111
2074 try sema.analyzeBody(&case_block, case.body);2112 try sema.analyzeBody(&case_block, case.body);
...@@ -2113,15 +2151,15 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins...@@ -2113,15 +2151,15 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
2113 .ErrorSet => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .ErrorSet", .{}),2151 .ErrorSet => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .ErrorSet", .{}),
2114 .Union => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .Union", .{}),2152 .Union => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .Union", .{}),
2115 .Int, .ComptimeInt => {2153 .Int, .ComptimeInt => {
2116 var range_set = @import("RangeSet.zig").init(mod.gpa);2154 var range_set = @import("RangeSet.zig").init(sema.gpa);
2117 defer range_set.deinit();2155 defer range_set.deinit();
21182156
2119 for (inst.positionals.items) |item| {2157 for (inst.positionals.items) |item| {
2120 const maybe_src = if (item.castTag(.switch_range)) |range| blk: {2158 const maybe_src = if (item.castTag(.switch_range)) |range| blk: {
2121 const start_resolved = sema.resolveInst(block, range.positionals.lhs);2159 const start_resolved = try sema.resolveInst(range.positionals.lhs);
2122 const start_casted = try sema.coerce(scope, target.ty, start_resolved);2160 const start_casted = try sema.coerce(block, target.ty, start_resolved);
2123 const end_resolved = sema.resolveInst(block, range.positionals.rhs);2161 const end_resolved = try sema.resolveInst(range.positionals.rhs);
2124 const end_casted = try sema.coerce(scope, target.ty, end_resolved);2162 const end_casted = try sema.coerce(block, target.ty, end_resolved);
21252163
2126 break :blk try range_set.add(2164 break :blk try range_set.add(
2127 try sema.resolveConstValue(block, range_start_src, start_casted),2165 try sema.resolveConstValue(block, range_start_src, start_casted),
...@@ -2129,8 +2167,8 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins...@@ -2129,8 +2167,8 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
2129 item.src,2167 item.src,
2130 );2168 );
2131 } else blk: {2169 } else blk: {
2132 const resolved = sema.resolveInst(block, item);2170 const resolved = try sema.resolveInst(item);
2133 const casted = try sema.coerce(scope, target.ty, resolved);2171 const casted = try sema.coerce(block, target.ty, resolved);
2134 const value = try sema.resolveConstValue(block, item_src, casted);2172 const value = try sema.resolveConstValue(block, item_src, casted);
2135 break :blk try range_set.add(value, value, item.src);2173 break :blk try range_set.add(value, value, item.src);
2136 };2174 };
...@@ -2142,7 +2180,7 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins...@@ -2142,7 +2180,7 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
2142 }2180 }
21432181
2144 if (target.ty.zigTypeTag() == .Int) {2182 if (target.ty.zigTypeTag() == .Int) {
2145 var arena = std.heap.ArenaAllocator.init(mod.gpa);2183 var arena = std.heap.ArenaAllocator.init(sema.gpa);
2146 defer arena.deinit();2184 defer arena.deinit();
21472185
2148 const start = try target.ty.minInt(&arena, mod.getTarget());2186 const start = try target.ty.minInt(&arena, mod.getTarget());
...@@ -2163,8 +2201,8 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins...@@ -2163,8 +2201,8 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
2163 var true_count: u8 = 0;2201 var true_count: u8 = 0;
2164 var false_count: u8 = 0;2202 var false_count: u8 = 0;
2165 for (inst.positionals.items) |item| {2203 for (inst.positionals.items) |item| {
2166 const resolved = sema.resolveInst(block, item);2204 const resolved = try sema.resolveInst(item);
2167 const casted = try sema.coerce(scope, Type.initTag(.bool), resolved);2205 const casted = try sema.coerce(block, Type.initTag(.bool), resolved);
2168 if ((try sema.resolveConstValue(block, item_src, casted)).toBool()) {2206 if ((try sema.resolveConstValue(block, item_src, casted)).toBool()) {
2169 true_count += 1;2207 true_count += 1;
2170 } else {2208 } else {
...@@ -2187,12 +2225,12 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins...@@ -2187,12 +2225,12 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
2187 return sema.mod.fail(&block.base, inst.base.src, "else prong required when switching on type '{}'", .{target.ty});2225 return sema.mod.fail(&block.base, inst.base.src, "else prong required when switching on type '{}'", .{target.ty});
2188 }2226 }
21892227
2190 var seen_values = std.HashMap(Value, usize, Value.hash, Value.eql, std.hash_map.DefaultMaxLoadPercentage).init(mod.gpa);2228 var seen_values = std.HashMap(Value, usize, Value.hash, Value.eql, std.hash_map.DefaultMaxLoadPercentage).init(sema.gpa);
2191 defer seen_values.deinit();2229 defer seen_values.deinit();
21922230
2193 for (inst.positionals.items) |item| {2231 for (inst.positionals.items) |item| {
2194 const resolved = sema.resolveInst(block, item);2232 const resolved = try sema.resolveInst(item);
2195 const casted = try sema.coerce(scope, target.ty, resolved);2233 const casted = try sema.coerce(block, target.ty, resolved);
2196 const val = try sema.resolveConstValue(block, item_src, casted);2234 const val = try sema.resolveConstValue(block, item_src, casted);
21972235
2198 if (try seen_values.fetchPut(val, item.src)) |prev| {2236 if (try seen_values.fetchPut(val, item.src)) |prev| {
...@@ -2249,27 +2287,30 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!...@@ -2249,27 +2287,30 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!
2249fn zirShl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2287fn zirShl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2250 const tracy = trace(@src());2288 const tracy = trace(@src());
2251 defer tracy.end();2289 defer tracy.end();
2252 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirShl", .{});2290 return sema.mod.fail(&block.base, sema.src, "TODO implement zirShl", .{});
2253}2291}
22542292
2255fn zirShr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2293fn zirShr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2256 const tracy = trace(@src());2294 const tracy = trace(@src());
2257 defer tracy.end();2295 defer tracy.end();
2258 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirShr", .{});2296 return sema.mod.fail(&block.base, sema.src, "TODO implement zirShr", .{});
2259}2297}
22602298
2261fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2299fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2262 const tracy = trace(@src());2300 const tracy = trace(@src());
2263 defer tracy.end();2301 defer tracy.end();
22642302
2303 if (true) @panic("TODO rework with zir-memory-layout in mind");
2304
2265 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2305 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2266 const lhs = sema.resolveInst(bin_inst.lhs);2306 const src: LazySrcLoc = .todo;
2267 const rhs = sema.resolveInst(bin_inst.rhs);2307 const lhs = try sema.resolveInst(bin_inst.lhs);
2308 const rhs = try sema.resolveInst(bin_inst.rhs);
22682309
2269 const instructions = &[_]*Inst{ lhs, rhs };2310 const instructions = &[_]*Inst{ lhs, rhs };
2270 const resolved_type = try sema.resolvePeerTypes(block, instructions);2311 const resolved_type = try sema.resolvePeerTypes(block, instructions);
2271 const casted_lhs = try sema.coerce(scope, resolved_type, lhs);2312 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);
2272 const casted_rhs = try sema.coerce(scope, resolved_type, rhs);2313 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);
22732314
2274 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)2315 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
2275 resolved_type.elemType()2316 resolved_type.elemType()
...@@ -2280,14 +2321,14 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2280,14 +2321,14 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
22802321
2281 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {2322 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
2282 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {2323 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {
2283 return sema.mod.fail(&block.base, inst.base.src, "vector length mismatch: {d} and {d}", .{2324 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
2284 lhs.ty.arrayLen(),2325 lhs.ty.arrayLen(),
2285 rhs.ty.arrayLen(),2326 rhs.ty.arrayLen(),
2286 });2327 });
2287 }2328 }
2288 return sema.mod.fail(&block.base, inst.base.src, "TODO implement support for vectors in zirBitwise", .{});2329 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBitwise", .{});
2289 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {2330 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {
2290 return sema.mod.fail(&block.base, inst.base.src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{2331 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
2291 lhs.ty,2332 lhs.ty,
2292 rhs.ty,2333 rhs.ty,
2293 });2334 });
...@@ -2296,22 +2337,22 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2296,22 +2337,22 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2296 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;2337 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
22972338
2298 if (!is_int) {2339 if (!is_int) {
2299 return sema.mod.fail(&block.base, inst.base.src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });2340 return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });
2300 }2341 }
23012342
2302 if (casted_lhs.value()) |lhs_val| {2343 if (casted_lhs.value()) |lhs_val| {
2303 if (casted_rhs.value()) |rhs_val| {2344 if (casted_rhs.value()) |rhs_val| {
2304 if (lhs_val.isUndef() or rhs_val.isUndef()) {2345 if (lhs_val.isUndef() or rhs_val.isUndef()) {
2305 return sema.mod.constInst(scope, inst.base.src, .{2346 return sema.mod.constInst(sema.arena, src, .{
2306 .ty = resolved_type,2347 .ty = resolved_type,
2307 .val = Value.initTag(.undef),2348 .val = Value.initTag(.undef),
2308 });2349 });
2309 }2350 }
2310 return sema.mod.fail(&block.base, inst.base.src, "TODO implement comptime bitwise operations", .{});2351 return sema.mod.fail(&block.base, src, "TODO implement comptime bitwise operations", .{});
2311 }2352 }
2312 }2353 }
23132354
2314 try sema.requireRuntimeBlock(block, inst.base.src);2355 try sema.requireRuntimeBlock(block, src);
2315 const ir_tag = switch (inst.base.tag) {2356 const ir_tag = switch (inst.base.tag) {
2316 .bit_and => Inst.Tag.bit_and,2357 .bit_and => Inst.Tag.bit_and,
2317 .bit_or => Inst.Tag.bit_or,2358 .bit_or => Inst.Tag.bit_or,
...@@ -2319,39 +2360,42 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2319,39 +2360,42 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2319 else => unreachable,2360 else => unreachable,
2320 };2361 };
23212362
2322 return mod.addBinOp(b, inst.base.src, scalar_type, ir_tag, casted_lhs, casted_rhs);2363 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);
2323}2364}
23242365
2325fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2366fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2326 const tracy = trace(@src());2367 const tracy = trace(@src());
2327 defer tracy.end();2368 defer tracy.end();
2328 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirBitNot", .{});2369 return sema.mod.fail(&block.base, sema.src, "TODO implement zirBitNot", .{});
2329}2370}
23302371
2331fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2372fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2332 const tracy = trace(@src());2373 const tracy = trace(@src());
2333 defer tracy.end();2374 defer tracy.end();
2334 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirArrayCat", .{});2375 return sema.mod.fail(&block.base, sema.src, "TODO implement zirArrayCat", .{});
2335}2376}
23362377
2337fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2378fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2338 const tracy = trace(@src());2379 const tracy = trace(@src());
2339 defer tracy.end();2380 defer tracy.end();
2340 return sema.mod.fail(&block.base, inst.base.src, "TODO implement zirArrayMul", .{});2381 return sema.mod.fail(&block.base, sema.src, "TODO implement zirArrayMul", .{});
2341}2382}
23422383
2343fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2384fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2344 const tracy = trace(@src());2385 const tracy = trace(@src());
2345 defer tracy.end();2386 defer tracy.end();
23462387
2388 if (true) @panic("TODO rework with zir-memory-layout in mind");
2389
2347 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2390 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2348 const lhs = sema.resolveInst(bin_inst.lhs);2391 const src: LazySrcLoc = .todo;
2349 const rhs = sema.resolveInst(bin_inst.rhs);2392 const lhs = try sema.resolveInst(bin_inst.lhs);
2393 const rhs = try sema.resolveInst(bin_inst.rhs);
23502394
2351 const instructions = &[_]*Inst{ lhs, rhs };2395 const instructions = &[_]*Inst{ lhs, rhs };
2352 const resolved_type = try sema.resolvePeerTypes(block, instructions);2396 const resolved_type = try sema.resolvePeerTypes(block, instructions);
2353 const casted_lhs = try sema.coerce(scope, resolved_type, lhs);2397 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);
2354 const casted_rhs = try sema.coerce(scope, resolved_type, rhs);2398 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);
23552399
2356 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)2400 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
2357 resolved_type.elemType()2401 resolved_type.elemType()
...@@ -2362,14 +2406,14 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2362,14 +2406,14 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
23622406
2363 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {2407 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
2364 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {2408 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {
2365 return sema.mod.fail(&block.base, inst.base.src, "vector length mismatch: {d} and {d}", .{2409 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
2366 lhs.ty.arrayLen(),2410 lhs.ty.arrayLen(),
2367 rhs.ty.arrayLen(),2411 rhs.ty.arrayLen(),
2368 });2412 });
2369 }2413 }
2370 return sema.mod.fail(&block.base, inst.base.src, "TODO implement support for vectors in zirBinOp", .{});2414 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBinOp", .{});
2371 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {2415 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {
2372 return sema.mod.fail(&block.base, inst.base.src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{2416 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
2373 lhs.ty,2417 lhs.ty,
2374 rhs.ty,2418 rhs.ty,
2375 });2419 });
...@@ -2379,22 +2423,22 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2379,22 +2423,22 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
2379 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;2423 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
23802424
2381 if (!is_int and !(is_float and floatOpAllowed(inst.base.tag))) {2425 if (!is_int and !(is_float and floatOpAllowed(inst.base.tag))) {
2382 return sema.mod.fail(&block.base, inst.base.src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });2426 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });
2383 }2427 }
23842428
2385 if (casted_lhs.value()) |lhs_val| {2429 if (casted_lhs.value()) |lhs_val| {
2386 if (casted_rhs.value()) |rhs_val| {2430 if (casted_rhs.value()) |rhs_val| {
2387 if (lhs_val.isUndef() or rhs_val.isUndef()) {2431 if (lhs_val.isUndef() or rhs_val.isUndef()) {
2388 return sema.mod.constInst(scope, inst.base.src, .{2432 return sema.mod.constInst(sema.arena, src, .{
2389 .ty = resolved_type,2433 .ty = resolved_type,
2390 .val = Value.initTag(.undef),2434 .val = Value.initTag(.undef),
2391 });2435 });
2392 }2436 }
2393 return analyzeInstComptimeOp(mod, scope, scalar_type, inst, lhs_val, rhs_val);2437 return sema.analyzeInstComptimeOp(block, scalar_type, inst, lhs_val, rhs_val);
2394 }2438 }
2395 }2439 }
23962440
2397 try sema.requireRuntimeBlock(block, inst.base.src);2441 try sema.requireRuntimeBlock(block, src);
2398 const ir_tag: Inst.Tag = switch (inst.base.tag) {2442 const ir_tag: Inst.Tag = switch (inst.base.tag) {
2399 .add => .add,2443 .add => .add,
2400 .addwrap => .addwrap,2444 .addwrap => .addwrap,
...@@ -2402,18 +2446,27 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2402,18 +2446,27 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
2402 .subwrap => .subwrap,2446 .subwrap => .subwrap,
2403 .mul => .mul,2447 .mul => .mul,
2404 .mulwrap => .mulwrap,2448 .mulwrap => .mulwrap,
2405 else => return sema.mod.fail(&block.base, inst.base.src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}),2449 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}),
2406 };2450 };
24072451
2408 return mod.addBinOp(b, inst.base.src, scalar_type, ir_tag, casted_lhs, casted_rhs);2452 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);
2409}2453}
24102454
2411/// Analyzes operands that are known at comptime2455/// Analyzes operands that are known at comptime
2412fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst: zir.Inst.Index, lhs_val: Value, rhs_val: Value) InnerError!*Inst {2456fn analyzeInstComptimeOp(
2457 sema: *Sema,
2458 block: *Scope.Block,
2459 res_type: Type,
2460 inst: zir.Inst.Index,
2461 lhs_val: Value,
2462 rhs_val: Value,
2463) InnerError!*Inst {
2464 if (true) @panic("TODO rework analyzeInstComptimeOp for zir-memory-layout");
2465
2413 // incase rhs is 0, simply return lhs without doing any calculations2466 // incase rhs is 0, simply return lhs without doing any calculations
2414 // TODO Once division is implemented we should throw an error when dividing by 0.2467 // TODO Once division is implemented we should throw an error when dividing by 0.
2415 if (rhs_val.compareWithZero(.eq)) {2468 if (rhs_val.compareWithZero(.eq)) {
2416 return sema.mod.constInst(scope, inst.base.src, .{2469 return sema.mod.constInst(sema.arena, inst.base.src, .{
2417 .ty = res_type,2470 .ty = res_type,
2418 .val = lhs_val,2471 .val = lhs_val,
2419 });2472 });
...@@ -2425,14 +2478,14 @@ fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst:...@@ -2425,14 +2478,14 @@ fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst:
2425 const val = if (is_int)2478 const val = if (is_int)
2426 try Module.intAdd(sema.arena, lhs_val, rhs_val)2479 try Module.intAdd(sema.arena, lhs_val, rhs_val)
2427 else2480 else
2428 try mod.floatAdd(scope, res_type, inst.base.src, lhs_val, rhs_val);2481 try Module.floatAdd(sema.arena, res_type, inst.base.src, lhs_val, rhs_val);
2429 break :blk val;2482 break :blk val;
2430 },2483 },
2431 .sub => blk: {2484 .sub => blk: {
2432 const val = if (is_int)2485 const val = if (is_int)
2433 try Module.intSub(sema.arena, lhs_val, rhs_val)2486 try Module.intSub(sema.arena, lhs_val, rhs_val)
2434 else2487 else
2435 try mod.floatSub(scope, res_type, inst.base.src, lhs_val, rhs_val);2488 try Module.floatSub(sema.arena, res_type, inst.base.src, lhs_val, rhs_val);
2436 break :blk val;2489 break :blk val;
2437 },2490 },
2438 else => return sema.mod.fail(&block.base, inst.base.src, "TODO Implement arithmetic operand '{s}'", .{@tagName(inst.base.tag)}),2491 else => return sema.mod.fail(&block.base, inst.base.src, "TODO Implement arithmetic operand '{s}'", .{@tagName(inst.base.tag)}),
...@@ -2440,27 +2493,27 @@ fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst:...@@ -2440,27 +2493,27 @@ fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst:
24402493
2441 log.debug("{s}({}, {}) result: {}", .{ @tagName(inst.base.tag), lhs_val, rhs_val, value });2494 log.debug("{s}({}, {}) result: {}", .{ @tagName(inst.base.tag), lhs_val, rhs_val, value });
24422495
2443 return sema.mod.constInst(scope, inst.base.src, .{2496 return sema.mod.constInst(sema.arena, inst.base.src, .{
2444 .ty = res_type,2497 .ty = res_type,
2445 .val = value,2498 .val = value,
2446 });2499 });
2447}2500}
24482501
2449fn zirDerefNode(sema: *Sema, block: *Scope.Block, deref: zir.Inst.Index) InnerError!*Inst {2502fn zirDerefNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2450 const tracy = trace(@src());2503 const tracy = trace(@src());
2451 defer tracy.end();2504 defer tracy.end();
24522505
2453 const inst_data = sema.code.instructions.items(.data)[inst].un_node;2506 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2454 const src = inst_data.src();2507 const src = inst_data.src();
2455 const ptr_src: LazySrcLoc = .{ .node_offset_deref_ptr = inst_data.src_node };2508 const ptr_src: LazySrcLoc = .{ .node_offset_deref_ptr = inst_data.src_node };
2456 const ptr = sema.resolveInst(block, inst_data.operand);2509 const ptr = try sema.resolveInst(inst_data.operand);
2457 return sema.analyzeDeref(block, src, ptr, ptr_src);2510 return sema.analyzeDeref(block, src, ptr, ptr_src);
2458}2511}
24592512
2460fn zirAsm(2513fn zirAsm(
2461 sema: *Sema,2514 sema: *Sema,
2462 block: *Scope.Block,2515 block: *Scope.Block,
2463 assembly: zir.Inst.Index,2516 inst: zir.Inst.Index,
2464 is_volatile: bool,2517 is_volatile: bool,
2465) InnerError!*Inst {2518) InnerError!*Inst {
2466 const tracy = trace(@src());2519 const tracy = trace(@src());
...@@ -2475,23 +2528,24 @@ fn zirAsm(...@@ -2475,23 +2528,24 @@ fn zirAsm(
2475 const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);2528 const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);
24762529
2477 var extra_i = extra.end;2530 var extra_i = extra.end;
2478 const output = if (extra.data.output != 0) blk: {2531 const Output = struct { name: []const u8, inst: *Inst };
2532 const output: ?Output = if (extra.data.output != 0) blk: {
2479 const name = sema.code.nullTerminatedString(sema.code.extra[extra_i]);2533 const name = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
2480 extra_i += 1;2534 extra_i += 1;
2481 break :blk .{2535 break :blk Output{
2482 .name = name,2536 .name = name,
2483 .inst = try sema.resolveInst(block, extra.data.output),2537 .inst = try sema.resolveInst(extra.data.output),
2484 };2538 };
2485 } else null;2539 } else null;
24862540
2487 const args = try sema.arena.alloc(*Inst, extra.data.args.len);2541 const args = try sema.arena.alloc(*Inst, extra.data.args_len);
2488 const inputs = try sema.arena.alloc([]const u8, extra.data.args_len);2542 const inputs = try sema.arena.alloc([]const u8, extra.data.args_len);
2489 const clobbers = try sema.arena.alloc([]const u8, extra.data.clobbers_len);2543 const clobbers = try sema.arena.alloc([]const u8, extra.data.clobbers_len);
24902544
2491 for (args) |*arg| {2545 for (args) |*arg| {
2492 const uncasted = sema.resolveInst(block, sema.code.extra[extra_i]);2546 const uncasted = try sema.resolveInst(sema.code.extra[extra_i]);
2493 extra_i += 1;2547 extra_i += 1;
2494 arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted);2548 arg.* = try sema.coerce(block, Type.initTag(.usize), uncasted, uncasted.src);
2495 }2549 }
2496 for (inputs) |*name| {2550 for (inputs) |*name| {
2497 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);2551 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
...@@ -2503,8 +2557,8 @@ fn zirAsm(...@@ -2503,8 +2557,8 @@ fn zirAsm(
2503 }2557 }
25042558
2505 try sema.requireRuntimeBlock(block, src);2559 try sema.requireRuntimeBlock(block, src);
2506 const inst = try sema.arena.create(Inst.Assembly);2560 const asm_tzir = try sema.arena.create(Inst.Assembly);
2507 inst.* = .{2561 asm_tzir.* = .{
2508 .base = .{2562 .base = .{
2509 .tag = .assembly,2563 .tag = .assembly,
2510 .ty = return_type,2564 .ty = return_type,
...@@ -2518,8 +2572,8 @@ fn zirAsm(...@@ -2518,8 +2572,8 @@ fn zirAsm(
2518 .clobbers = clobbers,2572 .clobbers = clobbers,
2519 .args = args,2573 .args = args,
2520 };2574 };
2521 try block.instructions.append(mod.gpa, &inst.base);2575 try block.instructions.append(sema.gpa, &asm_tzir.base);
2522 return &inst.base;2576 return &asm_tzir.base;
2523}2577}
25242578
2525fn zirCmp(2579fn zirCmp(
...@@ -2531,9 +2585,10 @@ fn zirCmp(...@@ -2531,9 +2585,10 @@ fn zirCmp(
2531 const tracy = trace(@src());2585 const tracy = trace(@src());
2532 defer tracy.end();2586 defer tracy.end();
25332587
2588 const src: LazySrcLoc = .todo;
2534 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2589 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2535 const lhs = sema.resolveInst(bin_inst.lhs);2590 const lhs = try sema.resolveInst(bin_inst.lhs);
2536 const rhs = sema.resolveInst(bin_inst.rhs);2591 const rhs = try sema.resolveInst(bin_inst.rhs);
25372592
2538 const is_equality_cmp = switch (op) {2593 const is_equality_cmp = switch (op) {
2539 .eq, .neq => true,2594 .eq, .neq => true,
...@@ -2543,50 +2598,50 @@ fn zirCmp(...@@ -2543,50 +2598,50 @@ fn zirCmp(
2543 const rhs_ty_tag = rhs.ty.zigTypeTag();2598 const rhs_ty_tag = rhs.ty.zigTypeTag();
2544 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {2599 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
2545 // null == null, null != null2600 // null == null, null != null
2546 return mod.constBool(sema.arena, inst.base.src, op == .eq);2601 return sema.mod.constBool(sema.arena, src, op == .eq);
2547 } else if (is_equality_cmp and2602 } else if (is_equality_cmp and
2548 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or2603 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or
2549 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))2604 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))
2550 {2605 {
2551 // comparing null with optionals2606 // comparing null with optionals
2552 const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs;2607 const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs;
2553 return sema.analyzeIsNull(block, inst.base.src, opt_operand, op == .neq);2608 return sema.analyzeIsNull(block, src, opt_operand, op == .neq);
2554 } else if (is_equality_cmp and2609 } else if (is_equality_cmp and
2555 ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr())))2610 ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr())))
2556 {2611 {
2557 return sema.mod.fail(&block.base, inst.base.src, "TODO implement C pointer cmp", .{});2612 return sema.mod.fail(&block.base, src, "TODO implement C pointer cmp", .{});
2558 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {2613 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
2559 const non_null_type = if (lhs_ty_tag == .Null) rhs.ty else lhs.ty;2614 const non_null_type = if (lhs_ty_tag == .Null) rhs.ty else lhs.ty;
2560 return sema.mod.fail(&block.base, inst.base.src, "comparison of '{}' with null", .{non_null_type});2615 return sema.mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type});
2561 } else if (is_equality_cmp and2616 } else if (is_equality_cmp and
2562 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or2617 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or
2563 (rhs_ty_tag == .EnumLiteral and lhs_ty_tag == .Union)))2618 (rhs_ty_tag == .EnumLiteral and lhs_ty_tag == .Union)))
2564 {2619 {
2565 return sema.mod.fail(&block.base, inst.base.src, "TODO implement equality comparison between a union's tag value and an enum literal", .{});2620 return sema.mod.fail(&block.base, src, "TODO implement equality comparison between a union's tag value and an enum literal", .{});
2566 } else if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {2621 } else if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {
2567 if (!is_equality_cmp) {2622 if (!is_equality_cmp) {
2568 return sema.mod.fail(&block.base, inst.base.src, "{s} operator not allowed for errors", .{@tagName(op)});2623 return sema.mod.fail(&block.base, src, "{s} operator not allowed for errors", .{@tagName(op)});
2569 }2624 }
2570 if (rhs.value()) |rval| {2625 if (rhs.value()) |rval| {
2571 if (lhs.value()) |lval| {2626 if (lhs.value()) |lval| {
2572 // TODO optimisation oppurtunity: evaluate if std.mem.eql is faster with the names, or calling to Module.getErrorValue to get the values and then compare them is faster2627 // TODO optimisation oppurtunity: evaluate if std.mem.eql is faster with the names, or calling to Module.getErrorValue to get the values and then compare them is faster
2573 return mod.constBool(sema.arena, inst.base.src, std.mem.eql(u8, lval.castTag(.@"error").?.data.name, rval.castTag(.@"error").?.data.name) == (op == .eq));2628 return sema.mod.constBool(sema.arena, src, std.mem.eql(u8, lval.castTag(.@"error").?.data.name, rval.castTag(.@"error").?.data.name) == (op == .eq));
2574 }2629 }
2575 }2630 }
2576 try sema.requireRuntimeBlock(block, inst.base.src);2631 try sema.requireRuntimeBlock(block, src);
2577 return mod.addBinOp(b, inst.base.src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);2632 return block.addBinOp(src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);
2578 } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) {2633 } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) {
2579 // This operation allows any combination of integer and float types, regardless of the2634 // This operation allows any combination of integer and float types, regardless of the
2580 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for2635 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
2581 // numeric types.2636 // numeric types.
2582 return mod.cmpNumeric(scope, inst.base.src, lhs, rhs, op);2637 return sema.cmpNumeric(block, src, lhs, rhs, op);
2583 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {2638 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
2584 if (!is_equality_cmp) {2639 if (!is_equality_cmp) {
2585 return sema.mod.fail(&block.base, inst.base.src, "{s} operator not allowed for types", .{@tagName(op)});2640 return sema.mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)});
2586 }2641 }
2587 return mod.constBool(sema.arena, inst.base.src, lhs.value().?.eql(rhs.value().?) == (op == .eq));2642 return sema.mod.constBool(sema.arena, src, lhs.value().?.eql(rhs.value().?) == (op == .eq));
2588 }2643 }
2589 return sema.mod.fail(&block.base, inst.base.src, "TODO implement more cmp analysis", .{});2644 return sema.mod.fail(&block.base, src, "TODO implement more cmp analysis", .{});
2590}2645}
25912646
2592fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2647fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -2594,7 +2649,7 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!...@@ -2594,7 +2649,7 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!
2594 defer tracy.end();2649 defer tracy.end();
25952650
2596 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2651 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2597 const operand = sema.resolveInst(block, inst_data.operand);2652 const operand = try sema.resolveInst(inst_data.operand);
2598 return sema.mod.constType(sema.arena, inst_data.src(), operand.ty);2653 return sema.mod.constType(sema.arena, inst_data.src(), operand.ty);
2599}2654}
26002655
...@@ -2606,18 +2661,14 @@ fn zirTypeofPeer(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr...@@ -2606,18 +2661,14 @@ fn zirTypeofPeer(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
2606 const src = inst_data.src();2661 const src = inst_data.src();
2607 const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index);2662 const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index);
26082663
2609 const inst_list = try mod.gpa.alloc(*ir.Inst, extra.data.operands_len);2664 const inst_list = try sema.gpa.alloc(*ir.Inst, extra.data.operands_len);
2610 defer mod.gpa.free(inst_list);2665 defer sema.gpa.free(inst_list);
2611
2612 const src_list = try mod.gpa.alloc(LazySrcLoc, extra.data.operands_len);
2613 defer mod.gpa.free(src_list);
26142666
2615 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {2667 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {
2616 inst_list[i] = sema.resolveInst(block, arg_ref);2668 inst_list[i] = try sema.resolveInst(arg_ref);
2617 src_list[i] = .{ .node_offset_builtin_call_argn = inst_data.src_node };
2618 }2669 }
26192670
2620 const result_type = try sema.resolvePeerTypes(block, inst_list, src_list);2671 const result_type = try sema.resolvePeerTypes(block, inst_list);
2621 return sema.mod.constType(sema.arena, src, result_type);2672 return sema.mod.constType(sema.arena, src, result_type);
2622}2673}
26232674
...@@ -2627,12 +2678,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2627,12 +2678,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
26272678
2628 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2679 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2629 const src = inst_data.src();2680 const src = inst_data.src();
2630 const uncasted_operand = sema.resolveInst(block, inst_data.operand);2681 const uncasted_operand = try sema.resolveInst(inst_data.operand);
26312682
2632 const bool_type = Type.initTag(.bool);2683 const bool_type = Type.initTag(.bool);
2633 const operand = try sema.coerce(scope, bool_type, uncasted_operand);2684 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);
2634 if (try mod.resolveDefinedValue(scope, operand)) |val| {2685 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
2635 return mod.constBool(sema.arena, src, !val.toBool());2686 return sema.mod.constBool(sema.arena, src, !val.toBool());
2636 }2687 }
2637 try sema.requireRuntimeBlock(block, src);2688 try sema.requireRuntimeBlock(block, src);
2638 return block.addUnOp(src, bool_type, .not, operand);2689 return block.addUnOp(src, bool_type, .not, operand);
...@@ -2647,25 +2698,26 @@ fn zirBoolOp(...@@ -2647,25 +2698,26 @@ fn zirBoolOp(
2647 const tracy = trace(@src());2698 const tracy = trace(@src());
2648 defer tracy.end();2699 defer tracy.end();
26492700
2701 const src: LazySrcLoc = .unneeded;
2650 const bool_type = Type.initTag(.bool);2702 const bool_type = Type.initTag(.bool);
2651 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2703 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2652 const uncasted_lhs = sema.resolveInst(bin_inst.lhs);2704 const uncasted_lhs = try sema.resolveInst(bin_inst.lhs);
2653 const lhs = try sema.coerce(scope, bool_type, uncasted_lhs);2705 const lhs = try sema.coerce(block, bool_type, uncasted_lhs, uncasted_lhs.src);
2654 const uncasted_rhs = sema.resolveInst(bin_inst.rhs);2706 const uncasted_rhs = try sema.resolveInst(bin_inst.rhs);
2655 const rhs = try sema.coerce(scope, bool_type, uncasted_rhs);2707 const rhs = try sema.coerce(block, bool_type, uncasted_rhs, uncasted_rhs.src);
26562708
2657 if (lhs.value()) |lhs_val| {2709 if (lhs.value()) |lhs_val| {
2658 if (rhs.value()) |rhs_val| {2710 if (rhs.value()) |rhs_val| {
2659 if (is_bool_or) {2711 if (is_bool_or) {
2660 return mod.constBool(sema.arena, inst.base.src, lhs_val.toBool() or rhs_val.toBool());2712 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() or rhs_val.toBool());
2661 } else {2713 } else {
2662 return mod.constBool(sema.arena, inst.base.src, lhs_val.toBool() and rhs_val.toBool());2714 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() and rhs_val.toBool());
2663 }2715 }
2664 }2716 }
2665 }2717 }
2666 try sema.requireRuntimeBlock(block, inst.base.src);2718 try sema.requireRuntimeBlock(block, src);
2667 const tag: ir.Inst.Tag = if (is_bool_or) .bool_or else .bool_and;2719 const tag: ir.Inst.Tag = if (is_bool_or) .bool_or else .bool_and;
2668 return mod.addBinOp(b, inst.base.src, bool_type, tag, lhs, rhs);2720 return block.addBinOp(src, bool_type, tag, lhs, rhs);
2669}2721}
26702722
2671fn zirIsNull(2723fn zirIsNull(
...@@ -2679,7 +2731,7 @@ fn zirIsNull(...@@ -2679,7 +2731,7 @@ fn zirIsNull(
26792731
2680 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2732 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2681 const src = inst_data.src();2733 const src = inst_data.src();
2682 const operand = sema.resolveInst(block, inst_data.operand);2734 const operand = try sema.resolveInst(inst_data.operand);
2683 return sema.analyzeIsNull(block, src, operand, invert_logic);2735 return sema.analyzeIsNull(block, src, operand, invert_logic);
2684}2736}
26852737
...@@ -2694,7 +2746,7 @@ fn zirIsNullPtr(...@@ -2694,7 +2746,7 @@ fn zirIsNullPtr(
26942746
2695 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2747 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2696 const src = inst_data.src();2748 const src = inst_data.src();
2697 const ptr = sema.resolveInst(block, inst_data.operand);2749 const ptr = try sema.resolveInst(inst_data.operand);
2698 const loaded = try sema.analyzeDeref(block, src, ptr, src);2750 const loaded = try sema.analyzeDeref(block, src, ptr, src);
2699 return sema.analyzeIsNull(block, src, loaded, invert_logic);2751 return sema.analyzeIsNull(block, src, loaded, invert_logic);
2700}2752}
...@@ -2704,8 +2756,8 @@ fn zirIsErr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*...@@ -2704,8 +2756,8 @@ fn zirIsErr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
2704 defer tracy.end();2756 defer tracy.end();
27052757
2706 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2758 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2707 const operand = sema.resolveInst(block, inst_data.operand);2759 const operand = try sema.resolveInst(inst_data.operand);
2708 return mod.analyzeIsErr(scope, inst_data.src(), operand);2760 return sema.analyzeIsErr(block, inst_data.src(), operand);
2709}2761}
27102762
2711fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2763fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -2714,83 +2766,111 @@ fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro...@@ -2714,83 +2766,111 @@ fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
27142766
2715 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;2767 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2716 const src = inst_data.src();2768 const src = inst_data.src();
2717 const ptr = sema.resolveInst(block, inst_data.operand);2769 const ptr = try sema.resolveInst(inst_data.operand);
2718 const loaded = try sema.analyzeDeref(block, src, ptr, src);2770 const loaded = try sema.analyzeDeref(block, src, ptr, src);
2719 return mod.analyzeIsErr(scope, src, loaded);2771 return sema.analyzeIsErr(block, src, loaded);
2720}2772}
27212773
2722fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2774fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2723 const tracy = trace(@src());2775 const tracy = trace(@src());
2724 defer tracy.end();2776 defer tracy.end();
27252777
2726 const uncasted_cond = sema.resolveInst(block, inst.positionals.condition);2778 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2727 const cond = try sema.coerce(scope, Type.initTag(.bool), uncasted_cond);2779 const src = inst_data.src();
2780 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
2781 const extra = sema.code.extraData(zir.Inst.CondBr, inst_data.payload_index);
2782
2783 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
2784 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
27282785
2729 if (try mod.resolveDefinedValue(scope, cond)) |cond_val| {2786 const uncasted_cond = try sema.resolveInst(extra.data.condition);
2730 const body = if (cond_val.toBool()) &inst.positionals.then_body else &inst.positionals.else_body;2787 const cond = try sema.coerce(parent_block, Type.initTag(.bool), uncasted_cond, cond_src);
2731 try sema.analyzeBody(parent_block, body.*);2788
2732 return mod.constNoReturn(scope, inst.base.src);2789 if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {
2790 const body = if (cond_val.toBool()) then_body else else_body;
2791 try sema.analyzeBody(parent_block, body);
2792 return sema.mod.constNoReturn(sema.arena, src);
2733 }2793 }
27342794
2735 var true_block: Scope.Block = .{2795 var true_block: Scope.Block = .{
2736 .parent = parent_block,2796 .parent = parent_block,
2737 .inst_table = parent_block.inst_table,2797 .sema = sema,
2738 .func = parent_block.func,
2739 .owner_decl = parent_block.owner_decl,
2740 .src_decl = parent_block.src_decl,2798 .src_decl = parent_block.src_decl,
2741 .instructions = .{},2799 .instructions = .{},
2742 .arena = sema.arena,
2743 .inlining = parent_block.inlining,2800 .inlining = parent_block.inlining,
2744 .is_comptime = parent_block.is_comptime,2801 .is_comptime = parent_block.is_comptime,
2745 .branch_quota = parent_block.branch_quota,
2746 };2802 };
2747 defer true_block.instructions.deinit(mod.gpa);2803 defer true_block.instructions.deinit(sema.gpa);
2748 try sema.analyzeBody(&true_block, inst.positionals.then_body);2804 try sema.analyzeBody(&true_block, then_body);
27492805
2750 var false_block: Scope.Block = .{2806 var false_block: Scope.Block = .{
2751 .parent = parent_block,2807 .parent = parent_block,
2752 .inst_table = parent_block.inst_table,2808 .sema = sema,
2753 .func = parent_block.func,
2754 .owner_decl = parent_block.owner_decl,
2755 .src_decl = parent_block.src_decl,2809 .src_decl = parent_block.src_decl,
2756 .instructions = .{},2810 .instructions = .{},
2757 .arena = sema.arena,
2758 .inlining = parent_block.inlining,2811 .inlining = parent_block.inlining,
2759 .is_comptime = parent_block.is_comptime,2812 .is_comptime = parent_block.is_comptime,
2760 .branch_quota = parent_block.branch_quota,
2761 };2813 };
2762 defer false_block.instructions.deinit(mod.gpa);2814 defer false_block.instructions.deinit(sema.gpa);
2763 try sema.analyzeBody(&false_block, inst.positionals.else_body);2815 try sema.analyzeBody(&false_block, else_body);
27642816
2765 const then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, true_block.instructions.items) };2817 const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, true_block.instructions.items) };
2766 const else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, false_block.instructions.items) };2818 const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, false_block.instructions.items) };
2767 return mod.addCondBr(parent_block, inst.base.src, cond, then_body, else_body);2819 return parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body);
2768}2820}
27692821
2770fn zirUnreachable(2822fn zirUnreachable(
2771 sema: *Sema,2823 sema: *Sema,
2772 block: *Scope.Block,2824 block: *Scope.Block,
2773 zir_index: zir.Inst.Index,2825 inst: zir.Inst.Index,
2774 safety_check: bool,2826 safety_check: bool,
2775) InnerError!*Inst {2827) InnerError!*Inst {
2776 const tracy = trace(@src());2828 const tracy = trace(@src());
2777 defer tracy.end();2829 defer tracy.end();
27782830
2779 try sema.requireRuntimeBlock(block, zir_index.base.src);2831 const src_node = sema.code.instructions.items(.data)[inst].node;
2832 const src: LazySrcLoc = .{ .node_offset = src_node };
2833 try sema.requireRuntimeBlock(block, src);
2780 // TODO Add compile error for @optimizeFor occurring too late in a scope.2834 // TODO Add compile error for @optimizeFor occurring too late in a scope.
2781 if (safety_check and block.wantSafety()) {2835 if (safety_check and block.wantSafety()) {
2782 return mod.safetyPanic(b, zir_index.base.src, .unreach);2836 return sema.safetyPanic(block, src, .unreach);
2783 } else {2837 } else {
2784 return block.addNoOp(zir_index.base.src, Type.initTag(.noreturn), .unreach);2838 return block.addNoOp(src, Type.initTag(.noreturn), .unreach);
2785 }2839 }
2786}2840}
27872841
2788fn zirRetTok(sema: *Sema, block: *Scope.Block, zir_inst: zir.Inst.Index) InnerError!*Inst {2842fn zirRetTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2789 @compileError("TODO");2843 const tracy = trace(@src());
2844 defer tracy.end();
2845
2846 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2847 const operand = try sema.resolveInst(inst_data.operand);
2848 const src = inst_data.src();
2849
2850 return sema.analyzeRet(block, operand, src);
2851}
2852
2853fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
2854 const tracy = trace(@src());
2855 defer tracy.end();
2856
2857 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2858 const operand = try sema.resolveInst(inst_data.operand);
2859 const src = inst_data.src();
2860
2861 return sema.analyzeRet(block, operand, src);
2790}2862}
27912863
2792fn zirRetNode(sema: *Sema, block: *Scope.Block, zir_inst: zir.Inst.Index) InnerError!*Inst {2864fn analyzeRet(sema: *Sema, block: *Scope.Block, operand: *Inst, src: LazySrcLoc) InnerError!*Inst {
2793 @compileError("TODO");2865 if (block.inlining) |inlining| {
2866 // We are inlining a function call; rewrite the `ret` as a `break`.
2867 try inlining.merges.results.append(sema.gpa, operand);
2868 const br = try block.addBr(src, inlining.merges.block_inst, operand);
2869 return &br.base;
2870 }
2871
2872 try sema.requireFunctionBlock(block, src);
2873 return block.addUnOp(src, Type.initTag(.noreturn), .ret, operand);
2794}2874}
27952875
2796fn floatOpAllowed(tag: zir.Inst.Tag) bool {2876fn floatOpAllowed(tag: zir.Inst.Tag) bool {
...@@ -2826,6 +2906,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2826,6 +2906,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2826 const tracy = trace(@src());2906 const tracy = trace(@src());
2827 defer tracy.end();2907 defer tracy.end();
28282908
2909 const src: LazySrcLoc = .unneeded;
2829 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;2910 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
2830 const extra = sema.code.extraData(zir.Inst.PtrType, inst_data.payload_index);2911 const extra = sema.code.extraData(zir.Inst.PtrType, inst_data.payload_index);
28312912
...@@ -2855,13 +2936,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2855,13 +2936,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2855 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);2936 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);
2856 } else 0;2937 } else 0;
28572938
2858 if (bit_end != 0 and bit_offset >= bit_end * 8)2939 if (bit_end != 0 and bit_start >= bit_end * 8)
2859 return sema.mod.fail(&block.base, inst.base.src, "bit offset starts after end of host integer", .{});2940 return sema.mod.fail(&block.base, src, "bit offset starts after end of host integer", .{});
28602941
2861 const elem_type = try sema.resolveType(block, extra.data.elem_type);2942 const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type);
28622943
2863 const ty = try mod.ptrType(2944 const ty = try sema.mod.ptrType(
2864 scope,2945 sema.arena,
2865 elem_type,2946 elem_type,
2866 sentinel,2947 sentinel,
2867 abi_align,2948 abi_align,
...@@ -2872,7 +2953,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2872,7 +2953,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2872 inst_data.flags.is_volatile,2953 inst_data.flags.is_volatile,
2873 inst_data.size,2954 inst_data.size,
2874 );2955 );
2875 return sema.mod.constType(sema.arena, .unneeded, ty);2956 return sema.mod.constType(sema.arena, src, ty);
2876}2957}
28772958
2878fn zirAwait(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {2959fn zirAwait(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -2892,7 +2973,7 @@ fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void...@@ -2892,7 +2973,7 @@ fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void
2892}2973}
28932974
2894fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {2975fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
2895 try sema.requireFunctionBlock(scope, src);2976 try sema.requireFunctionBlock(block, src);
2896 if (block.is_comptime) {2977 if (block.is_comptime) {
2897 return sema.mod.fail(&block.base, src, "unable to resolve comptime value", .{});2978 return sema.mod.fail(&block.base, src, "unable to resolve comptime value", .{});
2898 }2979 }
...@@ -2900,7 +2981,7 @@ fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void...@@ -2900,7 +2981,7 @@ fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void
29002981
2901fn validateVarType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {2982fn validateVarType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {
2902 if (!ty.isValidVarType(false)) {2983 if (!ty.isValidVarType(false)) {
2903 return mod.fail(&block.base, src, "variable of type '{}' must be const or comptime", .{ty});2984 return sema.mod.fail(&block.base, src, "variable of type '{}' must be const or comptime", .{ty});
2904 }2985 }
2905}2986}
29062987
...@@ -2939,20 +3020,16 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id:...@@ -2939,20 +3020,16 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id:
29393020
2940 var fail_block: Scope.Block = .{3021 var fail_block: Scope.Block = .{
2941 .parent = parent_block,3022 .parent = parent_block,
2942 .inst_map = parent_block.inst_map,3023 .sema = sema,
2943 .func = parent_block.func,
2944 .owner_decl = parent_block.owner_decl,
2945 .src_decl = parent_block.src_decl,3024 .src_decl = parent_block.src_decl,
2946 .instructions = .{},3025 .instructions = .{},
2947 .arena = sema.arena,
2948 .inlining = parent_block.inlining,3026 .inlining = parent_block.inlining,
2949 .is_comptime = parent_block.is_comptime,3027 .is_comptime = parent_block.is_comptime,
2950 .branch_quota = parent_block.branch_quota,
2951 };3028 };
29523029
2953 defer fail_block.instructions.deinit(mod.gpa);3030 defer fail_block.instructions.deinit(sema.gpa);
29543031
2955 _ = try mod.safetyPanic(&fail_block, ok.src, panic_id);3032 _ = try sema.safetyPanic(&fail_block, ok.src, panic_id);
29563033
2957 const fail_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, fail_block.instructions.items) };3034 const fail_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, fail_block.instructions.items) };
29583035
...@@ -2969,13 +3046,13 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id:...@@ -2969,13 +3046,13 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id:
2969 };3046 };
2970 block_inst.body.instructions[0] = &condbr.base;3047 block_inst.body.instructions[0] = &condbr.base;
29713048
2972 try parent_block.instructions.append(mod.gpa, &block_inst.base);3049 try parent_block.instructions.append(sema.gpa, &block_inst.base);
2973}3050}
29743051
2975fn safetyPanic(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, panic_id: PanicId) !*Inst {3052fn safetyPanic(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, panic_id: PanicId) !*Inst {
2976 // TODO Once we have a panic function to call, call it here instead of breakpoint.3053 // TODO Once we have a panic function to call, call it here instead of breakpoint.
2977 _ = try mod.addNoOp(block, src, Type.initTag(.void), .breakpoint);3054 _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
2978 return mod.addNoOp(block, src, Type.initTag(.noreturn), .unreach);3055 return block.addNoOp(src, Type.initTag(.noreturn), .unreach);
2979}3056}
29803057
2981fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {3058fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
...@@ -3002,16 +3079,16 @@ fn namedFieldPtr(...@@ -3002,16 +3079,16 @@ fn namedFieldPtr(
3002 switch (elem_ty.zigTypeTag()) {3079 switch (elem_ty.zigTypeTag()) {
3003 .Array => {3080 .Array => {
3004 if (mem.eql(u8, field_name, "len")) {3081 if (mem.eql(u8, field_name, "len")) {
3005 return mod.constInst(scope, src, .{3082 return sema.mod.constInst(sema.arena, src, .{
3006 .ty = Type.initTag(.single_const_pointer_to_comptime_int),3083 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
3007 .val = try Value.Tag.ref_val.create(3084 .val = try Value.Tag.ref_val.create(
3008 scope.arena(),3085 sema.arena,
3009 try Value.Tag.int_u64.create(scope.arena(), elem_ty.arrayLen()),3086 try Value.Tag.int_u64.create(sema.arena, elem_ty.arrayLen()),
3010 ),3087 ),
3011 });3088 });
3012 } else {3089 } else {
3013 return mod.fail(3090 return sema.mod.fail(
3014 scope,3091 &block.base,
3015 field_name_src,3092 field_name_src,
3016 "no member named '{s}' in '{}'",3093 "no member named '{s}' in '{}'",
3017 .{ field_name, elem_ty },3094 .{ field_name, elem_ty },
...@@ -3023,16 +3100,16 @@ fn namedFieldPtr(...@@ -3023,16 +3100,16 @@ fn namedFieldPtr(
3023 switch (ptr_child.zigTypeTag()) {3100 switch (ptr_child.zigTypeTag()) {
3024 .Array => {3101 .Array => {
3025 if (mem.eql(u8, field_name, "len")) {3102 if (mem.eql(u8, field_name, "len")) {
3026 return mod.constInst(scope, src, .{3103 return sema.mod.constInst(sema.arena, src, .{
3027 .ty = Type.initTag(.single_const_pointer_to_comptime_int),3104 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
3028 .val = try Value.Tag.ref_val.create(3105 .val = try Value.Tag.ref_val.create(
3029 scope.arena(),3106 sema.arena,
3030 try Value.Tag.int_u64.create(scope.arena(), ptr_child.arrayLen()),3107 try Value.Tag.int_u64.create(sema.arena, ptr_child.arrayLen()),
3031 ),3108 ),
3032 });3109 });
3033 } else {3110 } else {
3034 return mod.fail(3111 return sema.mod.fail(
3035 scope,3112 &block.base,
3036 field_name_src,3113 field_name_src,
3037 "no member named '{s}' in '{}'",3114 "no member named '{s}' in '{}'",
3038 .{ field_name, elem_ty },3115 .{ field_name, elem_ty },
...@@ -3043,10 +3120,10 @@ fn namedFieldPtr(...@@ -3043,10 +3120,10 @@ fn namedFieldPtr(
3043 }3120 }
3044 },3121 },
3045 .Type => {3122 .Type => {
3046 _ = try sema.resolveConstValue(scope, object_ptr.src, object_ptr);3123 _ = try sema.resolveConstValue(block, object_ptr.src, object_ptr);
3047 const result = try sema.analyzeDeref(block, src, object_ptr, object_ptr.src);3124 const result = try sema.analyzeDeref(block, src, object_ptr, object_ptr.src);
3048 const val = result.value().?;3125 const val = result.value().?;
3049 const child_type = try val.toType(scope.arena());3126 const child_type = try val.toType(sema.arena);
3050 switch (child_type.zigTypeTag()) {3127 switch (child_type.zigTypeTag()) {
3051 .ErrorSet => {3128 .ErrorSet => {
3052 var name: []const u8 = undefined;3129 var name: []const u8 = undefined;
...@@ -3054,18 +3131,18 @@ fn namedFieldPtr(...@@ -3054,18 +3131,18 @@ fn namedFieldPtr(
3054 if (val.castTag(.error_set)) |payload|3131 if (val.castTag(.error_set)) |payload|
3055 name = (payload.data.fields.getEntry(field_name) orelse return sema.mod.fail(&block.base, src, "no error named '{s}' in '{}'", .{ field_name, child_type })).key3132 name = (payload.data.fields.getEntry(field_name) orelse return sema.mod.fail(&block.base, src, "no error named '{s}' in '{}'", .{ field_name, child_type })).key
3056 else3133 else
3057 name = (try mod.getErrorValue(field_name)).key;3134 name = (try sema.mod.getErrorValue(field_name)).key;
30583135
3059 const result_type = if (child_type.tag() == .anyerror)3136 const result_type = if (child_type.tag() == .anyerror)
3060 try Type.Tag.error_set_single.create(scope.arena(), name)3137 try Type.Tag.error_set_single.create(sema.arena, name)
3061 else3138 else
3062 child_type;3139 child_type;
30633140
3064 return mod.constInst(scope, src, .{3141 return sema.mod.constInst(sema.arena, src, .{
3065 .ty = try mod.simplePtrType(scope.arena(), result_type, false, .One),3142 .ty = try sema.mod.simplePtrType(sema.arena, result_type, false, .One),
3066 .val = try Value.Tag.ref_val.create(3143 .val = try Value.Tag.ref_val.create(
3067 scope.arena(),3144 sema.arena,
3068 try Value.Tag.@"error".create(scope.arena(), .{3145 try Value.Tag.@"error".create(sema.arena, .{
3069 .name = name,3146 .name = name,
3070 }),3147 }),
3071 ),3148 ),
...@@ -3073,12 +3150,12 @@ fn namedFieldPtr(...@@ -3073,12 +3150,12 @@ fn namedFieldPtr(
3073 },3150 },
3074 .Struct => {3151 .Struct => {
3075 const container_scope = child_type.getContainerScope();3152 const container_scope = child_type.getContainerScope();
3076 if (mod.lookupDeclName(&container_scope.base, field_name)) |decl| {3153 if (sema.mod.lookupDeclName(&container_scope.base, field_name)) |decl| {
3077 // TODO if !decl.is_pub and inDifferentFiles() "{} is private"3154 // TODO if !decl.is_pub and inDifferentFiles() "{} is private"
3078 return sema.analyzeDeclRef(block, src, decl);3155 return sema.analyzeDeclRef(block, src, decl);
3079 }3156 }
30803157
3081 if (container_scope.file_scope == mod.root_scope) {3158 if (container_scope.file_scope == sema.mod.root_scope) {
3082 return sema.mod.fail(&block.base, src, "root source file has no member called '{s}'", .{field_name});3159 return sema.mod.fail(&block.base, src, "root source file has no member called '{s}'", .{field_name});
3083 } else {3160 } else {
3084 return sema.mod.fail(&block.base, src, "container '{}' has no member called '{s}'", .{ child_type, field_name });3161 return sema.mod.fail(&block.base, src, "container '{}' has no member called '{s}'", .{ child_type, field_name });
...@@ -3117,11 +3194,11 @@ fn elemPtr(...@@ -3117,11 +3194,11 @@ fn elemPtr(
3117 const index_u64 = index_val.toUnsignedInt();3194 const index_u64 = index_val.toUnsignedInt();
3118 // @intCast here because it would have been impossible to construct a value that3195 // @intCast here because it would have been impossible to construct a value that
3119 // required a larger index.3196 // required a larger index.
3120 const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64));3197 const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
3121 const pointee_type = elem_ty.elemType().elemType();3198 const pointee_type = elem_ty.elemType().elemType();
31223199
3123 return mod.constInst(scope, src, .{3200 return sema.mod.constInst(sema.arena, src, .{
3124 .ty = try Type.Tag.single_const_pointer.create(scope.arena(), pointee_type),3201 .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
3125 .val = elem_ptr,3202 .val = elem_ptr,
3126 });3203 });
3127 }3204 }
...@@ -3131,9 +3208,15 @@ fn elemPtr(...@@ -3131,9 +3208,15 @@ fn elemPtr(
3131 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{});3208 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{});
3132}3209}
31333210
3134fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerError!*Inst {3211fn coerce(
3212 sema: *Sema,
3213 block: *Scope.Block,
3214 dest_type: Type,
3215 inst: *Inst,
3216 inst_src: LazySrcLoc,
3217) InnerError!*Inst {
3135 if (dest_type.tag() == .var_args_param) {3218 if (dest_type.tag() == .var_args_param) {
3136 return sema.coerceVarArgParam(scope, inst);3219 return sema.coerceVarArgParam(block, inst);
3137 }3220 }
3138 // If the types are the same, we can return the operand.3221 // If the types are the same, we can return the operand.
3139 if (dest_type.eql(inst.ty))3222 if (dest_type.eql(inst.ty))
...@@ -3141,20 +3224,20 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3141,20 +3224,20 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
31413224
3142 const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty);3225 const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty);
3143 if (in_memory_result == .ok) {3226 if (in_memory_result == .ok) {
3144 return sema.bitcast(scope, dest_type, inst);3227 return sema.bitcast(block, dest_type, inst);
3145 }3228 }
31463229
3147 // undefined to anything3230 // undefined to anything
3148 if (inst.value()) |val| {3231 if (inst.value()) |val| {
3149 if (val.isUndef() or inst.ty.zigTypeTag() == .Undefined) {3232 if (val.isUndef() or inst.ty.zigTypeTag() == .Undefined) {
3150 return mod.constInst(scope.arena(), inst.src, .{ .ty = dest_type, .val = val });3233 return sema.mod.constInst(sema.arena, inst_src, .{ .ty = dest_type, .val = val });
3151 }3234 }
3152 }3235 }
3153 assert(inst.ty.zigTypeTag() != .Undefined);3236 assert(inst.ty.zigTypeTag() != .Undefined);
31543237
3155 // null to ?T3238 // null to ?T
3156 if (dest_type.zigTypeTag() == .Optional and inst.ty.zigTypeTag() == .Null) {3239 if (dest_type.zigTypeTag() == .Optional and inst.ty.zigTypeTag() == .Null) {
3157 return mod.constInst(scope.arena(), inst.src, .{ .ty = dest_type, .val = Value.initTag(.null_value) });3240 return sema.mod.constInst(sema.arena, inst_src, .{ .ty = dest_type, .val = Value.initTag(.null_value) });
3158 }3241 }
31593242
3160 // T to ?T3243 // T to ?T
...@@ -3162,15 +3245,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3162,15 +3245,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
3162 var buf: Type.Payload.ElemType = undefined;3245 var buf: Type.Payload.ElemType = undefined;
3163 const child_type = dest_type.optionalChild(&buf);3246 const child_type = dest_type.optionalChild(&buf);
3164 if (child_type.eql(inst.ty)) {3247 if (child_type.eql(inst.ty)) {
3165 return mod.wrapOptional(scope, dest_type, inst);3248 return sema.wrapOptional(block, dest_type, inst);
3166 } else if (try sema.coerceNum(scope, child_type, inst)) |some| {3249 } else if (try sema.coerceNum(block, child_type, inst)) |some| {
3167 return mod.wrapOptional(scope, dest_type, some);3250 return sema.wrapOptional(block, dest_type, some);
3168 }3251 }
3169 }3252 }
31703253
3171 // T to E!T or E to E!T3254 // T to E!T or E to E!T
3172 if (dest_type.tag() == .error_union) {3255 if (dest_type.tag() == .error_union) {
3173 return try mod.wrapErrorUnion(scope, dest_type, inst);3256 return try sema.wrapErrorUnion(block, dest_type, inst);
3174 }3257 }
31753258
3176 // Coercions where the source is a single pointer to an array.3259 // Coercions where the source is a single pointer to an array.
...@@ -3191,11 +3274,11 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3191,11 +3274,11 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
3191 switch (dest_type.ptrSize()) {3274 switch (dest_type.ptrSize()) {
3192 .Slice => {3275 .Slice => {
3193 // *[N]T to []T3276 // *[N]T to []T
3194 return sema.coerceArrayPtrToSlice(scope, dest_type, inst);3277 return sema.coerceArrayPtrToSlice(block, dest_type, inst);
3195 },3278 },
3196 .C => {3279 .C => {
3197 // *[N]T to [*c]T3280 // *[N]T to [*c]T
3198 return sema.coerceArrayPtrToMany(scope, dest_type, inst);3281 return sema.coerceArrayPtrToMany(block, dest_type, inst);
3199 },3282 },
3200 .Many => {3283 .Many => {
3201 // *[N]T to [*]T3284 // *[N]T to [*]T
...@@ -3203,12 +3286,12 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3203,12 +3286,12 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
3203 const src_sentinel = array_type.sentinel();3286 const src_sentinel = array_type.sentinel();
3204 const dst_sentinel = dest_type.sentinel();3287 const dst_sentinel = dest_type.sentinel();
3205 if (src_sentinel == null and dst_sentinel == null)3288 if (src_sentinel == null and dst_sentinel == null)
3206 return sema.coerceArrayPtrToMany(scope, dest_type, inst);3289 return sema.coerceArrayPtrToMany(block, dest_type, inst);
32073290
3208 if (src_sentinel) |src_s| {3291 if (src_sentinel) |src_s| {
3209 if (dst_sentinel) |dst_s| {3292 if (dst_sentinel) |dst_s| {
3210 if (src_s.eql(dst_s)) {3293 if (src_s.eql(dst_s)) {
3211 return sema.coerceArrayPtrToMany(scope, dest_type, inst);3294 return sema.coerceArrayPtrToMany(block, dest_type, inst);
3212 }3295 }
3213 }3296 }
3214 }3297 }
...@@ -3218,21 +3301,23 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3218,21 +3301,23 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
3218 }3301 }
32193302
3220 // comptime known number to other number3303 // comptime known number to other number
3221 if (try sema.coerceNum(scope, dest_type, inst)) |some|3304 if (try sema.coerceNum(block, dest_type, inst)) |some|
3222 return some;3305 return some;
32233306
3307 const target = sema.mod.getTarget();
3308
3224 // integer widening3309 // integer widening
3225 if (inst.ty.zigTypeTag() == .Int and dest_type.zigTypeTag() == .Int) {3310 if (inst.ty.zigTypeTag() == .Int and dest_type.zigTypeTag() == .Int) {
3226 assert(inst.value() == null); // handled above3311 assert(inst.value() == null); // handled above
32273312
3228 const src_info = inst.ty.intInfo(mod.getTarget());3313 const src_info = inst.ty.intInfo(target);
3229 const dst_info = dest_type.intInfo(mod.getTarget());3314 const dst_info = dest_type.intInfo(target);
3230 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or3315 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or
3231 // small enough unsigned ints can get casted to large enough signed ints3316 // small enough unsigned ints can get casted to large enough signed ints
3232 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))3317 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))
3233 {3318 {
3234 try sema.requireRuntimeBlock(block, inst.src);3319 try sema.requireRuntimeBlock(block, inst_src);
3235 return mod.addUnOp(b, inst.src, dest_type, .intcast, inst);3320 return block.addUnOp(inst_src, dest_type, .intcast, inst);
3236 }3321 }
3237 }3322 }
32383323
...@@ -3240,15 +3325,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE...@@ -3240,15 +3325,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
3240 if (inst.ty.zigTypeTag() == .Float and dest_type.zigTypeTag() == .Float) {3325 if (inst.ty.zigTypeTag() == .Float and dest_type.zigTypeTag() == .Float) {
3241 assert(inst.value() == null); // handled above3326 assert(inst.value() == null); // handled above
32423327
3243 const src_bits = inst.ty.floatBits(mod.getTarget());3328 const src_bits = inst.ty.floatBits(target);
3244 const dst_bits = dest_type.floatBits(mod.getTarget());3329 const dst_bits = dest_type.floatBits(target);
3245 if (dst_bits >= src_bits) {3330 if (dst_bits >= src_bits) {
3246 try sema.requireRuntimeBlock(block, inst.src);3331 try sema.requireRuntimeBlock(block, inst_src);
3247 return mod.addUnOp(b, inst.src, dest_type, .floatcast, inst);3332 return block.addUnOp(inst_src, dest_type, .floatcast, inst);
3248 }3333 }
3249 }3334 }
32503335
3251 return sema.mod.fail(&block.base, inst.src, "expected {}, found {}", .{ dest_type, inst.ty });3336 return sema.mod.fail(&block.base, inst_src, "expected {}, found {}", .{ dest_type, inst.ty });
3252}3337}
32533338
3254const InMemoryCoercionResult = enum {3339const InMemoryCoercionResult = enum {
...@@ -3270,6 +3355,8 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn...@@ -3270,6 +3355,8 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn
3270 const src_zig_tag = inst.ty.zigTypeTag();3355 const src_zig_tag = inst.ty.zigTypeTag();
3271 const dst_zig_tag = dest_type.zigTypeTag();3356 const dst_zig_tag = dest_type.zigTypeTag();
32723357
3358 const target = sema.mod.getTarget();
3359
3273 if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) {3360 if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) {
3274 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {3361 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
3275 if (val.floatHasFraction()) {3362 if (val.floatHasFraction()) {
...@@ -3277,23 +3364,23 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn...@@ -3277,23 +3364,23 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn
3277 }3364 }
3278 return sema.mod.fail(&block.base, inst.src, "TODO float to int", .{});3365 return sema.mod.fail(&block.base, inst.src, "TODO float to int", .{});
3279 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {3366 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
3280 if (!val.intFitsInType(dest_type, mod.getTarget())) {3367 if (!val.intFitsInType(dest_type, target)) {
3281 return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });3368 return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });
3282 }3369 }
3283 return mod.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });3370 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
3284 }3371 }
3285 } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) {3372 } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) {
3286 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {3373 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
3287 const res = val.floatCast(scope.arena(), dest_type, mod.getTarget()) catch |err| switch (err) {3374 const res = val.floatCast(sema.arena, dest_type, target) catch |err| switch (err) {
3288 error.Overflow => return mod.fail(3375 error.Overflow => return sema.mod.fail(
3289 scope,3376 &block.base,
3290 inst.src,3377 inst.src,
3291 "cast of value {} to type '{}' loses information",3378 "cast of value {} to type '{}' loses information",
3292 .{ val, dest_type },3379 .{ val, dest_type },
3293 ),3380 ),
3294 error.OutOfMemory => return error.OutOfMemory,3381 error.OutOfMemory => return error.OutOfMemory,
3295 };3382 };
3296 return mod.constInst(scope, inst.src, .{ .ty = dest_type, .val = res });3383 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = res });
3297 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {3384 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
3298 return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{});3385 return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{});
3299 }3386 }
...@@ -3310,12 +3397,18 @@ fn coerceVarArgParam(sema: *Sema, block: *Scope.Block, inst: *Inst) !*Inst {...@@ -3310,12 +3397,18 @@ fn coerceVarArgParam(sema: *Sema, block: *Scope.Block, inst: *Inst) !*Inst {
3310 return inst;3397 return inst;
3311}3398}
33123399
3313fn storePtr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ptr: *Inst, uncasted_value: *Inst) !*Inst {3400fn storePtr(
3401 sema: *Sema,
3402 block: *Scope.Block,
3403 src: LazySrcLoc,
3404 ptr: *Inst,
3405 uncasted_value: *Inst,
3406) !*Inst {
3314 if (ptr.ty.isConstPtr())3407 if (ptr.ty.isConstPtr())
3315 return sema.mod.fail(&block.base, src, "cannot assign to constant", .{});3408 return sema.mod.fail(&block.base, src, "cannot assign to constant", .{});
33163409
3317 const elem_ty = ptr.ty.elemType();3410 const elem_ty = ptr.ty.elemType();
3318 const value = try sema.coerce(scope, elem_ty, uncasted_value);3411 const value = try sema.coerce(block, elem_ty, uncasted_value, uncasted_value.src);
3319 if (elem_ty.onePossibleValue() != null)3412 if (elem_ty.onePossibleValue() != null)
3320 return sema.mod.constVoid(sema.arena, .unneeded);3413 return sema.mod.constVoid(sema.arena, .unneeded);
33213414
...@@ -3323,23 +3416,23 @@ fn storePtr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ptr: *Inst, uncas...@@ -3323,23 +3416,23 @@ fn storePtr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ptr: *Inst, uncas
3323 // TODO handle if the element type requires comptime3416 // TODO handle if the element type requires comptime
33243417
3325 try sema.requireRuntimeBlock(block, src);3418 try sema.requireRuntimeBlock(block, src);
3326 return mod.addBinOp(b, src, Type.initTag(.void), .store, ptr, value);3419 return block.addBinOp(src, Type.initTag(.void), .store, ptr, value);
3327}3420}
33283421
3329fn bitcast(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {3422fn bitcast(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
3330 if (inst.value()) |val| {3423 if (inst.value()) |val| {
3331 // Keep the comptime Value representation; take the new type.3424 // Keep the comptime Value representation; take the new type.
3332 return mod.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });3425 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
3333 }3426 }
3334 // TODO validate the type size and other compile errors3427 // TODO validate the type size and other compile errors
3335 try sema.requireRuntimeBlock(block, inst.src);3428 try sema.requireRuntimeBlock(block, inst.src);
3336 return mod.addUnOp(b, inst.src, dest_type, .bitcast, inst);3429 return block.addUnOp(inst.src, dest_type, .bitcast, inst);
3337}3430}
33383431
3339fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {3432fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
3340 if (inst.value()) |val| {3433 if (inst.value()) |val| {
3341 // The comptime Value representation is compatible with both types.3434 // The comptime Value representation is compatible with both types.
3342 return mod.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });3435 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
3343 }3436 }
3344 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});3437 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
3345}3438}
...@@ -3347,7 +3440,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst...@@ -3347,7 +3440,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst
3347fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {3440fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
3348 if (inst.value()) |val| {3441 if (inst.value()) |val| {
3349 // The comptime Value representation is compatible with both types.3442 // The comptime Value representation is compatible with both types.
3350 return mod.constInst(scope, inst.src, .{ .ty = dest_type, .val = val });3443 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
3351 }3444 }
3352 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});3445 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});
3353}3446}
...@@ -3358,44 +3451,39 @@ fn analyzeDeclVal(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl...@@ -3358,44 +3451,39 @@ fn analyzeDeclVal(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl
3358}3451}
33593452
3360fn analyzeDeclRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl) InnerError!*Inst {3453fn analyzeDeclRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl) InnerError!*Inst {
3361 const scope_decl = scope.ownerDecl().?;3454 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
3362 try mod.declareDeclDependency(scope_decl, decl);3455 sema.mod.ensureDeclAnalyzed(decl) catch |err| {
3363 mod.ensureDeclAnalyzed(decl) catch |err| {3456 if (sema.func) |func| {
3364 if (scope.cast(Scope.Block)) |block| {3457 func.state = .dependency_failure;
3365 if (block.func) |func| {
3366 func.state = .dependency_failure;
3367 } else {
3368 block.owner_decl.analysis = .dependency_failure;
3369 }
3370 } else {3458 } else {
3371 scope_decl.analysis = .dependency_failure;3459 sema.owner_decl.analysis = .dependency_failure;
3372 }3460 }
3373 return err;3461 return err;
3374 };3462 };
33753463
3376 const decl_tv = try decl.typedValue();3464 const decl_tv = try decl.typedValue();
3377 if (decl_tv.val.tag() == .variable) {3465 if (decl_tv.val.tag() == .variable) {
3378 return mod.analyzeVarRef(scope, src, decl_tv);3466 return sema.analyzeVarRef(block, src, decl_tv);
3379 }3467 }
3380 return mod.constInst(scope.arena(), src, .{3468 return sema.mod.constInst(sema.arena, src, .{
3381 .ty = try mod.simplePtrType(scope.arena(), decl_tv.ty, false, .One),3469 .ty = try sema.mod.simplePtrType(sema.arena, decl_tv.ty, false, .One),
3382 .val = try Value.Tag.decl_ref.create(scope.arena(), decl),3470 .val = try Value.Tag.decl_ref.create(sema.arena, decl),
3383 });3471 });
3384}3472}
33853473
3386fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedValue) InnerError!*Inst {3474fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedValue) InnerError!*Inst {
3387 const variable = tv.val.castTag(.variable).?.data;3475 const variable = tv.val.castTag(.variable).?.data;
33883476
3389 const ty = try mod.simplePtrType(scope.arena(), tv.ty, variable.is_mutable, .One);3477 const ty = try sema.mod.simplePtrType(sema.arena, tv.ty, variable.is_mutable, .One);
3390 if (!variable.is_mutable and !variable.is_extern) {3478 if (!variable.is_mutable and !variable.is_extern) {
3391 return mod.constInst(scope.arena(), src, .{3479 return sema.mod.constInst(sema.arena, src, .{
3392 .ty = ty,3480 .ty = ty,
3393 .val = try Value.Tag.ref_val.create(scope.arena(), variable.init),3481 .val = try Value.Tag.ref_val.create(sema.arena, variable.init),
3394 });3482 });
3395 }3483 }
33963484
3397 try sema.requireRuntimeBlock(block, src);3485 try sema.requireRuntimeBlock(block, src);
3398 const inst = try b.arena.create(Inst.VarPtr);3486 const inst = try sema.arena.create(Inst.VarPtr);
3399 inst.* = .{3487 inst.* = .{
3400 .base = .{3488 .base = .{
3401 .tag = .varptr,3489 .tag = .varptr,
...@@ -3404,7 +3492,7 @@ fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedVal...@@ -3404,7 +3492,7 @@ fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedVal
3404 },3492 },
3405 .variable = variable,3493 .variable = variable,
3406 };3494 };
3407 try b.instructions.append(mod.gpa, &inst.base);3495 try block.instructions.append(sema.gpa, &inst.base);
3408 return &inst.base;3496 return &inst.base;
3409}3497}
34103498
...@@ -3414,12 +3502,12 @@ fn analyzeRef(...@@ -3414,12 +3502,12 @@ fn analyzeRef(
3414 src: LazySrcLoc,3502 src: LazySrcLoc,
3415 operand: *Inst,3503 operand: *Inst,
3416) InnerError!*Inst {3504) InnerError!*Inst {
3417 const ptr_type = try mod.simplePtrType(scope.arena(), operand.ty, false, .One);3505 const ptr_type = try sema.mod.simplePtrType(sema.arena, operand.ty, false, .One);
34183506
3419 if (operand.value()) |val| {3507 if (operand.value()) |val| {
3420 return mod.constInst(scope.arena(), src, .{3508 return sema.mod.constInst(sema.arena, src, .{
3421 .ty = ptr_type,3509 .ty = ptr_type,
3422 .val = try Value.Tag.ref_val.create(scope.arena(), val),3510 .val = try Value.Tag.ref_val.create(sema.arena, val),
3423 });3511 });
3424 }3512 }
34253513
...@@ -3439,14 +3527,14 @@ fn analyzeDeref(...@@ -3439,14 +3527,14 @@ fn analyzeDeref(
3439 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty}),3527 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty}),
3440 };3528 };
3441 if (ptr.value()) |val| {3529 if (ptr.value()) |val| {
3442 return mod.constInst(scope.arena(), src, .{3530 return sema.mod.constInst(sema.arena, src, .{
3443 .ty = elem_ty,3531 .ty = elem_ty,
3444 .val = try val.pointerDeref(scope.arena()),3532 .val = try val.pointerDeref(sema.arena),
3445 });3533 });
3446 }3534 }
34473535
3448 try sema.requireRuntimeBlock(block, src);3536 try sema.requireRuntimeBlock(block, src);
3449 return mod.addUnOp(b, src, elem_ty, .load, ptr);3537 return block.addUnOp(src, elem_ty, .load, ptr);
3450}3538}
34513539
3452fn analyzeIsNull(3540fn analyzeIsNull(
...@@ -3459,23 +3547,23 @@ fn analyzeIsNull(...@@ -3459,23 +3547,23 @@ fn analyzeIsNull(
3459 if (operand.value()) |opt_val| {3547 if (operand.value()) |opt_val| {
3460 const is_null = opt_val.isNull();3548 const is_null = opt_val.isNull();
3461 const bool_value = if (invert_logic) !is_null else is_null;3549 const bool_value = if (invert_logic) !is_null else is_null;
3462 return mod.constBool(sema.arena, src, bool_value);3550 return sema.mod.constBool(sema.arena, src, bool_value);
3463 }3551 }
3464 try sema.requireRuntimeBlock(block, src);3552 try sema.requireRuntimeBlock(block, src);
3465 const inst_tag: Inst.Tag = if (invert_logic) .is_non_null else .is_null;3553 const inst_tag: Inst.Tag = if (invert_logic) .is_non_null else .is_null;
3466 return mod.addUnOp(b, src, Type.initTag(.bool), inst_tag, operand);3554 return block.addUnOp(src, Type.initTag(.bool), inst_tag, operand);
3467}3555}
34683556
3469fn analyzeIsErr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, operand: *Inst) InnerError!*Inst {3557fn analyzeIsErr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, operand: *Inst) InnerError!*Inst {
3470 const ot = operand.ty.zigTypeTag();3558 const ot = operand.ty.zigTypeTag();
3471 if (ot != .ErrorSet and ot != .ErrorUnion) return mod.constBool(sema.arena, src, false);3559 if (ot != .ErrorSet and ot != .ErrorUnion) return sema.mod.constBool(sema.arena, src, false);
3472 if (ot == .ErrorSet) return mod.constBool(sema.arena, src, true);3560 if (ot == .ErrorSet) return sema.mod.constBool(sema.arena, src, true);
3473 assert(ot == .ErrorUnion);3561 assert(ot == .ErrorUnion);
3474 if (operand.value()) |err_union| {3562 if (operand.value()) |err_union| {
3475 return mod.constBool(sema.arena, src, err_union.getError() != null);3563 return sema.mod.constBool(sema.arena, src, err_union.getError() != null);
3476 }3564 }
3477 try sema.requireRuntimeBlock(block, src);3565 try sema.requireRuntimeBlock(block, src);
3478 return mod.addUnOp(b, src, Type.initTag(.bool), .is_err, operand);3566 return block.addUnOp(src, Type.initTag(.bool), .is_err, operand);
3479}3567}
34803568
3481fn analyzeSlice(3569fn analyzeSlice(
...@@ -3511,7 +3599,7 @@ fn analyzeSlice(...@@ -3511,7 +3599,7 @@ fn analyzeSlice(
3511 };3599 };
35123600
3513 const slice_sentinel = if (sentinel_opt) |sentinel| blk: {3601 const slice_sentinel = if (sentinel_opt) |sentinel| blk: {
3514 const casted = try sema.coerce(scope, elem_type, sentinel);3602 const casted = try sema.coerce(block, elem_type, sentinel, sentinel.src);
3515 break :blk try sema.resolveConstValue(block, sentinel_src, casted);3603 break :blk try sema.resolveConstValue(block, sentinel_src, casted);
3516 } else null;3604 } else null;
35173605
...@@ -3531,13 +3619,13 @@ fn analyzeSlice(...@@ -3531,13 +3619,13 @@ fn analyzeSlice(
3531 array_type.sentinel()3619 array_type.sentinel()
3532 else3620 else
3533 slice_sentinel;3621 slice_sentinel;
3534 return_elem_type = try mod.arrayType(scope, len, array_sentinel, elem_type);3622 return_elem_type = try sema.mod.arrayType(sema.arena, len, array_sentinel, elem_type);
3535 return_ptr_size = .One;3623 return_ptr_size = .One;
3536 }3624 }
3537 }3625 }
3538 }3626 }
3539 const return_type = try mod.ptrType(3627 const return_type = try sema.mod.ptrType(
3540 scope,3628 sema.arena,
3541 return_elem_type,3629 return_elem_type,
3542 if (end_opt == null) slice_sentinel else null,3630 if (end_opt == null) slice_sentinel else null,
3543 0, // TODO alignment3631 0, // TODO alignment
...@@ -3553,24 +3641,24 @@ fn analyzeSlice(...@@ -3553,24 +3641,24 @@ fn analyzeSlice(
3553}3641}
35543642
3555fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_string: []const u8) !*Scope.File {3643fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_string: []const u8) !*Scope.File {
3556 const cur_pkg = scope.getFileScope().pkg;3644 const cur_pkg = block.getFileScope().pkg;
3557 const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse ".";3645 const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse ".";
3558 const found_pkg = cur_pkg.table.get(target_string);3646 const found_pkg = cur_pkg.table.get(target_string);
35593647
3560 const resolved_path = if (found_pkg) |pkg|3648 const resolved_path = if (found_pkg) |pkg|
3561 try std.fs.path.resolve(mod.gpa, &[_][]const u8{ pkg.root_src_directory.path orelse ".", pkg.root_src_path })3649 try std.fs.path.resolve(sema.gpa, &[_][]const u8{ pkg.root_src_directory.path orelse ".", pkg.root_src_path })
3562 else3650 else
3563 try std.fs.path.resolve(mod.gpa, &[_][]const u8{ cur_pkg_dir_path, target_string });3651 try std.fs.path.resolve(sema.gpa, &[_][]const u8{ cur_pkg_dir_path, target_string });
3564 errdefer mod.gpa.free(resolved_path);3652 errdefer sema.gpa.free(resolved_path);
35653653
3566 if (mod.import_table.get(resolved_path)) |some| {3654 if (sema.mod.import_table.get(resolved_path)) |some| {
3567 mod.gpa.free(resolved_path);3655 sema.gpa.free(resolved_path);
3568 return some;3656 return some;
3569 }3657 }
35703658
3571 if (found_pkg == null) {3659 if (found_pkg == null) {
3572 const resolved_root_path = try std.fs.path.resolve(mod.gpa, &[_][]const u8{cur_pkg_dir_path});3660 const resolved_root_path = try std.fs.path.resolve(sema.gpa, &[_][]const u8{cur_pkg_dir_path});
3573 defer mod.gpa.free(resolved_root_path);3661 defer sema.gpa.free(resolved_root_path);
35743662
3575 if (!mem.startsWith(u8, resolved_path, resolved_root_path)) {3663 if (!mem.startsWith(u8, resolved_path, resolved_root_path)) {
3576 return error.ImportOutsidePkgPath;3664 return error.ImportOutsidePkgPath;
...@@ -3578,10 +3666,10 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin...@@ -3578,10 +3666,10 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin
3578 }3666 }
35793667
3580 // TODO Scope.Container arena for ty and sub_file_path3668 // TODO Scope.Container arena for ty and sub_file_path
3581 const file_scope = try mod.gpa.create(Scope.File);3669 const file_scope = try sema.gpa.create(Scope.File);
3582 errdefer mod.gpa.destroy(file_scope);3670 errdefer sema.gpa.destroy(file_scope);
3583 const struct_ty = try Type.Tag.empty_struct.create(mod.gpa, &file_scope.root_container);3671 const struct_ty = try Type.Tag.empty_struct.create(sema.gpa, &file_scope.root_container);
3584 errdefer mod.gpa.destroy(struct_ty.castTag(.empty_struct).?);3672 errdefer sema.gpa.destroy(struct_ty.castTag(.empty_struct).?);
35853673
3586 file_scope.* = .{3674 file_scope.* = .{
3587 .sub_file_path = resolved_path,3675 .sub_file_path = resolved_path,
...@@ -3595,13 +3683,13 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin...@@ -3595,13 +3683,13 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin
3595 .ty = struct_ty,3683 .ty = struct_ty,
3596 },3684 },
3597 };3685 };
3598 mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {3686 sema.mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {
3599 error.AnalysisFail => {3687 error.AnalysisFail => {
3600 assert(mod.comp.totalErrorCount() != 0);3688 assert(sema.mod.comp.totalErrorCount() != 0);
3601 },3689 },
3602 else => |e| return e,3690 else => |e| return e,
3603 };3691 };
3604 try mod.import_table.put(mod.gpa, file_scope.sub_file_path, file_scope);3692 try sema.mod.import_table.put(sema.gpa, file_scope.sub_file_path, file_scope);
3605 return file_scope;3693 return file_scope;
3606}3694}
36073695
...@@ -3637,7 +3725,7 @@ fn cmpNumeric(...@@ -3637,7 +3725,7 @@ fn cmpNumeric(
36373725
3638 if (lhs.value()) |lhs_val| {3726 if (lhs.value()) |lhs_val| {
3639 if (rhs.value()) |rhs_val| {3727 if (rhs.value()) |rhs_val| {
3640 return mod.constBool(sema.arena, src, Value.compare(lhs_val, op, rhs_val));3728 return sema.mod.constBool(sema.arena, src, Value.compare(lhs_val, op, rhs_val));
3641 }3729 }
3642 }3730 }
36433731
...@@ -3658,6 +3746,7 @@ fn cmpNumeric(...@@ -3658,6 +3746,7 @@ fn cmpNumeric(
3658 .Float, .ComptimeFloat => true,3746 .Float, .ComptimeFloat => true,
3659 else => false,3747 else => false,
3660 };3748 };
3749 const target = sema.mod.getTarget();
3661 if (lhs_is_float and rhs_is_float) {3750 if (lhs_is_float and rhs_is_float) {
3662 // Implicit cast the smaller one to the larger one.3751 // Implicit cast the smaller one to the larger one.
3663 const dest_type = x: {3752 const dest_type = x: {
...@@ -3666,15 +3755,15 @@ fn cmpNumeric(...@@ -3666,15 +3755,15 @@ fn cmpNumeric(
3666 } else if (rhs_ty_tag == .ComptimeFloat) {3755 } else if (rhs_ty_tag == .ComptimeFloat) {
3667 break :x lhs.ty;3756 break :x lhs.ty;
3668 }3757 }
3669 if (lhs.ty.floatBits(mod.getTarget()) >= rhs.ty.floatBits(mod.getTarget())) {3758 if (lhs.ty.floatBits(target) >= rhs.ty.floatBits(target)) {
3670 break :x lhs.ty;3759 break :x lhs.ty;
3671 } else {3760 } else {
3672 break :x rhs.ty;3761 break :x rhs.ty;
3673 }3762 }
3674 };3763 };
3675 const casted_lhs = try sema.coerce(scope, dest_type, lhs);3764 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
3676 const casted_rhs = try sema.coerce(scope, dest_type, rhs);3765 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
3677 return mod.addBinOp(b, src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);3766 return block.addBinOp(src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
3678 }3767 }
3679 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.3768 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.
3680 // For mixed signed and unsigned integers, implicit cast both operands to a signed3769 // For mixed signed and unsigned integers, implicit cast both operands to a signed
...@@ -3697,16 +3786,16 @@ fn cmpNumeric(...@@ -3697,16 +3786,16 @@ fn cmpNumeric(
3697 var lhs_bits: usize = undefined;3786 var lhs_bits: usize = undefined;
3698 if (lhs.value()) |lhs_val| {3787 if (lhs.value()) |lhs_val| {
3699 if (lhs_val.isUndef())3788 if (lhs_val.isUndef())
3700 return mod.constUndef(scope, src, Type.initTag(.bool));3789 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
3701 const is_unsigned = if (lhs_is_float) x: {3790 const is_unsigned = if (lhs_is_float) x: {
3702 var bigint_space: Value.BigIntSpace = undefined;3791 var bigint_space: Value.BigIntSpace = undefined;
3703 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(mod.gpa);3792 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
3704 defer bigint.deinit();3793 defer bigint.deinit();
3705 const zcmp = lhs_val.orderAgainstZero();3794 const zcmp = lhs_val.orderAgainstZero();
3706 if (lhs_val.floatHasFraction()) {3795 if (lhs_val.floatHasFraction()) {
3707 switch (op) {3796 switch (op) {
3708 .eq => return mod.constBool(sema.arena, src, false),3797 .eq => return sema.mod.constBool(sema.arena, src, false),
3709 .neq => return mod.constBool(sema.arena, src, true),3798 .neq => return sema.mod.constBool(sema.arena, src, true),
3710 else => {},3799 else => {},
3711 }3800 }
3712 if (zcmp == .lt) {3801 if (zcmp == .lt) {
...@@ -3725,23 +3814,23 @@ fn cmpNumeric(...@@ -3725,23 +3814,23 @@ fn cmpNumeric(
3725 } else if (lhs_is_float) {3814 } else if (lhs_is_float) {
3726 dest_float_type = lhs.ty;3815 dest_float_type = lhs.ty;
3727 } else {3816 } else {
3728 const int_info = lhs.ty.intInfo(mod.getTarget());3817 const int_info = lhs.ty.intInfo(target);
3729 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);3818 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
3730 }3819 }
37313820
3732 var rhs_bits: usize = undefined;3821 var rhs_bits: usize = undefined;
3733 if (rhs.value()) |rhs_val| {3822 if (rhs.value()) |rhs_val| {
3734 if (rhs_val.isUndef())3823 if (rhs_val.isUndef())
3735 return mod.constUndef(scope, src, Type.initTag(.bool));3824 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
3736 const is_unsigned = if (rhs_is_float) x: {3825 const is_unsigned = if (rhs_is_float) x: {
3737 var bigint_space: Value.BigIntSpace = undefined;3826 var bigint_space: Value.BigIntSpace = undefined;
3738 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(mod.gpa);3827 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
3739 defer bigint.deinit();3828 defer bigint.deinit();
3740 const zcmp = rhs_val.orderAgainstZero();3829 const zcmp = rhs_val.orderAgainstZero();
3741 if (rhs_val.floatHasFraction()) {3830 if (rhs_val.floatHasFraction()) {
3742 switch (op) {3831 switch (op) {
3743 .eq => return mod.constBool(sema.arena, src, false),3832 .eq => return sema.mod.constBool(sema.arena, src, false),
3744 .neq => return mod.constBool(sema.arena, src, true),3833 .neq => return sema.mod.constBool(sema.arena, src, true),
3745 else => {},3834 else => {},
3746 }3835 }
3747 if (zcmp == .lt) {3836 if (zcmp == .lt) {
...@@ -3760,7 +3849,7 @@ fn cmpNumeric(...@@ -3760,7 +3849,7 @@ fn cmpNumeric(
3760 } else if (rhs_is_float) {3849 } else if (rhs_is_float) {
3761 dest_float_type = rhs.ty;3850 dest_float_type = rhs.ty;
3762 } else {3851 } else {
3763 const int_info = rhs.ty.intInfo(mod.getTarget());3852 const int_info = rhs.ty.intInfo(target);
3764 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);3853 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
3765 }3854 }
37663855
...@@ -3769,21 +3858,21 @@ fn cmpNumeric(...@@ -3769,21 +3858,21 @@ fn cmpNumeric(
3769 const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {3858 const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {
3770 error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}),3859 error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}),
3771 };3860 };
3772 break :blk try mod.makeIntType(scope, dest_int_is_signed, casted_bits);3861 break :blk try Module.makeIntType(sema.arena, dest_int_is_signed, casted_bits);
3773 };3862 };
3774 const casted_lhs = try sema.coerce(scope, dest_type, lhs);3863 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
3775 const casted_rhs = try sema.coerce(scope, dest_type, rhs);3864 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
37763865
3777 return mod.addBinOp(b, src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);3866 return block.addBinOp(src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
3778}3867}
37793868
3780fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {3869fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
3781 if (inst.value()) |val| {3870 if (inst.value()) |val| {
3782 return mod.constInst(scope.arena(), inst.src, .{ .ty = dest_type, .val = val });3871 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
3783 }3872 }
37843873
3785 try sema.requireRuntimeBlock(block, inst.src);3874 try sema.requireRuntimeBlock(block, inst.src);
3786 return mod.addUnOp(b, inst.src, dest_type, .wrap_optional, inst);3875 return block.addUnOp(inst.src, dest_type, .wrap_optional, inst);
3787}3876}
37883877
3789fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {3878fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
...@@ -3791,7 +3880,7 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst...@@ -3791,7 +3880,7 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst
3791 const err_union = dest_type.castTag(.error_union).?;3880 const err_union = dest_type.castTag(.error_union).?;
3792 if (inst.value()) |val| {3881 if (inst.value()) |val| {
3793 const to_wrap = if (inst.ty.zigTypeTag() != .ErrorSet) blk: {3882 const to_wrap = if (inst.ty.zigTypeTag() != .ErrorSet) blk: {
3794 _ = try sema.coerce(scope, err_union.data.payload, inst);3883 _ = try sema.coerce(block, err_union.data.payload, inst, inst.src);
3795 break :blk val;3884 break :blk val;
3796 } else switch (err_union.data.error_set.tag()) {3885 } else switch (err_union.data.error_set.tag()) {
3797 .anyerror => val,3886 .anyerror => val,
...@@ -3810,11 +3899,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst...@@ -3810,11 +3899,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst
3810 else => unreachable,3899 else => unreachable,
3811 };3900 };
38123901
3813 return mod.constInst(scope.arena(), inst.src, .{3902 return sema.mod.constInst(sema.arena, inst.src, .{
3814 .ty = dest_type,3903 .ty = dest_type,
3815 // creating a SubValue for the error_union payload3904 // creating a SubValue for the error_union payload
3816 .val = try Value.Tag.error_union.create(3905 .val = try Value.Tag.error_union.create(
3817 scope.arena(),3906 sema.arena,
3818 to_wrap,3907 to_wrap,
3819 ),3908 ),
3820 });3909 });
...@@ -3824,11 +3913,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst...@@ -3824,11 +3913,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst
38243913
3825 // we are coercing from E to E!T3914 // we are coercing from E to E!T
3826 if (inst.ty.zigTypeTag() == .ErrorSet) {3915 if (inst.ty.zigTypeTag() == .ErrorSet) {
3827 var coerced = try sema.coerce(scope, err_union.data.error_set, inst);3916 var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);
3828 return mod.addUnOp(b, inst.src, dest_type, .wrap_errunion_err, coerced);3917 return block.addUnOp(inst.src, dest_type, .wrap_errunion_err, coerced);
3829 } else {3918 } else {
3830 var coerced = try sema.coerce(scope, err_union.data.payload, inst);3919 var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);
3831 return mod.addUnOp(b, inst.src, dest_type, .wrap_errunion_payload, coerced);3920 return block.addUnOp(inst.src, dest_type, .wrap_errunion_payload, coerced);
3832 }3921 }
3833}3922}
38343923
...@@ -3839,6 +3928,8 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty...@@ -3839,6 +3928,8 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty
3839 if (instructions.len == 1)3928 if (instructions.len == 1)
3840 return instructions[0].ty;3929 return instructions[0].ty;
38413930
3931 const target = sema.mod.getTarget();
3932
3842 var chosen = instructions[0];3933 var chosen = instructions[0];
3843 for (instructions[1..]) |candidate| {3934 for (instructions[1..]) |candidate| {
3844 if (candidate.ty.eql(chosen.ty))3935 if (candidate.ty.eql(chosen.ty))
...@@ -3859,13 +3950,13 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty...@@ -3859,13 +3950,13 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty
3859 candidate.ty.isInt() and3950 candidate.ty.isInt() and
3860 chosen.ty.isSignedInt() == candidate.ty.isSignedInt())3951 chosen.ty.isSignedInt() == candidate.ty.isSignedInt())
3861 {3952 {
3862 if (chosen.ty.intInfo(mod.getTarget()).bits < candidate.ty.intInfo(mod.getTarget()).bits) {3953 if (chosen.ty.intInfo(target).bits < candidate.ty.intInfo(target).bits) {
3863 chosen = candidate;3954 chosen = candidate;
3864 }3955 }
3865 continue;3956 continue;
3866 }3957 }
3867 if (chosen.ty.isFloat() and candidate.ty.isFloat()) {3958 if (chosen.ty.isFloat() and candidate.ty.isFloat()) {
3868 if (chosen.ty.floatBits(mod.getTarget()) < candidate.ty.floatBits(mod.getTarget())) {3959 if (chosen.ty.floatBits(target) < candidate.ty.floatBits(target)) {
3869 chosen = candidate;3960 chosen = candidate;
3870 }3961 }
3871 continue;3962 continue;
src/astgen.zig+38-28
...@@ -25,18 +25,18 @@ pub const ResultLoc = union(enum) {...@@ -25,18 +25,18 @@ pub const ResultLoc = union(enum) {
25 /// of an assignment uses this kind of result location.25 /// of an assignment uses this kind of result location.
26 ref,26 ref,
27 /// The expression will be coerced into this type, but it will be evaluated as an rvalue.27 /// The expression will be coerced into this type, but it will be evaluated as an rvalue.
28 ty: zir.Inst.Index,28 ty: zir.Inst.Ref,
29 /// The expression must store its result into this typed pointer. The result instruction29 /// The expression must store its result into this typed pointer. The result instruction
30 /// from the expression must be ignored.30 /// from the expression must be ignored.
31 ptr: zir.Inst.Index,31 ptr: zir.Inst.Ref,
32 /// The expression must store its result into this allocation, which has an inferred type.32 /// The expression must store its result into this allocation, which has an inferred type.
33 /// The result instruction from the expression must be ignored.33 /// The result instruction from the expression must be ignored.
34 /// Always an instruction with tag `alloc_inferred`.34 /// Always an instruction with tag `alloc_inferred`.
35 inferred_ptr: zir.Inst.Index,35 inferred_ptr: zir.Inst.Ref,
36 /// The expression must store its result into this pointer, which is a typed pointer that36 /// The expression must store its result into this pointer, which is a typed pointer that
37 /// has been bitcasted to whatever the expression's type is.37 /// has been bitcasted to whatever the expression's type is.
38 /// The result instruction from the expression must be ignored.38 /// The result instruction from the expression must be ignored.
39 bitcasted_ptr: zir.Inst.Index,39 bitcasted_ptr: zir.Inst.Ref,
40 /// There is a pointer for the expression to store its result into, however, its type40 /// There is a pointer for the expression to store its result into, however, its type
41 /// is inferred based on peer type resolution for a `zir.Inst.Block`.41 /// is inferred based on peer type resolution for a `zir.Inst.Block`.
42 /// The result instruction from the expression must be ignored.42 /// The result instruction from the expression must be ignored.
...@@ -1133,10 +1133,9 @@ fn varDecl(...@@ -1133,10 +1133,9 @@ fn varDecl(
1133 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as1133 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
1134 // the variable, no memory location needed.1134 // the variable, no memory location needed.
1135 if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {1135 if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {
1136 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0)1136 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0) .{
1137 .{ .ty = try typeExpr(mod, scope, var_decl.ast.type_node) }1137 .ty = try typeExpr(mod, scope, var_decl.ast.type_node),
1138 else1138 } else .none;
1139 .none;
1140 const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);1139 const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);
1141 const sub_scope = try block_arena.create(Scope.LocalVal);1140 const sub_scope = try block_arena.create(Scope.LocalVal);
1142 sub_scope.* = .{1141 sub_scope.* = .{
...@@ -2539,16 +2538,13 @@ fn switchExpr(...@@ -2539,16 +2538,13 @@ fn switchExpr(
2539 if (underscore_src != null) special_prong = .underscore;2538 if (underscore_src != null) special_prong = .underscore;
2540 var cases = try block_scope.arena.alloc(zir.Inst.SwitchBr.Case, simple_case_count);2539 var cases = try block_scope.arena.alloc(zir.Inst.SwitchBr.Case, simple_case_count);
25412540
2542 const rl_and_tag: struct { rl: ResultLoc, tag: zir.Inst.Tag } = if (any_payload_is_ref)2541 const rl_and_tag: struct { rl: ResultLoc, tag: zir.Inst.Tag } = if (any_payload_is_ref) .{
2543 .{2542 .rl = .ref,
2544 .rl = .ref,2543 .tag = .switchbr_ref,
2545 .tag = .switchbr_ref,2544 } else .{
2546 }2545 .rl = .none,
2547 else2546 .tag = .switchbr,
2548 .{2547 };
2549 .rl = .none,
2550 .tag = .switchbr,
2551 };
2552 const target = try expr(mod, &block_scope.base, rl_and_tag.rl, target_node);2548 const target = try expr(mod, &block_scope.base, rl_and_tag.rl, target_node);
2553 const switch_inst = try addZirInstT(mod, &block_scope.base, switch_src, zir.Inst.SwitchBr, rl_and_tag.tag, .{2549 const switch_inst = try addZirInstT(mod, &block_scope.base, switch_src, zir.Inst.SwitchBr, rl_and_tag.tag, .{
2554 .target = target,2550 .target = target,
...@@ -2980,11 +2976,12 @@ fn integerLiteral(...@@ -2980,11 +2976,12 @@ fn integerLiteral(
2980 const main_tokens = tree.nodes.items(.main_token);2976 const main_tokens = tree.nodes.items(.main_token);
2981 const int_token = main_tokens[int_lit];2977 const int_token = main_tokens[int_lit];
2982 const prefixed_bytes = tree.tokenSlice(int_token);2978 const prefixed_bytes = tree.tokenSlice(int_token);
2979 const gz = scope.getGenZir();
2983 if (std.fmt.parseInt(u64, prefixed_bytes, 0)) |small_int| {2980 if (std.fmt.parseInt(u64, prefixed_bytes, 0)) |small_int| {
2984 const result: zir.Inst.Index = switch (small_int) {2981 const result: zir.Inst.Index = switch (small_int) {
2985 0 => @enumToInt(zir.Const.zero),2982 0 => @enumToInt(zir.Const.zero),
2986 1 => @enumToInt(zir.Const.one),2983 1 => @enumToInt(zir.Const.one),
2987 else => try addZirInt(small_int),2984 else => try gz.addInt(small_int),
2988 };2985 };
2989 return rvalue(mod, scope, rl, result);2986 return rvalue(mod, scope, rl, result);
2990 } else |err| {2987 } else |err| {
...@@ -3418,6 +3415,10 @@ fn callExpr(...@@ -3418,6 +3415,10 @@ fn callExpr(
3418 node: ast.Node.Index,3415 node: ast.Node.Index,
3419 call: ast.full.Call,3416 call: ast.full.Call,
3420) InnerError!*zir.Inst {3417) InnerError!*zir.Inst {
3418 if (true) {
3419 @panic("TODO update for zir-memory-layout branch");
3420 }
3421
3421 if (call.async_token) |async_token| {3422 if (call.async_token) |async_token| {
3422 return mod.failTok(scope, async_token, "TODO implement async fn call", .{});3423 return mod.failTok(scope, async_token, "TODO implement async fn call", .{});
3423 }3424 }
...@@ -3512,7 +3513,7 @@ fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Inde...@@ -3512,7 +3513,7 @@ fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Inde
3512 const tree = scope.tree();3513 const tree = scope.tree();
3513 var child_scope = Scope.Nosuspend{3514 var child_scope = Scope.Nosuspend{
3514 .parent = scope,3515 .parent = scope,
3515 .gen_zir = scope.getGenZIR(),3516 .gen_zir = scope.getGenZir(),
3516 .src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]],3517 .src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]],
3517 };3518 };
35183519
...@@ -3808,33 +3809,42 @@ fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {...@@ -3808,33 +3809,42 @@ fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
3808/// result locations must call this function on their result.3809/// result locations must call this function on their result.
3809/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.3810/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.
3810/// If the `ResultLoc` is `ty`, it will coerce the result to the type.3811/// If the `ResultLoc` is `ty`, it will coerce the result to the type.
3811fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerError!*zir.Inst {3812fn rvalue(
3813 mod: *Module,
3814 scope: *Scope,
3815 rl: ResultLoc,
3816 result: zir.Inst.Ref,
3817 src_node: ast.Node.Index,
3818) InnerError!zir.Inst.Ref {
3819 const gz = scope.getGenZir();
3812 switch (rl) {3820 switch (rl) {
3813 .none => return result,3821 .none => return result,
3814 .discard => {3822 .discard => {
3815 // Emit a compile error for discarding error values.3823 // Emit a compile error for discarding error values.
3816 _ = try addZIRUnOp(mod, scope, result.src, .ensure_result_non_error, result);3824 _ = try gz.addUnNode(.ensure_result_non_error, result, src_node);
3817 return result;3825 return result;
3818 },3826 },
3819 .ref => {3827 .ref => {
3820 // We need a pointer but we have a value.3828 // We need a pointer but we have a value.
3821 return addZIRUnOp(mod, scope, result.src, .ref, result);3829 const tree = scope.tree();
3830 const src_token = tree.firstToken(src_node);
3831 return gz.addUnTok(.ref, result, src_tok);
3822 },3832 },
3823 .ty => |ty_inst| return addZIRBinOp(mod, scope, result.src, .as, ty_inst, result),3833 .ty => |ty_inst| return gz.addBin(.as, ty_inst, result),
3824 .ptr => |ptr_inst| {3834 .ptr => |ptr_inst| {
3825 _ = try addZIRBinOp(mod, scope, result.src, .store, ptr_inst, result);3835 _ = try gz.addBin(.store, ptr_inst, result);
3826 return result;3836 return result;
3827 },3837 },
3828 .bitcasted_ptr => |bitcasted_ptr| {3838 .bitcasted_ptr => |bitcasted_ptr| {
3829 return mod.fail(scope, result.src, "TODO implement rvalue .bitcasted_ptr", .{});3839 return mod.failNode(scope, src_node, "TODO implement rvalue .bitcasted_ptr", .{});
3830 },3840 },
3831 .inferred_ptr => |alloc| {3841 .inferred_ptr => |alloc| {
3832 _ = try addZIRBinOp(mod, scope, result.src, .store_to_inferred_ptr, &alloc.base, result);3842 _ = try gz.addBin(.store_to_inferred_ptr, alloc, result);
3833 return result;3843 return result;
3834 },3844 },
3835 .block_ptr => |block_scope| {3845 .block_ptr => |block_scope| {
3836 block_scope.rvalue_rl_count += 1;3846 block_scope.rvalue_rl_count += 1;
3837 _ = try addZIRBinOp(mod, scope, result.src, .store_to_block_ptr, block_scope.rl_ptr.?, result);3847 _ = try gz.addBin(.store_to_block_ptr, block_scope.rl_ptr.?, result);
3838 return result;3848 return result;
3839 },3849 },
3840 }3850 }
src/codegen.zig+21-21
...@@ -17,6 +17,7 @@ const DW = std.dwarf;...@@ -17,6 +17,7 @@ const DW = std.dwarf;
17const leb128 = std.leb;17const leb128 = std.leb;
18const log = std.log.scoped(.codegen);18const log = std.log.scoped(.codegen);
19const build_options = @import("build_options");19const build_options = @import("build_options");
20const LazySrcLoc = Module.LazySrcLoc;
2021
21/// The codegen-related data that is stored in `ir.Inst.Block` instructions.22/// The codegen-related data that is stored in `ir.Inst.Block` instructions.
22pub const BlockData = struct {23pub const BlockData = struct {
...@@ -978,7 +979,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -978,7 +979,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
978 /// Copies a value to a register without tracking the register. The register is not considered979 /// Copies a value to a register without tracking the register. The register is not considered
979 /// allocated. A second call to `copyToTmpRegister` may return the same register.980 /// allocated. A second call to `copyToTmpRegister` may return the same register.
980 /// This can have a side effect of spilling instructions to the stack to free up a register.981 /// This can have a side effect of spilling instructions to the stack to free up a register.
981 fn copyToTmpRegister(self: *Self, src: usize, ty: Type, mcv: MCValue) !Register {982 fn copyToTmpRegister(self: *Self, src: LazySrcLoc, ty: Type, mcv: MCValue) !Register {
982 const reg = self.findUnusedReg() orelse b: {983 const reg = self.findUnusedReg() orelse b: {
983 // We'll take over the first register. Move the instruction that was previously984 // We'll take over the first register. Move the instruction that was previously
984 // there to a stack allocation.985 // there to a stack allocation.
...@@ -1457,7 +1458,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1457,7 +1458,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
14571458
1458 fn genArmBinOpCode(1459 fn genArmBinOpCode(
1459 self: *Self,1460 self: *Self,
1460 src: usize,1461 src: LazySrcLoc,
1461 dst_reg: Register,1462 dst_reg: Register,
1462 lhs_mcv: MCValue,1463 lhs_mcv: MCValue,
1463 rhs_mcv: MCValue,1464 rhs_mcv: MCValue,
...@@ -1620,7 +1621,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1620,7 +1621,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
16201621
1621 fn genX8664BinMathCode(1622 fn genX8664BinMathCode(
1622 self: *Self,1623 self: *Self,
1623 src: usize,1624 src: LazySrcLoc,
1624 dst_ty: Type,1625 dst_ty: Type,
1625 dst_mcv: MCValue,1626 dst_mcv: MCValue,
1626 src_mcv: MCValue,1627 src_mcv: MCValue,
...@@ -1706,7 +1707,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1706,7 +1707,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1706 }1707 }
1707 }1708 }
17081709
1709 fn genX8664ModRMRegToStack(self: *Self, src: usize, ty: Type, off: u32, reg: Register, opcode: u8) !void {1710 fn genX8664ModRMRegToStack(self: *Self, src: LazySrcLoc, ty: Type, off: u32, reg: Register, opcode: u8) !void {
1710 const abi_size = ty.abiSize(self.target.*);1711 const abi_size = ty.abiSize(self.target.*);
1711 const adj_off = off + abi_size;1712 const adj_off = off + abi_size;
1712 try self.code.ensureCapacity(self.code.items.len + 7);1713 try self.code.ensureCapacity(self.code.items.len + 7);
...@@ -1807,7 +1808,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1807,7 +1808,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1807 return result;1808 return result;
1808 }1809 }
18091810
1810 fn genBreakpoint(self: *Self, src: usize) !MCValue {1811 fn genBreakpoint(self: *Self, src: LazySrcLoc) !MCValue {
1811 switch (arch) {1812 switch (arch) {
1812 .i386, .x86_64 => {1813 .i386, .x86_64 => {
1813 try self.code.append(0xcc); // int31814 try self.code.append(0xcc); // int3
...@@ -2221,7 +2222,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2221,7 +2222,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2221 }2222 }
2222 }2223 }
22232224
2224 fn ret(self: *Self, src: usize, mcv: MCValue) !MCValue {2225 fn ret(self: *Self, src: LazySrcLoc, mcv: MCValue) !MCValue {
2225 const ret_ty = self.fn_type.fnReturnType();2226 const ret_ty = self.fn_type.fnReturnType();
2226 try self.setRegOrMem(src, ret_ty, self.ret_mcv, mcv);2227 try self.setRegOrMem(src, ret_ty, self.ret_mcv, mcv);
2227 switch (arch) {2228 switch (arch) {
...@@ -2558,7 +2559,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2558,7 +2559,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2558 }2559 }
25592560
2560 /// Send control flow to the `index` of `self.code`.2561 /// Send control flow to the `index` of `self.code`.
2561 fn jump(self: *Self, src: usize, index: usize) !void {2562 fn jump(self: *Self, src: LazySrcLoc, index: usize) !void {
2562 switch (arch) {2563 switch (arch) {
2563 .i386, .x86_64 => {2564 .i386, .x86_64 => {
2564 try self.code.ensureCapacity(self.code.items.len + 5);2565 try self.code.ensureCapacity(self.code.items.len + 5);
...@@ -2615,7 +2616,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2615,7 +2616,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2615 }2616 }
2616 }2617 }
26172618
2618 fn performReloc(self: *Self, src: usize, reloc: Reloc) !void {2619 fn performReloc(self: *Self, src: LazySrcLoc, reloc: Reloc) !void {
2619 switch (reloc) {2620 switch (reloc) {
2620 .rel32 => |pos| {2621 .rel32 => |pos| {
2621 const amt = self.code.items.len - (pos + 4);2622 const amt = self.code.items.len - (pos + 4);
...@@ -2679,7 +2680,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2679,7 +2680,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2679 }2680 }
2680 }2681 }
26812682
2682 fn br(self: *Self, src: usize, block: *ir.Inst.Block, operand: *ir.Inst) !MCValue {2683 fn br(self: *Self, src: LazySrcLoc, block: *ir.Inst.Block, operand: *ir.Inst) !MCValue {
2683 if (operand.ty.hasCodeGenBits()) {2684 if (operand.ty.hasCodeGenBits()) {
2684 const operand_mcv = try self.resolveInst(operand);2685 const operand_mcv = try self.resolveInst(operand);
2685 const block_mcv = @bitCast(MCValue, block.codegen.mcv);2686 const block_mcv = @bitCast(MCValue, block.codegen.mcv);
...@@ -2692,7 +2693,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2692,7 +2693,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2692 return self.brVoid(src, block);2693 return self.brVoid(src, block);
2693 }2694 }
26942695
2695 fn brVoid(self: *Self, src: usize, block: *ir.Inst.Block) !MCValue {2696 fn brVoid(self: *Self, src: LazySrcLoc, block: *ir.Inst.Block) !MCValue {
2696 // Emit a jump with a relocation. It will be patched up after the block ends.2697 // Emit a jump with a relocation. It will be patched up after the block ends.
2697 try block.codegen.relocs.ensureCapacity(self.gpa, block.codegen.relocs.items.len + 1);2698 try block.codegen.relocs.ensureCapacity(self.gpa, block.codegen.relocs.items.len + 1);
26982699
...@@ -2896,7 +2897,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2896,7 +2897,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2896 }2897 }
28972898
2898 /// Sets the value without any modifications to register allocation metadata or stack allocation metadata.2899 /// Sets the value without any modifications to register allocation metadata or stack allocation metadata.
2899 fn setRegOrMem(self: *Self, src: usize, ty: Type, loc: MCValue, val: MCValue) !void {2900 fn setRegOrMem(self: *Self, src: LazySrcLoc, ty: Type, loc: MCValue, val: MCValue) !void {
2900 switch (loc) {2901 switch (loc) {
2901 .none => return,2902 .none => return,
2902 .register => |reg| return self.genSetReg(src, ty, reg, val),2903 .register => |reg| return self.genSetReg(src, ty, reg, val),
...@@ -2908,7 +2909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2908,7 +2909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2908 }2909 }
2909 }2910 }
29102911
2911 fn genSetStack(self: *Self, src: usize, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {2912 fn genSetStack(self: *Self, src: LazySrcLoc, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
2912 switch (arch) {2913 switch (arch) {
2913 .arm, .armeb => switch (mcv) {2914 .arm, .armeb => switch (mcv) {
2914 .dead => unreachable,2915 .dead => unreachable,
...@@ -3111,7 +3112,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3111,7 +3112,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3111 4, 8 => {3112 4, 8 => {
3112 const offset = if (math.cast(i9, adj_off)) |imm|3113 const offset = if (math.cast(i9, adj_off)) |imm|
3113 Instruction.LoadStoreOffset.imm_post_index(-imm)3114 Instruction.LoadStoreOffset.imm_post_index(-imm)
3114 else |_| Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, Type.initTag(.u64), MCValue{ .immediate = adj_off }));3115 else |_|
3116 Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, Type.initTag(.u64), MCValue{ .immediate = adj_off }));
3115 const rn: Register = switch (arch) {3117 const rn: Register = switch (arch) {
3116 .aarch64, .aarch64_be => .x29,3118 .aarch64, .aarch64_be => .x29,
3117 .aarch64_32 => .w29,3119 .aarch64_32 => .w29,
...@@ -3140,7 +3142,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3140,7 +3142,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3140 }3142 }
3141 }3143 }
31423144
3143 fn genSetReg(self: *Self, src: usize, ty: Type, reg: Register, mcv: MCValue) InnerError!void {3145 fn genSetReg(self: *Self, src: LazySrcLoc, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3144 switch (arch) {3146 switch (arch) {
3145 .arm, .armeb => switch (mcv) {3147 .arm, .armeb => switch (mcv) {
3146 .dead => unreachable,3148 .dead => unreachable,
...@@ -3762,7 +3764,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3762,7 +3764,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3762 return mcv;3764 return mcv;
3763 }3765 }
37643766
3765 fn genTypedValue(self: *Self, src: usize, typed_value: TypedValue) InnerError!MCValue {3767 fn genTypedValue(self: *Self, src: LazySrcLoc, typed_value: TypedValue) InnerError!MCValue {
3766 if (typed_value.val.isUndef())3768 if (typed_value.val.isUndef())
3767 return MCValue{ .undef = {} };3769 return MCValue{ .undef = {} };
3768 const ptr_bits = self.target.cpu.arch.ptrBitWidth();3770 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
...@@ -3835,7 +3837,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3835,7 +3837,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3835 };3837 };
38363838
3837 /// Caller must call `CallMCValues.deinit`.3839 /// Caller must call `CallMCValues.deinit`.
3838 fn resolveCallingConventionValues(self: *Self, src: usize, fn_ty: Type) !CallMCValues {3840 fn resolveCallingConventionValues(self: *Self, src: LazySrcLoc, fn_ty: Type) !CallMCValues {
3839 const cc = fn_ty.fnCallingConvention();3841 const cc = fn_ty.fnCallingConvention();
3840 const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen());3842 const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen());
3841 defer self.gpa.free(param_types);3843 defer self.gpa.free(param_types);
...@@ -4049,13 +4051,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4049,13 +4051,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4049 };4051 };
4050 }4052 }
40514053
4052 fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) InnerError {4054 fn fail(self: *Self, src: LazySrcLoc, comptime format: []const u8, args: anytype) InnerError {
4053 @setCold(true);4055 @setCold(true);
4054 assert(self.err_msg == null);4056 assert(self.err_msg == null);
4055 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, .{4057 const src_loc = src.toSrcLocWithDecl(self.mod_fn.owner_decl);
4056 .file_scope = self.src_loc.file_scope,4058 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, src_loc, format, args);
4057 .byte_offset = src,
4058 }, format, args);
4059 return error.CodegenFail;4059 return error.CodegenFail;
4060 }4060 }
40614061
src/ir.zig+21-15
...@@ -591,7 +591,7 @@ pub const Body = struct {...@@ -591,7 +591,7 @@ pub const Body = struct {
591};591};
592592
593/// For debugging purposes, prints a function representation to stderr.593/// For debugging purposes, prints a function representation to stderr.
594pub fn dumpFn(old_module: IrModule, module_fn: *IrModule.Fn) void {594pub fn dumpFn(old_module: Module, module_fn: *Module.Fn) void {
595 const allocator = old_module.gpa;595 const allocator = old_module.gpa;
596 var ctx: DumpTzir = .{596 var ctx: DumpTzir = .{
597 .allocator = allocator,597 .allocator = allocator,
...@@ -622,10 +622,10 @@ pub fn dumpFn(old_module: IrModule, module_fn: *IrModule.Fn) void {...@@ -622,10 +622,10 @@ pub fn dumpFn(old_module: IrModule, module_fn: *IrModule.Fn) void {
622}622}
623623
624const DumpTzir = struct {624const DumpTzir = struct {
625 allocator: *Allocator,625 allocator: *std.mem.Allocator,
626 arena: std.heap.ArenaAllocator,626 arena: std.heap.ArenaAllocator,
627 old_module: *const IrModule,627 old_module: *const Module,
628 module_fn: *IrModule.Fn,628 module_fn: *Module.Fn,
629 indent: usize,629 indent: usize,
630 inst_table: InstTable,630 inst_table: InstTable,
631 partial_inst_table: InstTable,631 partial_inst_table: InstTable,
...@@ -634,12 +634,12 @@ const DumpTzir = struct {...@@ -634,12 +634,12 @@ const DumpTzir = struct {
634 next_partial_index: usize = 0,634 next_partial_index: usize = 0,
635 next_const_index: usize = 0,635 next_const_index: usize = 0,
636636
637 const InstTable = std.AutoArrayHashMap(*ir.Inst, usize);637 const InstTable = std.AutoArrayHashMap(*Inst, usize);
638638
639 /// TODO: Improve this code to include a stack of ir.Body and store the instructions639 /// TODO: Improve this code to include a stack of Body and store the instructions
640 /// in there. Now we are putting all the instructions in a function local table,640 /// in there. Now we are putting all the instructions in a function local table,
641 /// however instructions that are in a Body can be thown away when the Body ends.641 /// however instructions that are in a Body can be thown away when the Body ends.
642 fn dump(dtz: *DumpTzir, body: ir.Body, writer: std.fs.File.Writer) !void {642 fn dump(dtz: *DumpTzir, body: Body, writer: std.fs.File.Writer) !void {
643 // First pass to pre-populate the table so that we can show even invalid references.643 // First pass to pre-populate the table so that we can show even invalid references.
644 // Must iterate the same order we iterate the second time.644 // Must iterate the same order we iterate the second time.
645 // We also look for constants and put them in the const_table.645 // We also look for constants and put them in the const_table.
...@@ -657,7 +657,7 @@ const DumpTzir = struct {...@@ -657,7 +657,7 @@ const DumpTzir = struct {
657 return dtz.dumpBody(body, writer);657 return dtz.dumpBody(body, writer);
658 }658 }
659659
660 fn fetchInstsAndResolveConsts(dtz: *DumpTzir, body: ir.Body) error{OutOfMemory}!void {660 fn fetchInstsAndResolveConsts(dtz: *DumpTzir, body: Body) error{OutOfMemory}!void {
661 for (body.instructions) |inst| {661 for (body.instructions) |inst| {
662 try dtz.inst_table.put(inst, dtz.next_index);662 try dtz.inst_table.put(inst, dtz.next_index);
663 dtz.next_index += 1;663 dtz.next_index += 1;
...@@ -694,13 +694,16 @@ const DumpTzir = struct {...@@ -694,13 +694,16 @@ const DumpTzir = struct {
694 .unwrap_errunion_payload_ptr,694 .unwrap_errunion_payload_ptr,
695 .unwrap_errunion_err_ptr,695 .unwrap_errunion_err_ptr,
696 => {696 => {
697 const un_op = inst.cast(ir.Inst.UnOp).?;697 const un_op = inst.cast(Inst.UnOp).?;
698 try dtz.findConst(un_op.operand);698 try dtz.findConst(un_op.operand);
699 },699 },
700700
701 .add,701 .add,
702 .addwrap,
702 .sub,703 .sub,
704 .subwrap,
703 .mul,705 .mul,
706 .mulwrap,
704 .cmp_lt,707 .cmp_lt,
705 .cmp_lte,708 .cmp_lte,
706 .cmp_eq,709 .cmp_eq,
...@@ -714,7 +717,7 @@ const DumpTzir = struct {...@@ -714,7 +717,7 @@ const DumpTzir = struct {
714 .bit_or,717 .bit_or,
715 .xor,718 .xor,
716 => {719 => {
717 const bin_op = inst.cast(ir.Inst.BinOp).?;720 const bin_op = inst.cast(Inst.BinOp).?;
718 try dtz.findConst(bin_op.lhs);721 try dtz.findConst(bin_op.lhs);
719 try dtz.findConst(bin_op.rhs);722 try dtz.findConst(bin_op.rhs);
720 },723 },
...@@ -770,7 +773,7 @@ const DumpTzir = struct {...@@ -770,7 +773,7 @@ const DumpTzir = struct {
770 }773 }
771 }774 }
772775
773 fn dumpBody(dtz: *DumpTzir, body: ir.Body, writer: std.fs.File.Writer) (std.fs.File.WriteError || error{OutOfMemory})!void {776 fn dumpBody(dtz: *DumpTzir, body: Body, writer: std.fs.File.Writer) (std.fs.File.WriteError || error{OutOfMemory})!void {
774 for (body.instructions) |inst| {777 for (body.instructions) |inst| {
775 const my_index = dtz.next_partial_index;778 const my_index = dtz.next_partial_index;
776 try dtz.partial_inst_table.put(inst, my_index);779 try dtz.partial_inst_table.put(inst, my_index);
...@@ -812,7 +815,7 @@ const DumpTzir = struct {...@@ -812,7 +815,7 @@ const DumpTzir = struct {
812 .unwrap_errunion_payload_ptr,815 .unwrap_errunion_payload_ptr,
813 .unwrap_errunion_err_ptr,816 .unwrap_errunion_err_ptr,
814 => {817 => {
815 const un_op = inst.cast(ir.Inst.UnOp).?;818 const un_op = inst.cast(Inst.UnOp).?;
816 const kinky = try dtz.writeInst(writer, un_op.operand);819 const kinky = try dtz.writeInst(writer, un_op.operand);
817 if (kinky != null) {820 if (kinky != null) {
818 try writer.writeAll(") // Instruction does not dominate all uses!\n");821 try writer.writeAll(") // Instruction does not dominate all uses!\n");
...@@ -822,8 +825,11 @@ const DumpTzir = struct {...@@ -822,8 +825,11 @@ const DumpTzir = struct {
822 },825 },
823826
824 .add,827 .add,
828 .addwrap,
825 .sub,829 .sub,
830 .subwrap,
826 .mul,831 .mul,
832 .mulwrap,
827 .cmp_lt,833 .cmp_lt,
828 .cmp_lte,834 .cmp_lte,
829 .cmp_eq,835 .cmp_eq,
...@@ -837,7 +843,7 @@ const DumpTzir = struct {...@@ -837,7 +843,7 @@ const DumpTzir = struct {
837 .bit_or,843 .bit_or,
838 .xor,844 .xor,
839 => {845 => {
840 const bin_op = inst.cast(ir.Inst.BinOp).?;846 const bin_op = inst.cast(Inst.BinOp).?;
841847
842 const lhs_kinky = try dtz.writeInst(writer, bin_op.lhs);848 const lhs_kinky = try dtz.writeInst(writer, bin_op.lhs);
843 try writer.writeAll(", ");849 try writer.writeAll(", ");
...@@ -1008,7 +1014,7 @@ const DumpTzir = struct {...@@ -1008,7 +1014,7 @@ const DumpTzir = struct {
1008 }1014 }
1009 }1015 }
10101016
1011 fn writeInst(dtz: *DumpTzir, writer: std.fs.File.Writer, inst: *ir.Inst) !?usize {1017 fn writeInst(dtz: *DumpTzir, writer: std.fs.File.Writer, inst: *Inst) !?usize {
1012 if (dtz.partial_inst_table.get(inst)) |operand_index| {1018 if (dtz.partial_inst_table.get(inst)) |operand_index| {
1013 try writer.print("%{d}", .{operand_index});1019 try writer.print("%{d}", .{operand_index});
1014 return null;1020 return null;
...@@ -1024,7 +1030,7 @@ const DumpTzir = struct {...@@ -1024,7 +1030,7 @@ const DumpTzir = struct {
1024 }1030 }
1025 }1031 }
10261032
1027 fn findConst(dtz: *DumpTzir, operand: *ir.Inst) !void {1033 fn findConst(dtz: *DumpTzir, operand: *Inst) !void {
1028 if (operand.tag == .constant) {1034 if (operand.tag == .constant) {
1029 try dtz.const_table.put(operand, dtz.next_const_index);1035 try dtz.const_table.put(operand, dtz.next_const_index);
1030 dtz.next_const_index += 1;1036 dtz.next_const_index += 1;
src/link/Coff.zig+1-1
...@@ -727,7 +727,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {...@@ -727,7 +727,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {
727 self.offset_table_free_list.append(self.base.allocator, decl.link.coff.offset_table_index) catch {};727 self.offset_table_free_list.append(self.base.allocator, decl.link.coff.offset_table_index) catch {};
728}728}
729729
730pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, exports: []const *Module.Export) !void {730pub fn updateDeclExports(self: *Coff, module: *Module, decl: *Module.Decl, exports: []const *Module.Export) !void {
731 if (self.llvm_ir_module) |_| return;731 if (self.llvm_ir_module) |_| return;
732732
733 for (exports) |exp| {733 for (exports) |exp| {
src/link/Elf.zig+1-1
...@@ -2670,7 +2670,7 @@ fn writeDeclDebugInfo(self: *Elf, text_block: *TextBlock, dbg_info_buf: []const...@@ -2670,7 +2670,7 @@ fn writeDeclDebugInfo(self: *Elf, text_block: *TextBlock, dbg_info_buf: []const
2670pub fn updateDeclExports(2670pub fn updateDeclExports(
2671 self: *Elf,2671 self: *Elf,
2672 module: *Module,2672 module: *Module,
2673 decl: *const Module.Decl,2673 decl: *Module.Decl,
2674 exports: []const *Module.Export,2674 exports: []const *Module.Export,
2675) !void {2675) !void {
2676 if (self.llvm_ir_module) |_| return;2676 if (self.llvm_ir_module) |_| return;
src/link/MachO.zig+2-2
...@@ -834,7 +834,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {...@@ -834,7 +834,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
834 }834 }
835 },835 },
836 else => {836 else => {
837 log.err("{s} terminated", .{ argv.items[0] });837 log.err("{s} terminated", .{argv.items[0]});
838 return error.LLDCrashed;838 return error.LLDCrashed;
839 },839 },
840 }840 }
...@@ -1323,7 +1323,7 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.D...@@ -1323,7 +1323,7 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.D
1323pub fn updateDeclExports(1323pub fn updateDeclExports(
1324 self: *MachO,1324 self: *MachO,
1325 module: *Module,1325 module: *Module,
1326 decl: *const Module.Decl,1326 decl: *Module.Decl,
1327 exports: []const *Module.Export,1327 exports: []const *Module.Export,
1328) !void {1328) !void {
1329 const tracy = trace(@src());1329 const tracy = trace(@src());
src/type.zig+3-100
...@@ -94,9 +94,7 @@ pub const Type = extern union {...@@ -94,9 +94,7 @@ pub const Type = extern union {
9494
95 .anyframe_T, .@"anyframe" => return .AnyFrame,95 .anyframe_T, .@"anyframe" => return .AnyFrame,
9696
97 .@"struct", .empty_struct => return .Struct,97 .empty_struct => return .Struct,
98 .@"enum" => return .Enum,
99 .@"union" => return .Union,
10098
101 .var_args_param => unreachable, // can be any type99 .var_args_param => unreachable, // can be any type
102 }100 }
...@@ -484,9 +482,6 @@ pub const Type = extern union {...@@ -484,9 +482,6 @@ pub const Type = extern union {
484 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),482 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
485 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),483 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
486484
487 .@"enum" => return self.copyPayloadShallow(allocator, Payload.Enum),
488 .@"struct" => return self.copyPayloadShallow(allocator, Payload.Struct),
489 .@"union" => return self.copyPayloadShallow(allocator, Payload.Union),
490 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),485 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
491 }486 }
492 }487 }
...@@ -725,9 +720,6 @@ pub const Type = extern union {...@@ -725,9 +720,6 @@ pub const Type = extern union {
725 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),720 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),
726 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),721 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),
727 // TODO use declaration name722 // TODO use declaration name
728 .@"enum" => return out_stream.writeAll("enum {}"),
729 .@"struct" => return out_stream.writeAll("struct {}"),
730 .@"union" => return out_stream.writeAll("union {}"),
731 .@"opaque" => return out_stream.writeAll("opaque {}"),723 .@"opaque" => return out_stream.writeAll("opaque {}"),
732 }724 }
733 unreachable;725 unreachable;
...@@ -839,10 +831,6 @@ pub const Type = extern union {...@@ -839,10 +831,6 @@ pub const Type = extern union {
839 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();831 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
840 },832 },
841833
842 .@"enum" => @panic("TODO"),
843 .@"struct" => @panic("TODO"),
844 .@"union" => @panic("TODO"),
845
846 .c_void,834 .c_void,
847 .void,835 .void,
848 .type,836 .type,
...@@ -864,7 +852,7 @@ pub const Type = extern union {...@@ -864,7 +852,7 @@ pub const Type = extern union {
864852
865 pub fn isNoReturn(self: Type) bool {853 pub fn isNoReturn(self: Type) bool {
866 const definitely_correct_result = self.zigTypeTag() == .NoReturn;854 const definitely_correct_result = self.zigTypeTag() == .NoReturn;
867 const fast_result = self.tag_if_small_enough == Tag.noreturn;855 const fast_result = self.tag_if_small_enough == @enumToInt(Tag.noreturn);
868 assert(fast_result == definitely_correct_result);856 assert(fast_result == definitely_correct_result);
869 return fast_result;857 return fast_result;
870 }858 }
...@@ -970,10 +958,6 @@ pub const Type = extern union {...@@ -970,10 +958,6 @@ pub const Type = extern union {
970 @panic("TODO abiAlignment error union");958 @panic("TODO abiAlignment error union");
971 },959 },
972960
973 .@"enum" => self.cast(Payload.Enum).?.abiAlignment(target),
974 .@"struct" => @panic("TODO"),
975 .@"union" => @panic("TODO"),
976
977 .c_void,961 .c_void,
978 .void,962 .void,
979 .type,963 .type,
...@@ -1122,10 +1106,6 @@ pub const Type = extern union {...@@ -1122,10 +1106,6 @@ pub const Type = extern union {
1122 }1106 }
1123 @panic("TODO abiSize error union");1107 @panic("TODO abiSize error union");
1124 },1108 },
1125
1126 .@"enum" => @panic("TODO"),
1127 .@"struct" => @panic("TODO"),
1128 .@"union" => @panic("TODO"),
1129 };1109 };
1130 }1110 }
11311111
...@@ -1195,9 +1175,6 @@ pub const Type = extern union {...@@ -1195,9 +1175,6 @@ pub const Type = extern union {
1195 .error_set,1175 .error_set,
1196 .error_set_single,1176 .error_set_single,
1197 .empty_struct,1177 .empty_struct,
1198 .@"enum",
1199 .@"struct",
1200 .@"union",
1201 .@"opaque",1178 .@"opaque",
1202 .var_args_param,1179 .var_args_param,
1203 => false,1180 => false,
...@@ -1273,9 +1250,6 @@ pub const Type = extern union {...@@ -1273,9 +1250,6 @@ pub const Type = extern union {
1273 .error_set,1250 .error_set,
1274 .error_set_single,1251 .error_set_single,
1275 .empty_struct,1252 .empty_struct,
1276 .@"enum",
1277 .@"struct",
1278 .@"union",
1279 .@"opaque",1253 .@"opaque",
1280 .var_args_param,1254 .var_args_param,
1281 => unreachable,1255 => unreachable,
...@@ -1372,9 +1346,6 @@ pub const Type = extern union {...@@ -1372,9 +1346,6 @@ pub const Type = extern union {
1372 .empty_struct,1346 .empty_struct,
1373 .inferred_alloc_const,1347 .inferred_alloc_const,
1374 .inferred_alloc_mut,1348 .inferred_alloc_mut,
1375 .@"enum",
1376 .@"struct",
1377 .@"union",
1378 .@"opaque",1349 .@"opaque",
1379 .var_args_param,1350 .var_args_param,
1380 => false,1351 => false,
...@@ -1453,9 +1424,6 @@ pub const Type = extern union {...@@ -1453,9 +1424,6 @@ pub const Type = extern union {
1453 .empty_struct,1424 .empty_struct,
1454 .inferred_alloc_const,1425 .inferred_alloc_const,
1455 .inferred_alloc_mut,1426 .inferred_alloc_mut,
1456 .@"enum",
1457 .@"struct",
1458 .@"union",
1459 .@"opaque",1427 .@"opaque",
1460 .var_args_param,1428 .var_args_param,
1461 => false,1429 => false,
...@@ -1543,9 +1511,6 @@ pub const Type = extern union {...@@ -1543,9 +1511,6 @@ pub const Type = extern union {
1543 .empty_struct,1511 .empty_struct,
1544 .inferred_alloc_const,1512 .inferred_alloc_const,
1545 .inferred_alloc_mut,1513 .inferred_alloc_mut,
1546 .@"enum",
1547 .@"struct",
1548 .@"union",
1549 .@"opaque",1514 .@"opaque",
1550 .var_args_param,1515 .var_args_param,
1551 => false,1516 => false,
...@@ -1628,9 +1593,6 @@ pub const Type = extern union {...@@ -1628,9 +1593,6 @@ pub const Type = extern union {
1628 .empty_struct,1593 .empty_struct,
1629 .inferred_alloc_const,1594 .inferred_alloc_const,
1630 .inferred_alloc_mut,1595 .inferred_alloc_mut,
1631 .@"enum",
1632 .@"struct",
1633 .@"union",
1634 .@"opaque",1596 .@"opaque",
1635 .var_args_param,1597 .var_args_param,
1636 => false,1598 => false,
...@@ -1755,9 +1717,6 @@ pub const Type = extern union {...@@ -1755,9 +1717,6 @@ pub const Type = extern union {
1755 .empty_struct => unreachable,1717 .empty_struct => unreachable,
1756 .inferred_alloc_const => unreachable,1718 .inferred_alloc_const => unreachable,
1757 .inferred_alloc_mut => unreachable,1719 .inferred_alloc_mut => unreachable,
1758 .@"enum" => unreachable,
1759 .@"struct" => unreachable,
1760 .@"union" => unreachable,
1761 .@"opaque" => unreachable,1720 .@"opaque" => unreachable,
1762 .var_args_param => unreachable,1721 .var_args_param => unreachable,
17631722
...@@ -1908,9 +1867,6 @@ pub const Type = extern union {...@@ -1908,9 +1867,6 @@ pub const Type = extern union {
1908 .empty_struct,1867 .empty_struct,
1909 .inferred_alloc_const,1868 .inferred_alloc_const,
1910 .inferred_alloc_mut,1869 .inferred_alloc_mut,
1911 .@"enum",
1912 .@"struct",
1913 .@"union",
1914 .@"opaque",1870 .@"opaque",
1915 .var_args_param,1871 .var_args_param,
1916 => unreachable,1872 => unreachable,
...@@ -1983,9 +1939,6 @@ pub const Type = extern union {...@@ -1983,9 +1939,6 @@ pub const Type = extern union {
1983 .empty_struct,1939 .empty_struct,
1984 .inferred_alloc_const,1940 .inferred_alloc_const,
1985 .inferred_alloc_mut,1941 .inferred_alloc_mut,
1986 .@"enum",
1987 .@"struct",
1988 .@"union",
1989 .@"opaque",1942 .@"opaque",
1990 .var_args_param,1943 .var_args_param,
1991 => unreachable,1944 => unreachable,
...@@ -2073,9 +2026,6 @@ pub const Type = extern union {...@@ -2073,9 +2026,6 @@ pub const Type = extern union {
2073 .empty_struct,2026 .empty_struct,
2074 .inferred_alloc_const,2027 .inferred_alloc_const,
2075 .inferred_alloc_mut,2028 .inferred_alloc_mut,
2076 .@"enum",
2077 .@"struct",
2078 .@"union",
2079 .@"opaque",2029 .@"opaque",
2080 .var_args_param,2030 .var_args_param,
2081 => false,2031 => false,
...@@ -2159,9 +2109,6 @@ pub const Type = extern union {...@@ -2159,9 +2109,6 @@ pub const Type = extern union {
2159 .empty_struct,2109 .empty_struct,
2160 .inferred_alloc_const,2110 .inferred_alloc_const,
2161 .inferred_alloc_mut,2111 .inferred_alloc_mut,
2162 .@"enum",
2163 .@"struct",
2164 .@"union",
2165 .@"opaque",2112 .@"opaque",
2166 .var_args_param,2113 .var_args_param,
2167 => false,2114 => false,
...@@ -2231,9 +2178,6 @@ pub const Type = extern union {...@@ -2231,9 +2178,6 @@ pub const Type = extern union {
2231 .empty_struct,2178 .empty_struct,
2232 .inferred_alloc_const,2179 .inferred_alloc_const,
2233 .inferred_alloc_mut,2180 .inferred_alloc_mut,
2234 .@"enum",
2235 .@"struct",
2236 .@"union",
2237 .@"opaque",2181 .@"opaque",
2238 .var_args_param,2182 .var_args_param,
2239 => unreachable,2183 => unreachable,
...@@ -2331,9 +2275,6 @@ pub const Type = extern union {...@@ -2331,9 +2275,6 @@ pub const Type = extern union {
2331 .empty_struct,2275 .empty_struct,
2332 .inferred_alloc_const,2276 .inferred_alloc_const,
2333 .inferred_alloc_mut,2277 .inferred_alloc_mut,
2334 .@"enum",
2335 .@"struct",
2336 .@"union",
2337 .@"opaque",2278 .@"opaque",
2338 .var_args_param,2279 .var_args_param,
2339 => false,2280 => false,
...@@ -2452,9 +2393,6 @@ pub const Type = extern union {...@@ -2452,9 +2393,6 @@ pub const Type = extern union {
2452 .empty_struct,2393 .empty_struct,
2453 .inferred_alloc_const,2394 .inferred_alloc_const,
2454 .inferred_alloc_mut,2395 .inferred_alloc_mut,
2455 .@"enum",
2456 .@"struct",
2457 .@"union",
2458 .@"opaque",2396 .@"opaque",
2459 .var_args_param,2397 .var_args_param,
2460 => unreachable,2398 => unreachable,
...@@ -2539,9 +2477,6 @@ pub const Type = extern union {...@@ -2539,9 +2477,6 @@ pub const Type = extern union {
2539 .empty_struct,2477 .empty_struct,
2540 .inferred_alloc_const,2478 .inferred_alloc_const,
2541 .inferred_alloc_mut,2479 .inferred_alloc_mut,
2542 .@"enum",
2543 .@"struct",
2544 .@"union",
2545 .@"opaque",2480 .@"opaque",
2546 .var_args_param,2481 .var_args_param,
2547 => unreachable,2482 => unreachable,
...@@ -2625,9 +2560,6 @@ pub const Type = extern union {...@@ -2625,9 +2560,6 @@ pub const Type = extern union {
2625 .empty_struct,2560 .empty_struct,
2626 .inferred_alloc_const,2561 .inferred_alloc_const,
2627 .inferred_alloc_mut,2562 .inferred_alloc_mut,
2628 .@"enum",
2629 .@"struct",
2630 .@"union",
2631 .@"opaque",2563 .@"opaque",
2632 .var_args_param,2564 .var_args_param,
2633 => unreachable,2565 => unreachable,
...@@ -2711,9 +2643,6 @@ pub const Type = extern union {...@@ -2711,9 +2643,6 @@ pub const Type = extern union {
2711 .empty_struct,2643 .empty_struct,
2712 .inferred_alloc_const,2644 .inferred_alloc_const,
2713 .inferred_alloc_mut,2645 .inferred_alloc_mut,
2714 .@"enum",
2715 .@"struct",
2716 .@"union",
2717 .@"opaque",2646 .@"opaque",
2718 .var_args_param,2647 .var_args_param,
2719 => unreachable,2648 => unreachable,
...@@ -2794,9 +2723,6 @@ pub const Type = extern union {...@@ -2794,9 +2723,6 @@ pub const Type = extern union {
2794 .empty_struct,2723 .empty_struct,
2795 .inferred_alloc_const,2724 .inferred_alloc_const,
2796 .inferred_alloc_mut,2725 .inferred_alloc_mut,
2797 .@"enum",
2798 .@"struct",
2799 .@"union",
2800 .@"opaque",2726 .@"opaque",
2801 .var_args_param,2727 .var_args_param,
2802 => unreachable,2728 => unreachable,
...@@ -2877,9 +2803,6 @@ pub const Type = extern union {...@@ -2877,9 +2803,6 @@ pub const Type = extern union {
2877 .empty_struct,2803 .empty_struct,
2878 .inferred_alloc_const,2804 .inferred_alloc_const,
2879 .inferred_alloc_mut,2805 .inferred_alloc_mut,
2880 .@"enum",
2881 .@"struct",
2882 .@"union",
2883 .@"opaque",2806 .@"opaque",
2884 .var_args_param,2807 .var_args_param,
2885 => unreachable,2808 => unreachable,
...@@ -2960,9 +2883,6 @@ pub const Type = extern union {...@@ -2960,9 +2883,6 @@ pub const Type = extern union {
2960 .empty_struct,2883 .empty_struct,
2961 .inferred_alloc_const,2884 .inferred_alloc_const,
2962 .inferred_alloc_mut,2885 .inferred_alloc_mut,
2963 .@"enum",
2964 .@"struct",
2965 .@"union",
2966 .@"opaque",2886 .@"opaque",
2967 .var_args_param,2887 .var_args_param,
2968 => false,2888 => false,
...@@ -3028,10 +2948,6 @@ pub const Type = extern union {...@@ -3028,10 +2948,6 @@ pub const Type = extern union {
3028 .var_args_param,2948 .var_args_param,
3029 => return null,2949 => return null,
30302950
3031 .@"enum" => @panic("TODO onePossibleValue enum"),
3032 .@"struct" => @panic("TODO onePossibleValue struct"),
3033 .@"union" => @panic("TODO onePossibleValue union"),
3034
3035 .empty_struct => return Value.initTag(.empty_struct_value),2951 .empty_struct => return Value.initTag(.empty_struct_value),
3036 .void => return Value.initTag(.void_value),2952 .void => return Value.initTag(.void_value),
3037 .noreturn => return Value.initTag(.unreachable_value),2953 .noreturn => return Value.initTag(.unreachable_value),
...@@ -3139,9 +3055,6 @@ pub const Type = extern union {...@@ -3139,9 +3055,6 @@ pub const Type = extern union {
3139 .empty_struct,3055 .empty_struct,
3140 .inferred_alloc_const,3056 .inferred_alloc_const,
3141 .inferred_alloc_mut,3057 .inferred_alloc_mut,
3142 .@"enum",
3143 .@"struct",
3144 .@"union",
3145 .@"opaque",3058 .@"opaque",
3146 .var_args_param,3059 .var_args_param,
3147 => return false,3060 => return false,
...@@ -3237,9 +3150,6 @@ pub const Type = extern union {...@@ -3237,9 +3150,6 @@ pub const Type = extern union {
3237 => unreachable,3150 => unreachable,
32383151
3239 .empty_struct => self.castTag(.empty_struct).?.data,3152 .empty_struct => self.castTag(.empty_struct).?.data,
3240 .@"enum" => &self.castTag(.@"enum").?.scope,
3241 .@"struct" => &self.castTag(.@"struct").?.scope,
3242 .@"union" => &self.castTag(.@"union").?.scope,
3243 .@"opaque" => &self.castTag(.@"opaque").?.scope,3153 .@"opaque" => &self.castTag(.@"opaque").?.scope,
3244 };3154 };
3245 }3155 }
...@@ -3386,9 +3296,6 @@ pub const Type = extern union {...@@ -3386,9 +3296,6 @@ pub const Type = extern union {
3386 error_set,3296 error_set,
3387 error_set_single,3297 error_set_single,
3388 empty_struct,3298 empty_struct,
3389 @"enum",
3390 @"struct",
3391 @"union",
3392 @"opaque",3299 @"opaque",
33933300
3394 pub const last_no_payload_tag = Tag.inferred_alloc_const;3301 pub const last_no_payload_tag = Tag.inferred_alloc_const;
...@@ -3467,11 +3374,7 @@ pub const Type = extern union {...@@ -3467,11 +3374,7 @@ pub const Type = extern union {
3467 .int_unsigned,3374 .int_unsigned,
3468 => Payload.Bits,3375 => Payload.Bits,
34693376
3470 .error_set,3377 .error_set => Payload.Decl,
3471 .@"enum",
3472 .@"struct",
3473 .@"union",
3474 => Payload.Decl,
34753378
3476 .array => Payload.Array,3379 .array => Payload.Array,
3477 .array_sentinel => Payload.ArraySentinel,3380 .array_sentinel => Payload.ArraySentinel,
src/zir.zig+42-15
...@@ -34,6 +34,7 @@ pub const Code = struct {...@@ -34,6 +34,7 @@ pub const Code = struct {
34 /// The meaning of this data is determined by `Inst.Tag` value.34 /// The meaning of this data is determined by `Inst.Tag` value.
35 extra: []u32,35 extra: []u32,
36 /// First ZIR instruction in this `Code`.36 /// First ZIR instruction in this `Code`.
37 /// `extra` at this index contains a `Ref` for every root member.
37 root_start: Inst.Index,38 root_start: Inst.Index,
38 /// Number of ZIR instructions in the implicit root block of the `Code`.39 /// Number of ZIR instructions in the implicit root block of the `Code`.
39 root_len: u32,40 root_len: u32,
...@@ -358,10 +359,9 @@ pub const Inst = struct {...@@ -358,10 +359,9 @@ pub const Inst = struct {
358 /// Same as `alloc` except mutable.359 /// Same as `alloc` except mutable.
359 alloc_mut,360 alloc_mut,
360 /// Same as `alloc` except the type is inferred.361 /// Same as `alloc` except the type is inferred.
361 /// lhs and rhs unused.362 /// The operand is unused.
362 alloc_inferred,363 alloc_inferred,
363 /// Same as `alloc_inferred` except mutable.364 /// Same as `alloc_inferred` except mutable.
364 /// lhs and rhs unused.
365 alloc_inferred_mut,365 alloc_inferred_mut,
366 /// Create an `anyframe->T`.366 /// Create an `anyframe->T`.
367 /// Uses the `un_node` field. AST node is the `anyframe->T` syntax. Operand is the type.367 /// Uses the `un_node` field. AST node is the `anyframe->T` syntax. Operand is the type.
...@@ -370,9 +370,11 @@ pub const Inst = struct {...@@ -370,9 +370,11 @@ pub const Inst = struct {
370 array_cat,370 array_cat,
371 /// Array multiplication `a ** b`371 /// Array multiplication `a ** b`
372 array_mul,372 array_mul,
373 /// lhs is length, rhs is element type.373 /// `[N]T` syntax. No source location provided.
374 /// Uses the `bin` union field. lhs is length, rhs is element type.
374 array_type,375 array_type,
375 /// lhs is length, ArrayTypeSentinel[rhs]376 /// `[N:S]T` syntax. No source location provided.
377 /// Uses the `array_type_sentinel` field.
376 array_type_sentinel,378 array_type_sentinel,
377 /// Given a pointer to an indexable object, returns the len property. This is379 /// Given a pointer to an indexable object, returns the len property. This is
378 /// used by for loops. This instruction also emits a for-loop specific compile380 /// used by for loops. This instruction also emits a for-loop specific compile
...@@ -407,10 +409,11 @@ pub const Inst = struct {...@@ -407,10 +409,11 @@ pub const Inst = struct {
407 /// Bitwise OR. `|`409 /// Bitwise OR. `|`
408 bit_or,410 bit_or,
409 /// A labeled block of code, which can return a value.411 /// A labeled block of code, which can return a value.
410 /// Uses the `pl_node` union field.412 /// Uses the `pl_node` union field. Payload is `MultiOp`.
411 block,413 block,
412 /// A block of code, which can return a value. There are no instructions that break out of414 /// A block of code, which can return a value. There are no instructions that break out of
413 /// this block; it is implied that the final instruction is the result.415 /// this block; it is implied that the final instruction is the result.
416 /// Uses the `pl_node` union field. Payload is `MultiOp`.
414 block_flat,417 block_flat,
415 /// Same as `block` but additionally makes the inner instructions execute at comptime.418 /// Same as `block` but additionally makes the inner instructions execute at comptime.
416 block_comptime,419 block_comptime,
...@@ -433,7 +436,7 @@ pub const Inst = struct {...@@ -433,7 +436,7 @@ pub const Inst = struct {
433 /// the operand is assumed to be the void value.436 /// the operand is assumed to be the void value.
434 /// Uses the `un_tok` union field.437 /// Uses the `un_tok` union field.
435 break_void_tok,438 break_void_tok,
436 /// lhs and rhs unused.439 /// Uses the `node` union field.
437 breakpoint,440 breakpoint,
438 /// Function call with modifier `.auto`.441 /// Function call with modifier `.auto`.
439 /// Uses `pl_node`. AST node is the function call. Payload is `Call`.442 /// Uses `pl_node`. AST node is the function call. Payload is `Call`.
...@@ -471,8 +474,11 @@ pub const Inst = struct {...@@ -471,8 +474,11 @@ pub const Inst = struct {
471 /// The payload is `MultiOp`.474 /// The payload is `MultiOp`.
472 compile_log,475 compile_log,
473 /// Conditional branch. Splits control flow based on a boolean condition value.476 /// Conditional branch. Splits control flow based on a boolean condition value.
477 /// Uses the `pl_node` union field. AST node is an if, while, for, etc.
478 /// Payload is `CondBr`.
474 condbr,479 condbr,
475 /// Special case, has no textual representation.480 /// Special case, has no textual representation.
481 /// Uses the `const` union field.
476 @"const",482 @"const",
477 /// Declares the beginning of a statement. Used for debug info.483 /// Declares the beginning of a statement. Used for debug info.
478 /// Uses the `node` union field.484 /// Uses the `node` union field.
...@@ -512,7 +518,7 @@ pub const Inst = struct {...@@ -512,7 +518,7 @@ pub const Inst = struct {
512 error_union_type,518 error_union_type,
513 /// Create an error set. extra[lhs..rhs]. The values are token index offsets.519 /// Create an error set. extra[lhs..rhs]. The values are token index offsets.
514 error_set,520 error_set,
515 /// `error.Foo` syntax. uses the `tok` field of the Data union.521 /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.
516 error_value,522 error_value,
517 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer523 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
518 /// to the named field. The field name is stored in string_bytes. Used by a.b syntax.524 /// to the named field. The field name is stored in string_bytes. Used by a.b syntax.
...@@ -532,6 +538,8 @@ pub const Inst = struct {...@@ -532,6 +538,8 @@ pub const Inst = struct {
532 field_val_named,538 field_val_named,
533 /// Convert a larger float type to any other float type, possibly causing539 /// Convert a larger float type to any other float type, possibly causing
534 /// a loss of precision.540 /// a loss of precision.
541 /// Uses the `pl_node` field. AST is the `@floatCast` syntax.
542 /// Payload is `Bin` with lhs as the dest type, rhs the operand.
535 floatcast,543 floatcast,
536 /// Returns a function type, assuming unspecified calling convention.544 /// Returns a function type, assuming unspecified calling convention.
537 /// Uses the `fn_type` union field. `payload_index` points to a `FnType`.545 /// Uses the `fn_type` union field. `payload_index` points to a `FnType`.
...@@ -550,6 +558,8 @@ pub const Inst = struct {...@@ -550,6 +558,8 @@ pub const Inst = struct {
550 int,558 int,
551 /// Convert an integer value to another integer type, asserting that the destination type559 /// Convert an integer value to another integer type, asserting that the destination type
552 /// can hold the same mathematical value.560 /// can hold the same mathematical value.
561 /// Uses the `pl_node` field. AST is the `@intCast` syntax.
562 /// Payload is `Bin` with lhs as the dest type, rhs the operand.
553 intcast,563 intcast,
554 /// Make an integer type out of signedness and bit count.564 /// Make an integer type out of signedness and bit count.
555 /// lhs is signedness, rhs is bit count.565 /// lhs is signedness, rhs is bit count.
...@@ -574,7 +584,8 @@ pub const Inst = struct {...@@ -574,7 +584,8 @@ pub const Inst = struct {
574 is_err_ptr,584 is_err_ptr,
575 /// A labeled block of code that loops forever. At the end of the body it is implied585 /// A labeled block of code that loops forever. At the end of the body it is implied
576 /// to repeat; no explicit "repeat" instruction terminates loop bodies.586 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
577 /// SubRange[lhs..rhs]587 /// Uses the `pl_node` field. The AST node is either a for loop or while loop.
588 /// The payload is `MultiOp`.
578 loop,589 loop,
579 /// Merge two error sets into one, `E1 || E2`.590 /// Merge two error sets into one, `E1 || E2`.
580 merge_error_sets,591 merge_error_sets,
...@@ -677,12 +688,12 @@ pub const Inst = struct {...@@ -677,12 +688,12 @@ pub const Inst = struct {
677 typeof_peer,688 typeof_peer,
678 /// Asserts control-flow will not reach this instruction. Not safety checked - the compiler689 /// Asserts control-flow will not reach this instruction. Not safety checked - the compiler
679 /// will assume the correctness of this instruction.690 /// will assume the correctness of this instruction.
680 /// lhs and rhs unused.691 /// Uses the `node` union field.
681 unreachable_unsafe,692 unreachable_unsafe,
682 /// Asserts control-flow will not reach this instruction. In safety-checked modes,693 /// Asserts control-flow will not reach this instruction. In safety-checked modes,
683 /// this will generate a call to the panic function unless it can be proven unreachable694 /// this will generate a call to the panic function unless it can be proven unreachable
684 /// by the compiler.695 /// by the compiler.
685 /// lhs and rhs unused.696 /// Uses the `node` union field.
686 unreachable_safe,697 unreachable_safe,
687 /// Bitwise XOR. `^`698 /// Bitwise XOR. `^`
688 xor,699 xor,
...@@ -742,7 +753,7 @@ pub const Inst = struct {...@@ -742,7 +753,7 @@ pub const Inst = struct {
742 /// Takes a *E!T and raises a compiler error if T != void753 /// Takes a *E!T and raises a compiler error if T != void
743 /// Uses the `un_tok` field.754 /// Uses the `un_tok` field.
744 ensure_err_payload_void,755 ensure_err_payload_void,
745 /// An enum literal. Uses the `str` union field.756 /// An enum literal. Uses the `str_tok` union field.
746 enum_literal,757 enum_literal,
747 /// Suspend an async function. The suspend block has 0 or 1 statements in it.758 /// Suspend an async function. The suspend block has 0 or 1 statements in it.
748 /// Uses the `un_node` union field.759 /// Uses the `un_node` union field.
...@@ -995,6 +1006,7 @@ pub const Inst = struct {...@@ -995,6 +1006,7 @@ pub const Inst = struct {
995 bin: Bin,1006 bin: Bin,
996 decl: *Module.Decl,1007 decl: *Module.Decl,
997 @"const": *TypedValue,1008 @"const": *TypedValue,
1009 /// For strings which may contain null bytes.
998 str: struct {1010 str: struct {
999 /// Offset into `string_bytes`.1011 /// Offset into `string_bytes`.
1000 start: u32,1012 start: u32,
...@@ -1005,14 +1017,28 @@ pub const Inst = struct {...@@ -1005,14 +1017,28 @@ pub const Inst = struct {
1005 return code.string_bytes[self.start..][0..self.len];1017 return code.string_bytes[self.start..][0..self.len];
1006 }1018 }
1007 },1019 },
1020 str_tok: struct {
1021 /// Offset into `string_bytes`. Null-terminated.
1022 start: u32,
1023 /// Offset from Decl AST token index.
1024 src_tok: u32,
1025
1026 pub fn get(self: @This(), code: Code) [:0]const u8 {
1027 return code.nullTerminatedString(self.start);
1028 }
1029
1030 pub fn src(self: @This()) LazySrcLoc {
1031 return .{ .token_offset = self.src_tok };
1032 }
1033 },
1008 /// Offset from Decl AST token index.1034 /// Offset from Decl AST token index.
1009 tok: ast.TokenIndex,1035 tok: ast.TokenIndex,
1010 /// Offset from Decl AST node index.1036 /// Offset from Decl AST node index.
1011 node: ast.Node.Index,1037 node: ast.Node.Index,
1012 int: u64,1038 int: u64,
1013 condbr: struct {1039 array_type_sentinel: struct {
1014 condition: Ref,1040 len: Ref,
1015 /// index into extra.1041 /// index into extra, points to an `ArrayTypeSentinel`
1016 payload_index: u32,1042 payload_index: u32,
1017 },1043 },
1018 ptr_type_simple: struct {1044 ptr_type_simple: struct {
...@@ -1100,10 +1126,11 @@ pub const Inst = struct {...@@ -1100,10 +1126,11 @@ pub const Inst = struct {
1100 args_len: u32,1126 args_len: u32,
1101 };1127 };
11021128
1103 /// This data is stored inside extra, with two sets of trailing indexes:1129 /// This data is stored inside extra, with two sets of trailing `Ref`:
1104 /// * 0. the then body, according to `then_body_len`.1130 /// * 0. the then body, according to `then_body_len`.
1105 /// * 1. the else body, according to `else_body_len`.1131 /// * 1. the else body, according to `else_body_len`.
1106 pub const CondBr = struct {1132 pub const CondBr = struct {
1133 condition: Ref,
1107 then_body_len: u32,1134 then_body_len: u32,
1108 else_body_len: u32,1135 else_body_len: u32,
1109 };1136 };