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:
1313 * finish implementing SrcLoc byteOffset function
1414 * audit Module.zig for use of token_starts - it should only be when
1515 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
1821Performance optimizations to look into:
......@@ -30,71 +33,6 @@ Random snippets of code that I deleted and need to make sure get
3033re-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
9937 /// Each Decl gets its own string interning, in order to avoid contention when
10038 /// 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
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) {
2222 /// Invalid unicode escape at this index.
2323 invalid_unicode_escape: usize,
2424 /// The left brace at this index is missing a matching right brace.
25 missing_matching_brace: usize,
25 missing_matching_rbrace: usize,
2626 /// Expected unicode digits at this index.
2727 expected_unicode_digits: usize,
2828};
src/Module.zig+307-108
......@@ -237,10 +237,10 @@ pub const Decl = struct {
237237 }
238238 }
239239
240 pub fn srcLoc(decl: *const Decl) SrcLoc {
240 pub fn srcLoc(decl: *Decl) SrcLoc {
241241 return .{
242 .decl = decl,
243 .byte_offset = 0,
242 .container = .{ .decl = decl },
243 .lazy = .{ .node_offset = 0 },
244244 };
245245 }
246246
......@@ -352,7 +352,7 @@ pub const Fn = struct {
352352
353353 /// For debugging purposes.
354354 pub fn dump(func: *Fn, mod: Module) void {
355 zir.dumpFn(mod, func);
355 ir.dumpFn(mod, func);
356356 }
357357};
358358
......@@ -381,12 +381,12 @@ pub const Scope = struct {
381381 /// Returns the arena Allocator associated with the Decl of the Scope.
382382 pub fn arena(scope: *Scope) *Allocator {
383383 switch (scope.tag) {
384 .block => return scope.cast(Block).?.arena,
385 .gen_zir => return scope.cast(GenZir).?.arena,
386 .local_val => return scope.cast(LocalVal).?.gen_zir.arena,
387 .local_ptr => return scope.cast(LocalPtr).?.gen_zir.arena,
388 .gen_suspend => return scope.cast(GenZir).?.arena,
389 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.arena,
384 .block => return scope.cast(Block).?.sema.arena,
385 .gen_zir => return scope.cast(GenZir).?.zir_code.arena,
386 .local_val => return scope.cast(LocalVal).?.gen_zir.zir_code.arena,
387 .local_ptr => return scope.cast(LocalPtr).?.gen_zir.zir_code.arena,
388 .gen_suspend => return scope.cast(GenZir).?.zir_code.arena,
389 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.arena,
390390 .file => unreachable,
391391 .container => unreachable,
392392 .decl_ref => unreachable,
......@@ -399,12 +399,12 @@ pub const Scope = struct {
399399
400400 pub fn ownerDecl(scope: *Scope) ?*Decl {
401401 return switch (scope.tag) {
402 .block => scope.cast(Block).?.owner_decl,
402 .block => scope.cast(Block).?.sema.owner_decl,
403403 .gen_zir => scope.cast(GenZir).?.zir_code.decl,
404 .local_val => scope.cast(LocalVal).?.gen_zir.decl,
405 .local_ptr => scope.cast(LocalPtr).?.gen_zir.decl,
406 .gen_suspend => return scope.cast(GenZir).?.decl,
407 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.decl,
404 .local_val => scope.cast(LocalVal).?.gen_zir.zir_code.decl,
405 .local_ptr => scope.cast(LocalPtr).?.gen_zir.zir_code.decl,
406 .gen_suspend => return scope.cast(GenZir).?.zir_code.decl,
407 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.decl,
408408 .file => null,
409409 .container => null,
410410 .decl_ref => scope.cast(DeclRef).?.decl,
......@@ -415,10 +415,10 @@ pub const Scope = struct {
415415 return switch (scope.tag) {
416416 .block => scope.cast(Block).?.src_decl,
417417 .gen_zir => scope.cast(GenZir).?.zir_code.decl,
418 .local_val => scope.cast(LocalVal).?.gen_zir.decl,
419 .local_ptr => scope.cast(LocalPtr).?.gen_zir.decl,
420 .gen_suspend => return scope.cast(GenZir).?.decl,
421 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.decl,
418 .local_val => scope.cast(LocalVal).?.gen_zir.zir_code.decl,
419 .local_ptr => scope.cast(LocalPtr).?.gen_zir.zir_code.decl,
420 .gen_suspend => return scope.cast(GenZir).?.zir_code.decl,
421 .gen_nosuspend => return scope.cast(Nosuspend).?.gen_zir.zir_code.decl,
422422 .file => null,
423423 .container => null,
424424 .decl_ref => scope.cast(DeclRef).?.decl,
......@@ -463,11 +463,11 @@ pub const Scope = struct {
463463 .file => return &scope.cast(File).?.tree,
464464 .block => return &scope.cast(Block).?.src_decl.container.file_scope.tree,
465465 .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,
467 .local_ptr => return &scope.cast(LocalPtr).?.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.zir_code.decl.container.file_scope.tree,
468468 .container => return &scope.cast(Container).?.file_scope.tree,
469469 .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,
471471 .decl_ref => return &scope.cast(DeclRef).?.decl.container.file_scope.tree,
472472 }
473473 }
......@@ -529,7 +529,7 @@ pub const Scope = struct {
529529 .block => return @fieldParentPtr(Block, "base", cur).src_decl.container.file_scope,
530530 .gen_suspend => @fieldParentPtr(GenZir, "base", cur).parent,
531531 .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,
533533 };
534534 }
535535 }
......@@ -730,11 +730,6 @@ pub const Scope = struct {
730730 pub const Inlining = struct {
731731 /// Shared state among the entire inline/comptime call stack.
732732 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,
738733 merges: Merges,
739734
740735 pub const Shared = struct {
......@@ -762,16 +757,12 @@ pub const Scope = struct {
762757 pub fn makeSubBlock(parent: *Block) Block {
763758 return .{
764759 .parent = parent,
765 .inst_map = parent.inst_map,
766 .func = parent.func,
767 .owner_decl = parent.owner_decl,
760 .sema = parent.sema,
768761 .src_decl = parent.src_decl,
769762 .instructions = .{},
770 .arena = parent.arena,
771763 .label = null,
772764 .inlining = parent.inlining,
773765 .is_comptime = parent.is_comptime,
774 .branch_quota = parent.branch_quota,
775766 };
776767 }
777768
......@@ -795,7 +786,7 @@ pub const Scope = struct {
795786 ty: Type,
796787 comptime tag: ir.Inst.Tag,
797788 ) !*ir.Inst {
798 const inst = try block.arena.create(tag.Type());
789 const inst = try block.sema.arena.create(tag.Type());
799790 inst.* = .{
800791 .base = .{
801792 .tag = tag,
......@@ -814,7 +805,7 @@ pub const Scope = struct {
814805 tag: ir.Inst.Tag,
815806 operand: *ir.Inst,
816807 ) !*ir.Inst {
817 const inst = try block.arena.create(ir.Inst.UnOp);
808 const inst = try block.sema.arena.create(ir.Inst.UnOp);
818809 inst.* = .{
819810 .base = .{
820811 .tag = tag,
......@@ -835,7 +826,7 @@ pub const Scope = struct {
835826 lhs: *ir.Inst,
836827 rhs: *ir.Inst,
837828 ) !*ir.Inst {
838 const inst = try block.arena.create(ir.Inst.BinOp);
829 const inst = try block.sema.arena.create(ir.Inst.BinOp);
839830 inst.* = .{
840831 .base = .{
841832 .tag = tag,
......@@ -854,7 +845,7 @@ pub const Scope = struct {
854845 target_block: *ir.Inst.Block,
855846 operand: *ir.Inst,
856847 ) !*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);
858849 inst.* = .{
859850 .base = .{
860851 .tag = .br,
......@@ -875,7 +866,7 @@ pub const Scope = struct {
875866 then_body: ir.Body,
876867 else_body: ir.Body,
877868 ) !*ir.Inst {
878 const inst = try block.arena.create(ir.Inst.CondBr);
869 const inst = try block.sema.arena.create(ir.Inst.CondBr);
879870 inst.* = .{
880871 .base = .{
881872 .tag = .condbr,
......@@ -897,7 +888,7 @@ pub const Scope = struct {
897888 func: *ir.Inst,
898889 args: []const *ir.Inst,
899890 ) !*ir.Inst {
900 const inst = try block.arena.create(ir.Inst.Call);
891 const inst = try block.sema.arena.create(ir.Inst.Call);
901892 inst.* = .{
902893 .base = .{
903894 .tag = .call,
......@@ -918,7 +909,7 @@ pub const Scope = struct {
918909 cases: []ir.Inst.SwitchBr.Case,
919910 else_body: ir.Body,
920911 ) !*ir.Inst {
921 const inst = try block.arena.create(ir.Inst.SwitchBr);
912 const inst = try block.sema.arena.create(ir.Inst.SwitchBr);
922913 inst.* = .{
923914 .base = .{
924915 .tag = .switchbr,
......@@ -946,7 +937,7 @@ pub const Scope = struct {
946937 zir_code: *WipZirCode,
947938 /// Keeps track of the list of instructions in this scope only. References
948939 /// to instructions in `zir_code`.
949 instructions: std.ArrayListUnmanaged(zir.Inst.Index) = .{},
940 instructions: std.ArrayListUnmanaged(zir.Inst.Ref) = .{},
950941 label: ?Label = null,
951942 break_block: zir.Inst.Index = 0,
952943 continue_block: zir.Inst.Index = 0,
......@@ -978,12 +969,12 @@ pub const Scope = struct {
978969 };
979970
980971 pub fn addFnTypeCc(gz: *GenZir, args: struct {
981 param_types: []const zir.Inst.Index,
982 ret_ty: zir.Inst.Index,
983 cc: zir.Inst.Index,
972 param_types: []const zir.Inst.Ref,
973 ret_ty: zir.Inst.Ref,
974 cc: zir.Inst.Ref,
984975 }) !zir.Inst.Index {
985976 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);
987978 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
988979 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
989980 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);
......@@ -994,7 +985,7 @@ pub const Scope = struct {
994985 }) catch unreachable; // Capacity is ensured above.
995986 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;
998989 gz.zir_code.instructions.appendAssumeCapacity(.{
999990 .tag = .fn_type_cc,
1000991 .data = .{ .fn_type = .{
......@@ -1002,17 +993,18 @@ pub const Scope = struct {
1002993 .payload_index = payload_index,
1003994 } },
1004995 });
1005 gz.instructions.appendAssumeCapacity(new_index);
1006 return new_index;
996 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
997 gz.instructions.appendAssumeCapacity(result);
998 return result;
1007999 }
10081000
10091001 pub fn addFnType(
10101002 gz: *GenZir,
1011 ret_ty: zir.Inst.Index,
1012 param_types: []const zir.Inst.Index,
1003 ret_ty: zir.Inst.Ref,
1004 param_types: []const zir.Inst.Ref,
10131005 ) !zir.Inst.Index {
10141006 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);
10161008 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
10171009 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
10181010 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);
......@@ -1022,7 +1014,7 @@ pub const Scope = struct {
10221014 }) catch unreachable; // Capacity is ensured above.
10231015 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;
10261018 gz.zir_code.instructions.appendAssumeCapacity(.{
10271019 .tag = .fn_type_cc,
10281020 .data = .{ .fn_type = .{
......@@ -1030,29 +1022,118 @@ pub const Scope = struct {
10301022 .payload_index = payload_index,
10311023 } },
10321024 });
1033 gz.instructions.appendAssumeCapacity(new_index);
1034 return new_index;
1025 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1026 gz.instructions.appendAssumeCapacity(result);
1027 return result;
10351028 }
10361029
10371030 pub fn addRetTok(
10381031 gz: *GenZir,
1039 operand: zir.Inst.Index,
1040 src_tok: ast.TokenIndex,
1032 operand: zir.Inst.Ref,
1033 /// Absolute token index. This function does the conversion to Decl offset.
1034 abs_tok_index: ast.TokenIndex,
10411035 ) !zir.Inst.Index {
10421036 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);
10441038 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;
10471041 gz.zir_code.instructions.appendAssumeCapacity(.{
10481042 .tag = .ret_tok,
10491043 .data = .{ .fn_type = .{
10501044 .operand = operand,
1051 .src_tok = src_tok,
1045 .src_tok = abs_tok_index - gz.zir_code.decl.srcToken(),
10521046 } },
10531047 });
1054 gz.instructions.appendAssumeCapacity(new_index);
1055 return new_index;
1048 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_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;
10561137 }
10571138 };
10581139
......@@ -1106,7 +1187,9 @@ pub const WipZirCode = struct {
11061187 instructions: std.MultiArrayList(zir.Inst) = .{},
11071188 string_bytes: std.ArrayListUnmanaged(u8) = .{},
11081189 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,
11101193 decl: *Decl,
11111194 gpa: *Allocator,
11121195 arena: *Allocator,
......@@ -1189,6 +1272,7 @@ pub const SrcLoc = struct {
11891272
11901273 .byte_abs,
11911274 .token_abs,
1275 .node_abs,
11921276 => src_loc.container.file_scope,
11931277
11941278 .byte_offset,
......@@ -1201,6 +1285,13 @@ pub const SrcLoc = struct {
12011285 .node_offset_builtin_call_argn,
12021286 .node_offset_array_access_index,
12031287 .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,
12041295 => src_loc.container.decl.container.file_scope,
12051296 };
12061297 }
......@@ -1218,6 +1309,13 @@ pub const SrcLoc = struct {
12181309 const token_starts = tree.tokens.items(.start);
12191310 return token_starts[tok_index];
12201311 },
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 },
12211319 .byte_offset => |byte_off| {
12221320 const decl = src_loc.container.decl;
12231321 return decl.srcByteOffset() + byte_off;
......@@ -1244,6 +1342,13 @@ pub const SrcLoc = struct {
12441342 .node_offset_builtin_call_argn => unreachable, // Handled specially in `Sema`.
12451343 .node_offset_array_access_index => @panic("TODO"),
12461344 .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"),
12471352 }
12481353 }
12491354};
......@@ -1276,6 +1381,10 @@ pub const LazySrcLoc = union(enum) {
12761381 /// offset from 0. The source file is determined contextually.
12771382 /// Inside a `SrcLoc`, the `file_scope` union field will be active.
12781383 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,
12791388 /// The source location points to a byte offset within a source file,
12801389 /// offset from the byte offset of the Decl within the file.
12811390 /// The Decl is determined contextually.
......@@ -1322,6 +1431,48 @@ pub const LazySrcLoc = union(enum) {
13221431 /// to the sentinel expression.
13231432 /// The Decl is determined contextually.
13241433 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
13261477 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
13271478 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
......@@ -1330,6 +1481,7 @@ pub const LazySrcLoc = union(enum) {
13301481 .todo,
13311482 .byte_abs,
13321483 .token_abs,
1484 .node_abs,
13331485 => .{
13341486 .container = .{ .file_scope = scope.getFileScope() },
13351487 .lazy = lazy,
......@@ -1345,12 +1497,56 @@ pub const LazySrcLoc = union(enum) {
13451497 .node_offset_builtin_call_argn,
13461498 .node_offset_array_access_index,
13471499 .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,
13481507 => .{
13491508 .container = .{ .decl = scope.srcDecl().? },
13501509 .lazy = lazy,
13511510 },
13521511 };
13531512 }
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 }
13541550};
13551551
13561552pub const InnerError = error{ OutOfMemory, AnalysisFail };
......@@ -2255,7 +2451,7 @@ fn astgenAndSemaVarDecl(
22552451 return type_changed;
22562452}
22572453
2258fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void {
2454pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !void {
22592455 try depender.dependencies.ensureCapacity(mod.gpa, depender.dependencies.items().len + 1);
22602456 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
31443340 return mod.decl_table.get(name_hash);
31453341}
31463342
3147fn makeIntType(mod: *Module, scope: *Scope, signed: bool, bits: u16) !Type {
3148 const int_payload = try scope.arena().create(Type.Payload.Bits);
3343pub fn makeIntType(arena: *Allocator, signed: bool, bits: u16) !Type {
3344 const int_payload = try arena.create(Type.Payload.Bits);
31493345 int_payload.* = .{
31503346 .base = .{
31513347 .tag = if (signed) .int_signed else .int_unsigned,
......@@ -3252,45 +3448,51 @@ pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) In
32523448 if (inlining.shared.caller) |func| {
32533449 func.state = .sema_failure;
32543450 } else {
3255 block.owner_decl.analysis = .sema_failure;
3256 block.owner_decl.generation = mod.generation;
3451 block.sema.owner_decl.analysis = .sema_failure;
3452 block.sema.owner_decl.generation = mod.generation;
32573453 }
32583454 } else {
3259 if (block.func) |func| {
3455 if (block.sema.func) |func| {
32603456 func.state = .sema_failure;
32613457 } else {
3262 block.owner_decl.analysis = .sema_failure;
3263 block.owner_decl.generation = mod.generation;
3458 block.sema.owner_decl.analysis = .sema_failure;
3459 block.sema.owner_decl.generation = mod.generation;
32643460 }
32653461 }
3266 mod.failed_decls.putAssumeCapacityNoClobber(block.owner_decl, err_msg);
3462 mod.failed_decls.putAssumeCapacityNoClobber(block.sema.owner_decl, err_msg);
32673463 },
32683464 .gen_zir, .gen_suspend => {
32693465 const gen_zir = scope.cast(Scope.GenZir).?;
3270 gen_zir.decl.analysis = .sema_failure;
3271 gen_zir.decl.generation = mod.generation;
3272 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3466 gen_zir.zir_code.decl.analysis = .sema_failure;
3467 gen_zir.zir_code.decl.generation = mod.generation;
3468 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
32733469 },
32743470 .local_val => {
32753471 const gen_zir = scope.cast(Scope.LocalVal).?.gen_zir;
3276 gen_zir.decl.analysis = .sema_failure;
3277 gen_zir.decl.generation = mod.generation;
3278 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3472 gen_zir.zir_code.decl.analysis = .sema_failure;
3473 gen_zir.zir_code.decl.generation = mod.generation;
3474 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
32793475 },
32803476 .local_ptr => {
32813477 const gen_zir = scope.cast(Scope.LocalPtr).?.gen_zir;
3282 gen_zir.decl.analysis = .sema_failure;
3283 gen_zir.decl.generation = mod.generation;
3284 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3478 gen_zir.zir_code.decl.analysis = .sema_failure;
3479 gen_zir.zir_code.decl.generation = mod.generation;
3480 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
32853481 },
32863482 .gen_nosuspend => {
32873483 const gen_zir = scope.cast(Scope.Nosuspend).?.gen_zir;
3288 gen_zir.decl.analysis = .sema_failure;
3289 gen_zir.decl.generation = mod.generation;
3290 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
3484 gen_zir.zir_code.decl.analysis = .sema_failure;
3485 gen_zir.zir_code.decl.generation = mod.generation;
3486 mod.failed_decls.putAssumeCapacityNoClobber(gen_zir.zir_code.decl, err_msg);
32913487 },
32923488 .file => unreachable,
32933489 .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 },
32943496 }
32953497 return error.AnalysisFail;
32963498}
......@@ -3344,14 +3546,12 @@ pub fn intSub(allocator: *Allocator, lhs: Value, rhs: Value) !Value {
33443546}
33453547
33463548pub fn floatAdd(
3347 mod: *Module,
3348 scope: *Scope,
3549 arena: *Allocator,
33493550 float_type: Type,
33503551 src: LazySrcLoc,
33513552 lhs: Value,
33523553 rhs: Value,
33533554) !Value {
3354 const arena = scope.arena();
33553555 switch (float_type.tag()) {
33563556 .f16 => {
33573557 @panic("TODO add __trunctfhf2 to compiler-rt");
......@@ -3379,14 +3579,12 @@ pub fn floatAdd(
33793579}
33803580
33813581pub fn floatSub(
3382 mod: *Module,
3383 scope: *Scope,
3582 arena: *Allocator,
33843583 float_type: Type,
33853584 src: LazySrcLoc,
33863585 lhs: Value,
33873586 rhs: Value,
33883587) !Value {
3389 const arena = scope.arena();
33903588 switch (float_type.tag()) {
33913589 .f16 => {
33923590 @panic("TODO add __trunctfhf2 to compiler-rt");
......@@ -3584,7 +3782,6 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode {
35843782pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex) InnerError![]const u8 {
35853783 const tree = scope.tree();
35863784 const token_tags = tree.tokens.items(.tag);
3587 const token_starts = tree.tokens.items(.start);
35883785 assert(token_tags[token] == .identifier);
35893786 const ident_name = tree.tokenSlice(token);
35903787 if (!mem.startsWith(u8, ident_name, "@")) {
......@@ -3592,7 +3789,7 @@ pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex)
35923789 }
35933790 var buf = std.ArrayList(u8).init(mod.gpa);
35943791 defer buf.deinit();
3595 try parseStrLit(mod, scope, buf, ident_name, 1);
3792 try parseStrLit(mod, scope, token, &buf, ident_name, 1);
35963793 return buf.toOwnedSlice();
35973794}
35983795
......@@ -3607,13 +3804,12 @@ pub fn appendIdentStr(
36073804) InnerError!void {
36083805 const tree = scope.tree();
36093806 const token_tags = tree.tokens.items(.tag);
3610 const token_starts = tree.tokens.items(.start);
36113807 assert(token_tags[token] == .identifier);
36123808 const ident_name = tree.tokenSlice(token);
36133809 if (!mem.startsWith(u8, ident_name, "@")) {
36143810 return buf.appendSlice(ident_name);
36153811 } else {
3616 return parseStrLit(scope, buf, ident_name, 1);
3812 return parseStrLit(scope, token, buf, ident_name, 1);
36173813 }
36183814}
36193815
......@@ -3621,57 +3817,60 @@ pub fn appendIdentStr(
36213817pub fn parseStrLit(
36223818 mod: *Module,
36233819 scope: *Scope,
3624 buf: *ArrayList(u8),
3820 token: ast.TokenIndex,
3821 buf: *std.ArrayList(u8),
36253822 bytes: []const u8,
3626 offset: usize,
3823 offset: u32,
36273824) InnerError!void {
3825 const tree = scope.tree();
3826 const token_starts = tree.tokens.items(.start);
36283827 const raw_string = bytes[offset..];
36293828 switch (try std.zig.string_literal.parseAppend(buf, raw_string)) {
36303829 .success => return,
36313830 .invalid_character => |bad_index| {
3632 return mod.fail(
3831 return mod.failOff(
36333832 scope,
3634 token_starts[token] + offset + bad_index,
3833 token_starts[token] + offset + @intCast(u32, bad_index),
36353834 "invalid string literal character: '{c}'",
36363835 .{raw_string[bad_index]},
36373836 );
36383837 },
36393838 .expected_hex_digits => |bad_index| {
3640 return mod.fail(
3839 return mod.failOff(
36413840 scope,
3642 token_starts[token] + offset + bad_index,
3841 token_starts[token] + offset + @intCast(u32, bad_index),
36433842 "expected hex digits after '\\x'",
36443843 .{},
36453844 );
36463845 },
36473846 .invalid_hex_escape => |bad_index| {
3648 return mod.fail(
3847 return mod.failOff(
36493848 scope,
3650 token_starts[token] + offset + bad_index,
3849 token_starts[token] + offset + @intCast(u32, bad_index),
36513850 "invalid hex digit: '{c}'",
36523851 .{raw_string[bad_index]},
36533852 );
36543853 },
36553854 .invalid_unicode_escape => |bad_index| {
3656 return mod.fail(
3855 return mod.failOff(
36573856 scope,
3658 token_starts[token] + offset + bad_index,
3857 token_starts[token] + offset + @intCast(u32, bad_index),
36593858 "invalid unicode digit: '{c}'",
36603859 .{raw_string[bad_index]},
36613860 );
36623861 },
3663 .missing_matching_brace => |bad_index| {
3664 return mod.fail(
3862 .missing_matching_rbrace => |bad_index| {
3863 return mod.failOff(
36653864 scope,
3666 token_starts[token] + offset + bad_index,
3865 token_starts[token] + offset + @intCast(u32, bad_index),
36673866 "missing matching '}}' character",
36683867 .{},
36693868 );
36703869 },
36713870 .expected_unicode_digits => |bad_index| {
3672 return mod.fail(
3871 return mod.failOff(
36733872 scope,
3674 token_starts[token] + offset + bad_index,
3873 token_starts[token] + offset + @intCast(u32, bad_index),
36753874 "expected unicode digits after '\\u'",
36763875 .{},
36773876 );
src/Sema.zig+679-588
......@@ -6,7 +6,7 @@
66//! This is the the heart of the Zig compiler.
77
88mod: *Module,
9/// Same as `mod.gpa`.
9/// Alias to `mod.gpa`.
1010gpa: *Allocator,
1111/// Points to the arena allocator of the Decl.
1212arena: *Allocator,
......@@ -53,22 +53,6 @@ const InnerError = Module.InnerError;
5353const Decl = Module.Decl;
5454const 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
7256pub fn root(sema: *Sema, root_block: *Scope.Block) !void {
7357 const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len];
7458 return sema.analyzeBody(root_block, root_body);
......@@ -246,27 +230,26 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde
246230 }
247231}
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 {
250235 var i = zir_ref;
251236
252237 // First section of indexes correspond to a set number of constant values.
253 if (i < const_tzir_inst_list.len) {
254 return &const_tzir_inst_list[i];
238 if (i < zir.const_inst_list.len) {
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]);
255245 }
256 i -= const_tzir_inst_list.len;
246 i -= zir.const_inst_list.len;
257247
258248 // Next section of indexes correspond to function parameters, if any.
259 if (block.inlining) |inlining| {
260 if (i < inlining.casted_args.len) {
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;
249 if (i < sema.param_inst_list.len) {
250 return sema.param_inst_list[i];
269251 }
252 i -= sema.param_inst_list.len;
270253
271254 // Finally, the last section of indexes refers to the map of ZIR=>TZIR.
272255 return sema.inst_map[i];
......@@ -278,17 +261,17 @@ fn resolveConstString(
278261 src: LazySrcLoc,
279262 zir_ref: zir.Inst.Ref,
280263) ![]u8 {
281 const tzir_inst = sema.resolveInst(block, zir_ref);
264 const tzir_inst = try sema.resolveInst(zir_ref);
282265 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);
284267 const val = try sema.resolveConstValue(block, src, coerced_inst);
285268 return val.toAllocatedBytes(sema.arena);
286269}
287270
288271fn 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);
290273 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);
292275 const val = try sema.resolveConstValue(block, src, coerced_inst);
293276 return val.toType(sema.arena);
294277}
......@@ -319,7 +302,7 @@ fn resolveAlreadyCoercedInt(
319302 comptime Int: type,
320303) !Int {
321304 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);
323306 const val = try sema.resolveConstValue(block, src, tzir_inst);
324307 switch (@typeInfo(Int).Int.signedness) {
325308 .signed => return @intCast(Int, val.toSignedInt()),
......@@ -334,8 +317,8 @@ fn resolveInt(
334317 zir_ref: zir.Inst.Ref,
335318 dest_type: Type,
336319) !u64 {
337 const tzir_inst = sema.resolveInst(block, zir_ref);
338 const coerced = try sema.coerce(scope, dest_type, tzir_inst);
320 const tzir_inst = try sema.resolveInst(zir_ref);
321 const coerced = try sema.coerce(block, dest_type, tzir_inst, src);
339322 const val = try sema.resolveConstValue(block, src, coerced);
340323
341324 return val.toUnsignedInt();
......@@ -347,7 +330,7 @@ fn resolveInstConst(
347330 src: LazySrcLoc,
348331 zir_ref: zir.Inst.Ref,
349332) InnerError!TypedValue {
350 const tzir_inst = sema.resolveInst(block, zir_ref);
333 const tzir_inst = try sema.resolveInst(zir_ref);
351334 const val = try sema.resolveConstValue(block, src, tzir_inst);
352335 return TypedValue{
353336 .ty = tzir_inst.ty,
......@@ -355,42 +338,46 @@ fn resolveInstConst(
355338 };
356339}
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 {
359342 const tracy = trace(@src());
360343 defer tracy.end();
344
345 const tv_ptr = sema.code.instructions.items(.data)[inst].@"const";
361346 // Move the TypedValue from old memory to new memory. This allows freeing the ZIR instructions
362 // after analysis.
363 const typed_value_copy = try const_inst.positionals.typed_value.copy(sema.arena);
364 return sema.mod.constInst(scope, const_inst.base.src, typed_value_copy);
347 // after analysis. This happens, for example, with variable declaration initialization
348 // expressions.
349 const typed_value_copy = try tv_ptr.copy(sema.arena);
350 return sema.mod.constInst(sema.arena, .unneeded, typed_value_copy);
365351}
366352
367353fn zirBitcastRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
368354 const tracy = trace(@src());
369355 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", .{});
371357}
372358
373359fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
374360 const tracy = trace(@src());
375361 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", .{});
377363}
378364
379365fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
380366 const tracy = trace(@src());
381367 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", .{});
383369}
384370
385371fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
386372 const tracy = trace(@src());
387373 defer tracy.end();
388374
389 try sema.requireFunctionBlock(block, inst.base.src);
390 const fn_ty = block.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
375 const src: LazySrcLoc = .unneeded;
376 try sema.requireFunctionBlock(block, src);
377 const fn_ty = sema.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
391378 const ret_type = fn_ty.fnReturnType();
392379 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);
394381}
395382
396383fn 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
398385 defer tracy.end();
399386
400387 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);
402389 return sema.analyzeRef(block, inst_data.src(), operand);
403390}
404391
405392fn zirRetType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
406393 const tracy = trace(@src());
407394 defer tracy.end();
408 try sema.requireFunctionBlock(block, inst.base.src);
409 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
395
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;
410399 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);
412401}
413402
414403fn 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
416405 defer tracy.end();
417406
418407 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);
420409 const src = inst_data.src();
421410 switch (operand.ty.zigTypeTag()) {
422411 .Void, .NoReturn => return sema.mod.constVoid(sema.arena, .unneeded),
......@@ -429,7 +418,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde
429418 defer tracy.end();
430419
431420 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);
433422 const src = inst_data.src();
434423 switch (operand.ty.zigTypeTag()) {
435424 .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
442431 defer tracy.end();
443432
444433 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
447437 const elem_ty = array_ptr.ty.elemType();
448438 if (!elem_ty.isIndexable()) {
......@@ -454,7 +444,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
454444 "type '{}' does not support indexing",
455445 .{elem_ty},
456446 );
457 errdefer msg.destroy(mod.gpa);
447 errdefer msg.destroy(sema.gpa);
458448 try sema.mod.errNote(
459449 &block.base,
460450 cond_src,
......@@ -464,10 +454,10 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
464454 );
465455 break :msg msg;
466456 };
467 return mod.failWithOwnedErrorMsg(scope, msg);
457 return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
468458 }
469 const result_ptr = try sema.namedFieldPtr(block, inst.base.src, array_ptr, "len", inst.base.src);
470 return sema.analyzeDeref(block, inst.base.src, result_ptr, result_ptr.src);
459 const result_ptr = try sema.namedFieldPtr(block, src, array_ptr, "len", src);
460 return sema.analyzeDeref(block, src, result_ptr, result_ptr.src);
471461}
472462
473463fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
......@@ -505,6 +495,10 @@ fn zirAllocInferred(
505495) InnerError!*Inst {
506496 const tracy = trace(@src());
507497 defer tracy.end();
498
499 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
500 const src = inst_data.src();
501
508502 const val_payload = try sema.arena.create(Value.Payload.InferredAlloc);
509503 val_payload.* = .{
510504 .data = .{},
......@@ -513,11 +507,11 @@ fn zirAllocInferred(
513507 // not needed in the case of constant values. However here, we plan to "downgrade"
514508 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append
515509 // 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, .{
517511 .ty = inferred_alloc_ty,
518512 .val = Value.initPayload(&val_payload.base),
519513 });
520 try sema.requireFunctionBlock(block, inst.base.src);
514 try sema.requireFunctionBlock(block, src);
521515 try block.instructions.append(sema.gpa, result);
522516 return result;
523517}
......@@ -532,7 +526,7 @@ fn zirResolveInferredAlloc(
532526
533527 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
534528 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);
536530 const ptr_val = ptr.castTag(.constant).?.val;
537531 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;
538532 const peer_inst_list = inferred_alloc.data.stored_inst_list.items;
......@@ -563,14 +557,15 @@ fn zirStoreToBlockPtr(
563557 defer tracy.end();
564558
565559 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
566 const ptr = sema.resolveInst(bin_inst.lhs);
567 const value = sema.resolveInst(bin_inst.rhs);
560 const ptr = try sema.resolveInst(bin_inst.lhs);
561 const value = try sema.resolveInst(bin_inst.rhs);
568562 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);
569563 // TODO detect when this store should be done at compile-time. For example,
570564 // if expressions should force it when the condition is compile-time known.
565 const src: LazySrcLoc = .unneeded;
571566 try sema.requireRuntimeBlock(block, src);
572 const bitcasted_ptr = try block.addUnOp(inst.base.src, ptr_ty, .bitcast, ptr);
573 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);
567 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
568 return sema.storePtr(block, src, bitcasted_ptr, value);
574569}
575570
576571fn zirStoreToInferredPtr(
......@@ -581,9 +576,10 @@ fn zirStoreToInferredPtr(
581576 const tracy = trace(@src());
582577 defer tracy.end();
583578
579 const src: LazySrcLoc = .unneeded;
584580 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
585 const ptr = sema.resolveInst(bin_inst.lhs);
586 const value = sema.resolveInst(bin_inst.rhs);
581 const ptr = try sema.resolveInst(bin_inst.lhs);
582 const value = try sema.resolveInst(bin_inst.rhs);
587583 const inferred_alloc = ptr.castTag(.constant).?.val.castTag(.inferred_alloc).?;
588584 // Add the stored instruction to the set we will use to resolve peer types
589585 // for the inferred allocation.
......@@ -591,8 +587,8 @@ fn zirStoreToInferredPtr(
591587 // Create a runtime bitcast instruction with exactly the type the pointer wants.
592588 const ptr_ty = try sema.mod.simplePtrType(sema.arena, value.ty, true, .One);
593589 try sema.requireRuntimeBlock(block, src);
594 const bitcasted_ptr = try block.addUnOp(inst.base.src, ptr_ty, .bitcast, ptr);
595 return mod.storePtr(scope, inst.base.src, bitcasted_ptr, value);
590 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
591 return sema.storePtr(block, src, bitcasted_ptr, value);
596592}
597593
598594fn zirSetEvalBranchQuota(
......@@ -614,17 +610,18 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
614610 defer tracy.end();
615611
616612 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
617 const ptr = sema.resolveInst(bin_inst.lhs);
618 const value = sema.resolveInst(bin_inst.rhs);
619 return mod.storePtr(scope, inst.base.src, ptr, value);
613 const ptr = try sema.resolveInst(bin_inst.lhs);
614 const value = try sema.resolveInst(bin_inst.rhs);
615 return sema.storePtr(block, .unneeded, ptr, value);
620616}
621617
622618fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
623619 const tracy = trace(@src());
624620 defer tracy.end();
625621
622 const src: LazySrcLoc = .todo;
626623 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);
628625 const param_index = inst_data.param_index;
629626
630627 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
640637 const param_count = fn_ty.fnParamLen();
641638 if (param_index >= param_count) {
642639 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));
644641 }
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)", .{
646643 param_index,
647644 fn_ty,
648645 param_count,
......@@ -651,20 +648,25 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr
651648
652649 // TODO support generic functions
653650 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);
655652}
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 {
658655 const tracy = trace(@src());
659656 defer tracy.end();
660657
661 // The bytes references memory inside the ZIR module, which is fine. Multiple
662 // anonymous Decls may have strings which point to within the same ZIR module.
663 const bytes = sema.code.instructions.items(.data)[inst].str.get(sema.code);
658 const zir_bytes = sema.code.instructions.items(.data)[inst].str.get(sema.code);
659
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
665665 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
666666 errdefer new_decl_arena.deinit();
667667
668 const bytes = try new_decl_arena.allocator.dupe(u8, zir_bytes);
669
668670 const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len);
669671 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
679681 const tracy = trace(@src());
680682 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);
683686}
684687
685688fn 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
694697}
695698
696699fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
697 var managed = mod.compile_log_text.toManaged(mod.gpa);
698 defer mod.compile_log_text = managed.moveToUnmanaged();
700 var managed = sema.mod.compile_log_text.toManaged(sema.gpa);
701 defer sema.mod.compile_log_text = managed.moveToUnmanaged();
699702 const writer = managed.writer();
700703
701704 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
703706 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {
704707 if (i != 0) try writer.print(", ", .{});
705708
706 const arg = sema.resolveInst(block, arg_ref);
709 const arg = try sema.resolveInst(arg_ref);
707710 if (arg.value()) |val| {
708711 try writer.print("@as({}, {})", .{ arg.ty, val });
709712 } else {
......@@ -712,12 +715,9 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
712715 }
713716 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);
716719 if (!gop.found_existing) {
717 gop.entry.value = .{
718 .file_scope = block.getFileScope(),
719 .lazy = inst_data.src(),
720 };
720 gop.entry.value = inst_data.src().toSrcLoc(&block.base);
721721 }
722722 return sema.mod.constVoid(sema.arena, .unneeded);
723723}
......@@ -726,6 +726,11 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE
726726 const tracy = trace(@src());
727727 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
729734 // Reserve space for a Loop instruction so that generated Break instructions can
730735 // point to it, even if it doesn't end up getting used because the code ends up being
731736 // comptime evaluated.
......@@ -734,52 +739,57 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE
734739 .base = .{
735740 .tag = Inst.Loop.base_tag,
736741 .ty = Type.initTag(.noreturn),
737 .src = inst.base.src,
742 .src = src,
738743 },
739744 .body = undefined,
740745 };
741746
742747 var child_block: Scope.Block = .{
743748 .parent = parent_block,
744 .inst_table = parent_block.inst_table,
745 .func = parent_block.func,
746 .owner_decl = parent_block.owner_decl,
749 .sema = sema,
747750 .src_decl = parent_block.src_decl,
748751 .instructions = .{},
749 .arena = sema.arena,
750752 .inlining = parent_block.inlining,
751753 .is_comptime = parent_block.is_comptime,
752 .branch_quota = parent_block.branch_quota,
753754 };
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
758759 // 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);
761762 loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items) };
762763 return &loop_inst.base;
763764}
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 {
766772 const tracy = trace(@src());
767773 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
769780 var child_block = parent_block.makeSubBlock();
770 defer child_block.instructions.deinit(mod.gpa);
781 defer child_block.instructions.deinit(sema.gpa);
771782 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
775786 // Move the analyzed instructions into the parent block arena.
776787 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
779790 // The result of a flat block is the last instruction.
780 const zir_inst_list = inst.positionals.body.instructions;
781 const last_zir_inst = zir_inst_list[zir_inst_list.len - 1];
782 return sema.inst_map[last_zir_inst];
791 const last_zir_inst = body[body.len - 1];
792 return sema.resolveInst(last_zir_inst);
783793}
784794
785795fn zirBlock(
......@@ -791,6 +801,11 @@ fn zirBlock(
791801 const tracy = trace(@src());
792802 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
794809 // Reserve space for a Block instruction so that generated Break instructions can
795810 // point to it, even if it doesn't end up getting used because the code ends up being
796811 // comptime evaluated.
......@@ -799,19 +814,16 @@ fn zirBlock(
799814 .base = .{
800815 .tag = Inst.Block.base_tag,
801816 .ty = undefined, // Set after analysis.
802 .src = inst.base.src,
817 .src = src,
803818 },
804819 .body = undefined,
805820 };
806821
807822 var child_block: Scope.Block = .{
808823 .parent = parent_block,
809 .inst_table = parent_block.inst_table,
810 .func = parent_block.func,
811 .owner_decl = parent_block.owner_decl,
824 .sema = sema,
812825 .src_decl = parent_block.src_decl,
813826 .instructions = .{},
814 .arena = sema.arena,
815827 // TODO @as here is working around a stage1 miscompilation bug :(
816828 .label = @as(?Scope.Block.Label, Scope.Block.Label{
817829 .zir_block = inst,
......@@ -823,17 +835,16 @@ fn zirBlock(
823835 }),
824836 .inlining = parent_block.inlining,
825837 .is_comptime = is_comptime or parent_block.is_comptime,
826 .branch_quota = parent_block.branch_quota,
827838 };
828839 const merges = &child_block.label.?.merges;
829840
830 defer child_block.instructions.deinit(mod.gpa);
831 defer merges.results.deinit(mod.gpa);
832 defer merges.br_list.deinit(mod.gpa);
841 defer child_block.instructions.deinit(sema.gpa);
842 defer merges.results.deinit(sema.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);
837848}
838849
839850fn analyzeBlockBody(
......@@ -853,7 +864,7 @@ fn analyzeBlockBody(
853864 // No need for a block instruction. We can put the new instructions
854865 // directly into the parent block.
855866 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);
857868 return copied_instructions[copied_instructions.len - 1];
858869 }
859870 if (merges.results.items.len == 1) {
......@@ -864,7 +875,7 @@ fn analyzeBlockBody(
864875 // No need for a block instruction. We can put the new instructions directly
865876 // into the parent block. Here we omit the break instruction.
866877 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);
868879 return merges.results.items[0];
869880 }
870881 }
......@@ -874,7 +885,7 @@ fn analyzeBlockBody(
874885
875886 // Need to set the type and emit the Block instruction. This allows machine code generation
876887 // 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);
878889 const resolved_ty = try sema.resolvePeerTypes(parent_block, merges.results.items);
879890 merges.block_inst.base.ty = resolved_ty;
880891 merges.block_inst.body = .{
......@@ -888,8 +899,8 @@ fn analyzeBlockBody(
888899 continue;
889900 }
890901 var coerce_block = parent_block.makeSubBlock();
891 defer coerce_block.instructions.deinit(mod.gpa);
892 const coerced_operand = try sema.coerce(&coerce_block.base, resolved_ty, br.operand);
902 defer coerce_block.instructions.deinit(sema.gpa);
903 const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, .todo);
893904 // If no instructions were produced, such as in the case of a coercion of a
894905 // constant value to a new type, we can simply point the br operand to it.
895906 if (coerce_block.instructions.items.len == 0) {
......@@ -921,8 +932,10 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
921932 const tracy = trace(@src());
922933 defer tracy.end();
923934
935 const src_node = sema.code.instructions.items(.data)[inst].node;
936 const src: LazySrcLoc = .{ .node_offset = src_node };
924937 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);
926939}
927940
928941fn 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!*
930943 defer tracy.end();
931944
932945 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);
934947 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);
936949}
937950
938951fn 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
942955 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
943956 const zir_block = inst_data.operand;
944957 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);
946959}
947960
948961fn analyzeBreak(
949962 sema: *Sema,
950 block: *Scope.Block,
963 start_block: *Scope.Block,
951964 src: LazySrcLoc,
952965 zir_block: zir.Inst.Index,
953966 operand: *Inst,
954967) InnerError!*Inst {
955 var opt_block = scope.cast(Scope.Block);
956 while (opt_block) |block| {
968 var block = start_block;
969 while (true) {
957970 if (block.label) |*label| {
958971 if (label.zir_block == zir_block) {
959972 try sema.requireFunctionBlock(block, src);
960973 // Here we add a br instruction, but we over-allocate a little bit
961974 // (if necessary) to make it possible to convert the instruction into
962975 // 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(
964977 u8,
965978 Inst.convertable_br_align,
966979 Inst.convertable_br_size,
......@@ -974,21 +987,21 @@ fn analyzeBreak(
974987 .operand = operand,
975988 .block = label.merges.block_inst,
976989 };
977 try b.instructions.append(mod.gpa, &br.base);
978 try label.merges.results.append(mod.gpa, operand);
979 try label.merges.br_list.append(mod.gpa, br);
990 try block.instructions.append(sema.gpa, &br.base);
991 try label.merges.results.append(sema.gpa, operand);
992 try label.merges.br_list.append(sema.gpa, br);
980993 return &br.base;
981994 }
982995 }
983 opt_block = block.parent;
984 } else unreachable;
996 block = block.parent.?;
997 }
985998}
986999
9871000fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
9881001 const tracy = trace(@src());
9891002 defer tracy.end();
9901003
991 if (b.is_comptime) {
1004 if (block.is_comptime) {
9921005 return sema.mod.constVoid(sema.arena, .unneeded);
9931006 }
9941007
......@@ -1048,9 +1061,9 @@ fn analyzeCall(
10481061 func_src: LazySrcLoc,
10491062 call_src: LazySrcLoc,
10501063 modifier: std.builtin.CallOptions.Modifier,
1051 zir_args: []const Ref,
1064 zir_args: []const zir.Inst.Ref,
10521065) InnerError!*ir.Inst {
1053 const func = sema.resolveInst(zir_func);
1066 const func = try sema.resolveInst(zir_func);
10541067
10551068 if (func.ty.zigTypeTag() != .Fn)
10561069 return sema.mod.fail(&block.base, func_src, "type '{}' not a function", .{func.ty});
......@@ -1091,20 +1104,20 @@ fn analyzeCall(
10911104 return sema.mod.fail(&block.base, call_src, "TODO implement comptime function calls", .{});
10921105 }
10931106 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});
10951108 }
10961109
10971110 // TODO handle function calls of generic functions
10981111 const casted_args = try sema.arena.alloc(*Inst, zir_args.len);
10991112 for (zir_args) |zir_arg, i| {
11001113 // 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);
11021115 }
11031116
11041117 const ret_type = func.ty.fnReturnType();
11051118
11061119 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;
11081121 const is_inline_call = is_comptime_call or modifier == .always_inline or
11091122 func.ty.fnCallingConvention() == .Inline;
11101123 if (is_inline_call) {
......@@ -1135,70 +1148,75 @@ fn analyzeCall(
11351148 // Otherwise we pass on the shared data from the parent scope.
11361149 var shared_inlining: Scope.Block.Inlining.Shared = .{
11371150 .branch_count = 0,
1138 .caller = b.func,
1151 .caller = sema.func,
11391152 };
11401153 // This one is shared among sub-blocks within the same callee, but not
11411154 // shared among the entire inline/comptime call stack.
11421155 var inlining: Scope.Block.Inlining = .{
1143 .shared = if (b.inlining) |inlining| inlining.shared else &shared_inlining,
1144 .param_index = 0,
1145 .casted_args = casted_args,
1156 .shared = if (block.inlining) |inlining| inlining.shared else &shared_inlining,
11461157 .merges = .{
11471158 .results = .{},
11481159 .br_list = .{},
11491160 .block_inst = block_inst,
11501161 },
11511162 };
1152 var inst_table = Scope.Block.InstTable.init(mod.gpa);
1153 defer inst_table.deinit();
1163 var inline_sema: Sema = .{
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
11551175 var child_block: Scope.Block = .{
11561176 .parent = null,
1157 .inst_table = &inst_table,
1158 .func = module_fn,
1159 .owner_decl = scope.ownerDecl().?,
1177 .sema = &inline_sema,
11601178 .src_decl = module_fn.owner_decl,
11611179 .instructions = .{},
1162 .arena = sema.arena,
11631180 .label = null,
11641181 .inlining = &inlining,
11651182 .is_comptime = is_comptime_call,
1166 .branch_quota = b.branch_quota,
11671183 };
11681184
11691185 const merges = &child_block.inlining.?.merges;
11701186
1171 defer child_block.instructions.deinit(mod.gpa);
1172 defer merges.results.deinit(mod.gpa);
1173 defer merges.br_list.deinit(mod.gpa);
1187 defer child_block.instructions.deinit(sema.gpa);
1188 defer merges.results.deinit(sema.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
11771193 // This will have return instructions analyzed as break instructions to
11781194 // 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);
11821198 }
11831199
11841200 return block.addCall(call_src, ret_type, func, casted_args);
11851201}
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 {
11881204 const tracy = trace(@src());
11891205 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", .{});
11911208}
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 {
11941211 const tracy = trace(@src());
11951212 defer tracy.end();
11961213
11971214 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1198 const child_type = try sema.resolveType(block, inst_data.operand);
1199 const opt_type = try mod.optionalType(sema.arena, child_type);
1215 const src = inst_data.src();
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);
12021220}
12031221
12041222fn 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
12061224 defer tracy.end();
12071225
12081226 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);
12101228 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
12131231 return sema.mod.constType(sema.arena, inst_data.src(), opt_ty);
12141232}
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 {
12171235 const tracy = trace(@src());
12181236 defer tracy.end();
1237
12191238 // TODO these should be lazily evaluated
1220 const len = try resolveInstConst(mod, scope, array.positionals.lhs);
1221 const elem_type = try sema.resolveType(block, array.positionals.rhs);
1239 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
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);
12241245}
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 {
12271248 const tracy = trace(@src());
12281249 defer tracy.end();
1250
12291251 // TODO these should be lazily evaluated
1230 const len = try resolveInstConst(mod, scope, array.positionals.len);
1231 const sentinel = try resolveInstConst(mod, scope, array.positionals.sentinel);
1232 const elem_type = try sema.resolveType(block, array.positionals.elem_type);
1252 const inst_data = sema.code.instructions.items(.data)[inst].array_type_sentinel;
1253 const len = try sema.resolveInstConst(block, .unneeded, inst_data.len);
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);
12351260}
12361261
12371262fn 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
12391264 defer tracy.end();
12401265
12411266 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1242 const error_union = try sema.resolveType(block, bin_inst.lhs);
1243 const payload = try sema.resolveType(block, bin_inst.rhs);
1267 const error_union = try sema.resolveType(block, .unneeded, bin_inst.lhs);
1268 const payload = try sema.resolveType(block, .unneeded, bin_inst.rhs);
12441269
12451270 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()});
12471272 }
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);
12501276}
12511277
12521278fn 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
12661292 const tracy = trace(@src());
12671293 defer tracy.end();
12681294
1295 if (true) @panic("TODO update zirErrorSet in zir-memory-layout branch");
1296
12691297 // 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);
12711299 errdefer new_decl_arena.deinit();
12721300
12731301 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
12811309 try payload.data.fields.ensureCapacity(&new_decl_arena.allocator, @intCast(u32, inst.positionals.fields.len));
12821310
12831311 for (inst.positionals.fields) |field_name| {
1284 const entry = try mod.getErrorValue(field_name);
1312 const entry = try sema.mod.getErrorValue(field_name);
12851313 if (payload.data.fields.fetchPutAssumeCapacity(entry.key, {})) |_| {
12861314 return sema.mod.fail(&block.base, inst.base.src, "duplicate error: '{s}'", .{field_name});
12871315 }
12881316 }
12891317 // 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, .{
12911319 .ty = Type.initTag(.type),
12921320 .val = Value.initPayload(&payload.base),
12931321 });
12941322 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);
12961324}
12971325
12981326fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
12991327 const tracy = trace(@src());
13001328 defer tracy.end();
13011329
1330 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1331 const src = inst_data.src();
1332
13021333 // 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));
13041335 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, .{
13061337 .ty = result_type,
13071338 .val = try Value.Tag.@"error".create(sema.arena, .{
13081339 .name = entry.key,
......@@ -1314,9 +1345,11 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
13141345 const tracy = trace(@src());
13151346 defer tracy.end();
13161347
1348 if (true) @panic("TODO update zirMergeErrorSets in zir-memory-layout branch");
1349
13171350 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1318 const lhs_ty = try sema.resolveType(block, bin_inst.lhs);
1319 const rhs_ty = try sema.resolveType(block, bin_inst.rhs);
1351 const lhs_ty = try sema.resolveType(block, .unneeded, bin_inst.lhs);
1352 const rhs_ty = try sema.resolveType(block, .unneeded, bin_inst.rhs);
13201353 if (rhs_ty.zigTypeTag() != .ErrorSet)
13211354 return sema.mod.fail(&block.base, inst.positionals.rhs.src, "expected error set type, found {}", .{rhs_ty});
13221355 if (lhs_ty.zigTypeTag() != .ErrorSet)
......@@ -1324,12 +1357,12 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inn
13241357
13251358 // anything merged with anyerror is anyerror
13261359 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, .{
13281361 .ty = Type.initTag(.type),
13291362 .val = Value.initTag(.anyerror_type),
13301363 });
13311364 // 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);
13331366 errdefer new_decl_arena.deinit();
13341367
13351368 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
13801413 else => unreachable,
13811414 }
13821415 // 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, .{
13841417 .ty = Type.initTag(.type),
13851418 .val = Value.initPayload(&payload.base),
13861419 });
13871420 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);
13901423}
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 {
13931426 const tracy = trace(@src());
13941427 defer tracy.end();
13951428
1396 const duped_name = try sema.arena.dupe(u8, inst.positionals.name);
1397 return sema.mod.constInst(scope, inst.base.src, .{
1429 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
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, .{
13981433 .ty = Type.initTag(.enum_literal),
13991434 .val = try Value.Tag.enum_literal.create(sema.arena, duped_name),
14001435 });
......@@ -1411,7 +1446,7 @@ fn zirOptionalPayloadPtr(
14111446 defer tracy.end();
14121447
14131448 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);
14151450 assert(optional_ptr.ty.zigTypeTag() == .Pointer);
14161451 const src = inst_data.src();
14171452
......@@ -1429,7 +1464,7 @@ fn zirOptionalPayloadPtr(
14291464 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
14301465 }
14311466 // 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, .{
14331468 .ty = child_pointer,
14341469 .val = pointer_val,
14351470 });
......@@ -1438,7 +1473,7 @@ fn zirOptionalPayloadPtr(
14381473 try sema.requireRuntimeBlock(block, src);
14391474 if (safety_check and block.wantSafety()) {
14401475 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);
14421477 }
14431478 return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr);
14441479}
......@@ -1455,7 +1490,7 @@ fn zirOptionalPayload(
14551490
14561491 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
14571492 const src = inst_data.src();
1458 const operand = sema.resolveInst(block, inst_data.operand);
1493 const operand = try sema.resolveInst(inst_data.operand);
14591494 const opt_type = operand.ty;
14601495 if (opt_type.zigTypeTag() != .Optional) {
14611496 return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});
......@@ -1467,7 +1502,7 @@ fn zirOptionalPayload(
14671502 if (val.isNull()) {
14681503 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
14691504 }
1470 return sema.mod.constInst(scope, src, .{
1505 return sema.mod.constInst(sema.arena, src, .{
14711506 .ty = child_type,
14721507 .val = val,
14731508 });
......@@ -1476,7 +1511,7 @@ fn zirOptionalPayload(
14761511 try sema.requireRuntimeBlock(block, src);
14771512 if (safety_check and block.wantSafety()) {
14781513 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);
14801515 }
14811516 return block.addUnOp(src, child_type, .optional_payload, operand);
14821517}
......@@ -1493,7 +1528,7 @@ fn zirErrUnionPayload(
14931528
14941529 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
14951530 const src = inst_data.src();
1496 const operand = sema.resolveInst(block, inst_data.operand);
1531 const operand = try sema.resolveInst(inst_data.operand);
14971532 if (operand.ty.zigTypeTag() != .ErrorUnion)
14981533 return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty});
14991534
......@@ -1502,7 +1537,7 @@ fn zirErrUnionPayload(
15021537 return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name});
15031538 }
15041539 const data = val.castTag(.error_union).?.data;
1505 return sema.mod.constInst(scope, src, .{
1540 return sema.mod.constInst(sema.arena, src, .{
15061541 .ty = operand.ty.castTag(.error_union).?.data.payload,
15071542 .val = data,
15081543 });
......@@ -1510,7 +1545,7 @@ fn zirErrUnionPayload(
15101545 try sema.requireRuntimeBlock(block, src);
15111546 if (safety_check and block.wantSafety()) {
15121547 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);
15141549 }
15151550 return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_payload, operand);
15161551}
......@@ -1527,7 +1562,7 @@ fn zirErrUnionPayloadPtr(
15271562
15281563 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
15291564 const src = inst_data.src();
1530 const operand = sema.resolveInst(block, inst_data.operand);
1565 const operand = try sema.resolveInst(inst_data.operand);
15311566 assert(operand.ty.zigTypeTag() == .Pointer);
15321567
15331568 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
......@@ -1542,7 +1577,7 @@ fn zirErrUnionPayloadPtr(
15421577 }
15431578 const data = val.castTag(.error_union).?.data;
15441579 // 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, .{
15461581 .ty = operand_pointer_ty,
15471582 .val = try Value.Tag.ref_val.create(
15481583 sema.arena,
......@@ -1554,7 +1589,7 @@ fn zirErrUnionPayloadPtr(
15541589 try sema.requireRuntimeBlock(block, src);
15551590 if (safety_check and block.wantSafety()) {
15561591 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);
15581593 }
15591594 return block.addUnOp(src, operand_pointer_ty, .unwrap_errunion_payload_ptr, operand);
15601595}
......@@ -1566,14 +1601,14 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner
15661601
15671602 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
15681603 const src = inst_data.src();
1569 const operand = sema.resolveInst(block, inst_data.operand);
1604 const operand = try sema.resolveInst(inst_data.operand);
15701605 if (operand.ty.zigTypeTag() != .ErrorUnion)
15711606 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
15721607
15731608 if (operand.value()) |val| {
15741609 assert(val.getError() != null);
15751610 const data = val.castTag(.error_union).?.data;
1576 return sema.mod.constInst(scope, src, .{
1611 return sema.mod.constInst(sema.arena, src, .{
15771612 .ty = operand.ty.castTag(.error_union).?.data.error_set,
15781613 .val = data,
15791614 });
......@@ -1590,7 +1625,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
15901625
15911626 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
15921627 const src = inst_data.src();
1593 const operand = sema.resolveInst(block, inst_data.operand);
1628 const operand = try sema.resolveInst(inst_data.operand);
15941629 assert(operand.ty.zigTypeTag() == .Pointer);
15951630
15961631 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
......@@ -1600,7 +1635,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In
16001635 const val = try pointer_val.pointerDeref(sema.arena);
16011636 assert(val.getError() != null);
16021637 const data = val.castTag(.error_union).?.data;
1603 return sema.mod.constInst(scope, src, .{
1638 return sema.mod.constInst(sema.arena, src, .{
16041639 .ty = operand.ty.elemType().castTag(.error_union).?.data.error_set,
16051640 .val = data,
16061641 });
......@@ -1616,7 +1651,7 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde
16161651
16171652 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
16181653 const src = inst_data.src();
1619 const operand = sema.resolveInst(block, inst_data.operand);
1654 const operand = try sema.resolveInst(inst_data.operand);
16201655 if (operand.ty.zigTypeTag() != .ErrorUnion)
16211656 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
16221657 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:
16511686 const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index);
16521687 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);
16551690 // TODO once we're capable of importing and analyzing decls from
16561691 // std.builtin, this needs to change
16571692 const cc_str = cc_tv.val.castTag(.enum_literal).?.data;
......@@ -1676,7 +1711,7 @@ fn fnTypeCommon(
16761711 cc: std.builtin.CallingConvention,
16771712 var_args: bool,
16781713) 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
16811716 // Hot path for some common function types.
16821717 if (zir_param_types.len == 0 and !var_args) {
......@@ -1699,7 +1734,7 @@ fn fnTypeCommon(
16991734
17001735 const param_types = try sema.arena.alloc(Type, zir_param_types.len);
17011736 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);
17031738 // TODO skip for comptime params
17041739 if (!resolved.isValidVarType(false)) {
17051740 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
17211756 defer tracy.end();
17221757
17231758 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1724 const dest_type = try sema.resolveType(block, bin_inst.lhs);
1725 const tzir_inst = sema.resolveInst(block, bin_inst.rhs);
1726 return sema.coerce(scope, dest_type, tzir_inst);
1759 const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs);
1760 const tzir_inst = try sema.resolveInst(bin_inst.rhs);
1761 return sema.coerce(block, dest_type, tzir_inst, .todo);
17271762}
17281763
17291764fn 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
17311766 defer tracy.end();
17321767
17331768 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);
17351770 if (ptr.ty.zigTypeTag() != .Pointer) {
17361771 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
17371772 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
17521787 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
17531788 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;
17541789 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);
17561791 const object_ptr = try sema.analyzeRef(block, src, object);
17571792 const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
17581793 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
17671802 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
17681803 const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data;
17691804 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);
17711806 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
17721807}
17731808
......@@ -1779,7 +1814,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne
17791814 const src = inst_data.src();
17801815 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
17811816 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);
17831818 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);
17841819 const object_ptr = try sema.analyzeRef(block, src, object);
17851820 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
17941829 const src = inst_data.src();
17951830 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
17961831 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);
17981833 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name);
17991834 return sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src);
18001835}
......@@ -1803,40 +1838,43 @@ fn zirIntcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
18031838 const tracy = trace(@src());
18041839 defer tracy.end();
18051840
1806 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1807 const dest_type = try sema.resolveType(block, bin_inst.lhs);
1808 const operand = sema.resolveInst(bin_inst.rhs);
1841 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1842 const src = inst_data.src();
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
18101850 const dest_is_comptime_int = switch (dest_type.zigTypeTag()) {
18111851 .ComptimeInt => true,
18121852 .Int => false,
1813 else => return mod.fail(
1814 scope,
1815 inst.positionals.lhs.src,
1853 else => return sema.mod.fail(
1854 &block.base,
1855 dest_ty_src,
18161856 "expected integer type, found '{}'",
1817 .{
1818 dest_type,
1819 },
1857 .{dest_type},
18201858 ),
18211859 };
18221860
18231861 switch (operand.ty.zigTypeTag()) {
18241862 .ComptimeInt, .Int => {},
1825 else => return mod.fail(
1826 scope,
1827 inst.positionals.rhs.src,
1863 else => return sema.mod.fail(
1864 &block.base,
1865 operand_src,
18281866 "expected integer type, found '{}'",
18291867 .{operand.ty},
18301868 ),
18311869 }
18321870
18331871 if (operand.value() != null) {
1834 return sema.coerce(scope, dest_type, operand);
1872 return sema.coerce(block, dest_type, operand, operand_src);
18351873 } 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'", .{});
18371875 }
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", .{});
18401878}
18411879
18421880fn 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
18441882 defer tracy.end();
18451883
18461884 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1847 const dest_type = try sema.resolveType(block, bin_inst.lhs);
1848 const operand = sema.resolveInst(bin_inst.rhs);
1849 return mod.bitcast(scope, dest_type, operand);
1885 const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs);
1886 const operand = try sema.resolveInst(bin_inst.rhs);
1887 return sema.bitcast(block, dest_type, operand);
18501888}
18511889
18521890fn zirFloatcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
18531891 const tracy = trace(@src());
18541892 defer tracy.end();
18551893
1856 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1857 const dest_type = try sema.resolveType(block, bin_inst.lhs);
1858 const operand = sema.resolveInst(bin_inst.rhs);
1894 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1895 const src = inst_data.src();
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
18601903 const dest_is_comptime_float = switch (dest_type.zigTypeTag()) {
18611904 .ComptimeFloat => true,
18621905 .Float => false,
1863 else => return mod.fail(
1864 scope,
1865 inst.positionals.lhs.src,
1906 else => return sema.mod.fail(
1907 &block.base,
1908 dest_ty_src,
18661909 "expected float type, found '{}'",
1867 .{
1868 dest_type,
1869 },
1910 .{dest_type},
18701911 ),
18711912 };
18721913
18731914 switch (operand.ty.zigTypeTag()) {
18741915 .ComptimeFloat, .Float, .ComptimeInt => {},
1875 else => return mod.fail(
1876 scope,
1877 inst.positionals.rhs.src,
1916 else => return sema.mod.fail(
1917 &block.base,
1918 operand_src,
18781919 "expected float type, found '{}'",
18791920 .{operand.ty},
18801921 ),
18811922 }
18821923
18831924 if (operand.value() != null) {
1884 return sema.coerce(scope, dest_type, operand);
1925 return sema.coerce(block, dest_type, operand, operand_src);
18851926 } 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'", .{});
18871928 }
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", .{});
18901931}
18911932
18921933fn 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
18941935 defer tracy.end();
18951936
18961937 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);
18981939 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);
19001941 const result_ptr = try sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);
19011942 return sema.analyzeDeref(block, sema.src, result_ptr, sema.src);
19021943}
......@@ -1909,9 +1950,9 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
19091950 const src = inst_data.src();
19101951 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
19111952 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);
19131954 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);
19151956 const result_ptr = try sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);
19161957 return sema.analyzeDeref(block, src, result_ptr, src);
19171958}
......@@ -1921,8 +1962,8 @@ fn zirElemPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
19211962 defer tracy.end();
19221963
19231964 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1924 const array_ptr = sema.resolveInst(block, bin_inst.lhs);
1925 const elem_index = sema.resolveInst(block, bin_inst.rhs);
1965 const array_ptr = try sema.resolveInst(bin_inst.lhs);
1966 const elem_index = try sema.resolveInst(bin_inst.rhs);
19261967 return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);
19271968}
19281969
......@@ -1934,8 +1975,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
19341975 const src = inst_data.src();
19351976 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
19361977 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1937 const array_ptr = sema.resolveInst(block, extra.lhs);
1938 const elem_index = sema.resolveInst(block, extra.rhs);
1978 const array_ptr = try sema.resolveInst(extra.lhs);
1979 const elem_index = try sema.resolveInst(extra.rhs);
19391980 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);
19401981}
19411982
......@@ -1946,8 +1987,8 @@ fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
19461987 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19471988 const src = inst_data.src();
19481989 const extra = sema.code.extraData(zir.Inst.SliceStart, inst_data.payload_index).data;
1949 const array_ptr = sema.resolveInst(extra.lhs);
1950 const start = sema.resolveInst(extra.start);
1990 const array_ptr = try sema.resolveInst(extra.lhs);
1991 const start = try sema.resolveInst(extra.start);
19511992
19521993 return sema.analyzeSlice(block, src, array_ptr, start, null, null, .unneeded);
19531994}
......@@ -1959,9 +2000,9 @@ fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro
19592000 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19602001 const src = inst_data.src();
19612002 const extra = sema.code.extraData(zir.Inst.SliceEnd, inst_data.payload_index).data;
1962 const array_ptr = sema.resolveInst(extra.lhs);
1963 const start = sema.resolveInst(extra.start);
1964 const end = sema.resolveInst(extra.end);
2003 const array_ptr = try sema.resolveInst(extra.lhs);
2004 const start = try sema.resolveInst(extra.start);
2005 const end = try sema.resolveInst(extra.end);
19652006
19662007 return sema.analyzeSlice(block, src, array_ptr, start, end, null, .unneeded);
19672008}
......@@ -1974,21 +2015,22 @@ fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inne
19742015 const src = inst_data.src();
19752016 const sentinel_src: LazySrcLoc = .{ .node_offset_slice_sentinel = inst_data.src_node };
19762017 const extra = sema.code.extraData(zir.Inst.SliceSentinel, inst_data.payload_index).data;
1977 const array_ptr = sema.resolveInst(extra.lhs);
1978 const start = sema.resolveInst(extra.start);
1979 const end = sema.resolveInst(extra.end);
1980 const sentinel = sema.resolveInst(extra.sentinel);
2018 const array_ptr = try sema.resolveInst(extra.lhs);
2019 const start = try sema.resolveInst(extra.start);
2020 const end = try sema.resolveInst(extra.end);
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);
19832024}
19842025
19852026fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
19862027 const tracy = trace(@src());
19872028 defer tracy.end();
19882029
2030 const src: LazySrcLoc = .todo;
19892031 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
1990 const start = sema.resolveInst(bin_inst.lhs);
1991 const end = sema.resolveInst(bin_inst.rhs);
2032 const start = try sema.resolveInst(bin_inst.lhs);
2033 const end = try sema.resolveInst(bin_inst.rhs);
19922034
19932035 switch (start.ty.zigTypeTag()) {
19942036 .Int, .ComptimeInt => {},
......@@ -2002,7 +2044,7 @@ fn zirSwitchRange(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
20022044 const start_val = start.value().?;
20032045 const end_val = end.value().?;
20042046 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", .{});
20062048 }
20072049 return sema.mod.constVoid(sema.arena, .unneeded);
20082050}
......@@ -2018,32 +2060,32 @@ fn zirSwitchBr(
20182060
20192061 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);
20222064 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)
20242066 else
20252067 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| {
20292071 for (inst.positionals.cases) |case| {
2030 const resolved = sema.resolveInst(block, case.item);
2031 const casted = try sema.coerce(scope, target.ty, resolved);
2072 const resolved = try sema.resolveInst(case.item);
2073 const casted = try sema.coerce(block, target.ty, resolved, resolved_src);
20322074 const item = try sema.resolveConstValue(parent_block, case_src, casted);
20332075
20342076 if (target_val.eql(item)) {
2035 try sema.analyzeBody(scope.cast(Scope.Block).?, case.body);
2036 return mod.constNoReturn(scope, inst.base.src);
2077 try sema.analyzeBody(parent_block, case.body);
2078 return sema.mod.constNoReturn(sema.arena, inst.base.src);
20372079 }
20382080 }
2039 try sema.analyzeBody(scope.cast(Scope.Block).?, inst.positionals.else_body);
2040 return mod.constNoReturn(scope, inst.base.src);
2081 try sema.analyzeBody(parent_block, inst.positionals.else_body);
2082 return sema.mod.constNoReturn(sema.arena, inst.base.src);
20412083 }
20422084
20432085 if (inst.positionals.cases.len == 0) {
20442086 // no cases just analyze else_branch
2045 try sema.analyzeBody(scope.cast(Scope.Block).?, inst.positionals.else_body);
2046 return mod.constNoReturn(scope, inst.base.src);
2087 try sema.analyzeBody(parent_block, inst.positionals.else_body);
2088 return sema.mod.constNoReturn(sema.arena, inst.base.src);
20472089 }
20482090
20492091 try sema.requireRuntimeBlock(parent_block, inst.base.src);
......@@ -2051,24 +2093,20 @@ fn zirSwitchBr(
20512093
20522094 var case_block: Scope.Block = .{
20532095 .parent = parent_block,
2054 .inst_table = parent_block.inst_table,
2055 .func = parent_block.func,
2056 .owner_decl = parent_block.owner_decl,
2096 .sema = sema,
20572097 .src_decl = parent_block.src_decl,
20582098 .instructions = .{},
2059 .arena = sema.arena,
20602099 .inlining = parent_block.inlining,
20612100 .is_comptime = parent_block.is_comptime,
2062 .branch_quota = parent_block.branch_quota,
20632101 };
2064 defer case_block.instructions.deinit(mod.gpa);
2102 defer case_block.instructions.deinit(sema.gpa);
20652103
20662104 for (inst.positionals.cases) |case, i| {
20672105 // Reset without freeing.
20682106 case_block.instructions.items.len = 0;
20692107
2070 const resolved = sema.resolveInst(block, case.item);
2071 const casted = try sema.coerce(scope, target.ty, resolved);
2108 const resolved = try sema.resolveInst(case.item);
2109 const casted = try sema.coerce(block, target.ty, resolved, resolved_src);
20722110 const item = try sema.resolveConstValue(parent_block, case_src, casted);
20732111
20742112 try sema.analyzeBody(&case_block, case.body);
......@@ -2113,15 +2151,15 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
21132151 .ErrorSet => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .ErrorSet", .{}),
21142152 .Union => return sema.mod.fail(&block.base, inst.base.src, "TODO validateSwitch .Union", .{}),
21152153 .Int, .ComptimeInt => {
2116 var range_set = @import("RangeSet.zig").init(mod.gpa);
2154 var range_set = @import("RangeSet.zig").init(sema.gpa);
21172155 defer range_set.deinit();
21182156
21192157 for (inst.positionals.items) |item| {
21202158 const maybe_src = if (item.castTag(.switch_range)) |range| blk: {
2121 const start_resolved = sema.resolveInst(block, range.positionals.lhs);
2122 const start_casted = try sema.coerce(scope, target.ty, start_resolved);
2123 const end_resolved = sema.resolveInst(block, range.positionals.rhs);
2124 const end_casted = try sema.coerce(scope, target.ty, end_resolved);
2159 const start_resolved = try sema.resolveInst(range.positionals.lhs);
2160 const start_casted = try sema.coerce(block, target.ty, start_resolved);
2161 const end_resolved = try sema.resolveInst(range.positionals.rhs);
2162 const end_casted = try sema.coerce(block, target.ty, end_resolved);
21252163
21262164 break :blk try range_set.add(
21272165 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
21292167 item.src,
21302168 );
21312169 } else blk: {
2132 const resolved = sema.resolveInst(block, item);
2133 const casted = try sema.coerce(scope, target.ty, resolved);
2170 const resolved = try sema.resolveInst(item);
2171 const casted = try sema.coerce(block, target.ty, resolved);
21342172 const value = try sema.resolveConstValue(block, item_src, casted);
21352173 break :blk try range_set.add(value, value, item.src);
21362174 };
......@@ -2142,7 +2180,7 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
21422180 }
21432181
21442182 if (target.ty.zigTypeTag() == .Int) {
2145 var arena = std.heap.ArenaAllocator.init(mod.gpa);
2183 var arena = std.heap.ArenaAllocator.init(sema.gpa);
21462184 defer arena.deinit();
21472185
21482186 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
21632201 var true_count: u8 = 0;
21642202 var false_count: u8 = 0;
21652203 for (inst.positionals.items) |item| {
2166 const resolved = sema.resolveInst(block, item);
2167 const casted = try sema.coerce(scope, Type.initTag(.bool), resolved);
2204 const resolved = try sema.resolveInst(item);
2205 const casted = try sema.coerce(block, Type.initTag(.bool), resolved);
21682206 if ((try sema.resolveConstValue(block, item_src, casted)).toBool()) {
21692207 true_count += 1;
21702208 } else {
......@@ -2187,12 +2225,12 @@ fn validateSwitch(sema: *Sema, block: *Scope.Block, target: *Inst, inst: zir.Ins
21872225 return sema.mod.fail(&block.base, inst.base.src, "else prong required when switching on type '{}'", .{target.ty});
21882226 }
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);
21912229 defer seen_values.deinit();
21922230
21932231 for (inst.positionals.items) |item| {
2194 const resolved = sema.resolveInst(block, item);
2195 const casted = try sema.coerce(scope, target.ty, resolved);
2232 const resolved = try sema.resolveInst(item);
2233 const casted = try sema.coerce(block, target.ty, resolved);
21962234 const val = try sema.resolveConstValue(block, item_src, casted);
21972235
21982236 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!
22492287fn zirShl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
22502288 const tracy = trace(@src());
22512289 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", .{});
22532291}
22542292
22552293fn zirShr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
22562294 const tracy = trace(@src());
22572295 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", .{});
22592297}
22602298
22612299fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
22622300 const tracy = trace(@src());
22632301 defer tracy.end();
22642302
2303 if (true) @panic("TODO rework with zir-memory-layout in mind");
2304
22652305 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2266 const lhs = sema.resolveInst(bin_inst.lhs);
2267 const rhs = sema.resolveInst(bin_inst.rhs);
2306 const src: LazySrcLoc = .todo;
2307 const lhs = try sema.resolveInst(bin_inst.lhs);
2308 const rhs = try sema.resolveInst(bin_inst.rhs);
22682309
22692310 const instructions = &[_]*Inst{ lhs, rhs };
22702311 const resolved_type = try sema.resolvePeerTypes(block, instructions);
2271 const casted_lhs = try sema.coerce(scope, resolved_type, lhs);
2272 const casted_rhs = try sema.coerce(scope, resolved_type, rhs);
2312 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);
2313 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);
22732314
22742315 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
22752316 resolved_type.elemType()
......@@ -2280,14 +2321,14 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
22802321
22812322 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
22822323 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}", .{
22842325 lhs.ty.arrayLen(),
22852326 rhs.ty.arrayLen(),
22862327 });
22872328 }
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", .{});
22892330 } 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 '{}'", .{
22912332 lhs.ty,
22922333 rhs.ty,
22932334 });
......@@ -2296,22 +2337,22 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
22962337 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
22972338
22982339 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()) });
23002341 }
23012342
23022343 if (casted_lhs.value()) |lhs_val| {
23032344 if (casted_rhs.value()) |rhs_val| {
23042345 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, .{
23062347 .ty = resolved_type,
23072348 .val = Value.initTag(.undef),
23082349 });
23092350 }
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", .{});
23112352 }
23122353 }
23132354
2314 try sema.requireRuntimeBlock(block, inst.base.src);
2355 try sema.requireRuntimeBlock(block, src);
23152356 const ir_tag = switch (inst.base.tag) {
23162357 .bit_and => Inst.Tag.bit_and,
23172358 .bit_or => Inst.Tag.bit_or,
......@@ -2319,39 +2360,42 @@ fn zirBitwise(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
23192360 else => unreachable,
23202361 };
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);
23232364}
23242365
23252366fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
23262367 const tracy = trace(@src());
23272368 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", .{});
23292370}
23302371
23312372fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
23322373 const tracy = trace(@src());
23332374 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", .{});
23352376}
23362377
23372378fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
23382379 const tracy = trace(@src());
23392380 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", .{});
23412382}
23422383
23432384fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
23442385 const tracy = trace(@src());
23452386 defer tracy.end();
23462387
2388 if (true) @panic("TODO rework with zir-memory-layout in mind");
2389
23472390 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2348 const lhs = sema.resolveInst(bin_inst.lhs);
2349 const rhs = sema.resolveInst(bin_inst.rhs);
2391 const src: LazySrcLoc = .todo;
2392 const lhs = try sema.resolveInst(bin_inst.lhs);
2393 const rhs = try sema.resolveInst(bin_inst.rhs);
23502394
23512395 const instructions = &[_]*Inst{ lhs, rhs };
23522396 const resolved_type = try sema.resolvePeerTypes(block, instructions);
2353 const casted_lhs = try sema.coerce(scope, resolved_type, lhs);
2354 const casted_rhs = try sema.coerce(scope, resolved_type, rhs);
2397 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src);
2398 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src);
23552399
23562400 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
23572401 resolved_type.elemType()
......@@ -2362,14 +2406,14 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
23622406
23632407 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
23642408 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}", .{
23662410 lhs.ty.arrayLen(),
23672411 rhs.ty.arrayLen(),
23682412 });
23692413 }
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", .{});
23712415 } 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 '{}'", .{
23732417 lhs.ty,
23742418 rhs.ty,
23752419 });
......@@ -2379,22 +2423,22 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
23792423 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
23802424
23812425 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()) });
23832427 }
23842428
23852429 if (casted_lhs.value()) |lhs_val| {
23862430 if (casted_rhs.value()) |rhs_val| {
23872431 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, .{
23892433 .ty = resolved_type,
23902434 .val = Value.initTag(.undef),
23912435 });
23922436 }
2393 return analyzeInstComptimeOp(mod, scope, scalar_type, inst, lhs_val, rhs_val);
2437 return sema.analyzeInstComptimeOp(block, scalar_type, inst, lhs_val, rhs_val);
23942438 }
23952439 }
23962440
2397 try sema.requireRuntimeBlock(block, inst.base.src);
2441 try sema.requireRuntimeBlock(block, src);
23982442 const ir_tag: Inst.Tag = switch (inst.base.tag) {
23992443 .add => .add,
24002444 .addwrap => .addwrap,
......@@ -2402,18 +2446,27 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
24022446 .subwrap => .subwrap,
24032447 .mul => .mul,
24042448 .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)}),
24062450 };
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);
24092453}
24102454
24112455/// 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
24132466 // incase rhs is 0, simply return lhs without doing any calculations
24142467 // TODO Once division is implemented we should throw an error when dividing by 0.
24152468 if (rhs_val.compareWithZero(.eq)) {
2416 return sema.mod.constInst(scope, inst.base.src, .{
2469 return sema.mod.constInst(sema.arena, inst.base.src, .{
24172470 .ty = res_type,
24182471 .val = lhs_val,
24192472 });
......@@ -2425,14 +2478,14 @@ fn analyzeInstComptimeOp(sema: *Sema, block: *Scope.Block, res_type: Type, inst:
24252478 const val = if (is_int)
24262479 try Module.intAdd(sema.arena, lhs_val, rhs_val)
24272480 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);
24292482 break :blk val;
24302483 },
24312484 .sub => blk: {
24322485 const val = if (is_int)
24332486 try Module.intSub(sema.arena, lhs_val, rhs_val)
24342487 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);
24362489 break :blk val;
24372490 },
24382491 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:
24402493
24412494 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, .{
24442497 .ty = res_type,
24452498 .val = value,
24462499 });
24472500}
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 {
24502503 const tracy = trace(@src());
24512504 defer tracy.end();
24522505
24532506 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
24542507 const src = inst_data.src();
24552508 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);
24572510 return sema.analyzeDeref(block, src, ptr, ptr_src);
24582511}
24592512
24602513fn zirAsm(
24612514 sema: *Sema,
24622515 block: *Scope.Block,
2463 assembly: zir.Inst.Index,
2516 inst: zir.Inst.Index,
24642517 is_volatile: bool,
24652518) InnerError!*Inst {
24662519 const tracy = trace(@src());
......@@ -2475,23 +2528,24 @@ fn zirAsm(
24752528 const asm_source = try sema.resolveConstString(block, asm_source_src, extra.data.asm_source);
24762529
24772530 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: {
24792533 const name = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
24802534 extra_i += 1;
2481 break :blk .{
2535 break :blk Output{
24822536 .name = name,
2483 .inst = try sema.resolveInst(block, extra.data.output),
2537 .inst = try sema.resolveInst(extra.data.output),
24842538 };
24852539 } 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);
24882542 const inputs = try sema.arena.alloc([]const u8, extra.data.args_len);
24892543 const clobbers = try sema.arena.alloc([]const u8, extra.data.clobbers_len);
24902544
24912545 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]);
24932547 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);
24952549 }
24962550 for (inputs) |*name| {
24972551 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
......@@ -2503,8 +2557,8 @@ fn zirAsm(
25032557 }
25042558
25052559 try sema.requireRuntimeBlock(block, src);
2506 const inst = try sema.arena.create(Inst.Assembly);
2507 inst.* = .{
2560 const asm_tzir = try sema.arena.create(Inst.Assembly);
2561 asm_tzir.* = .{
25082562 .base = .{
25092563 .tag = .assembly,
25102564 .ty = return_type,
......@@ -2518,8 +2572,8 @@ fn zirAsm(
25182572 .clobbers = clobbers,
25192573 .args = args,
25202574 };
2521 try block.instructions.append(mod.gpa, &inst.base);
2522 return &inst.base;
2575 try block.instructions.append(sema.gpa, &asm_tzir.base);
2576 return &asm_tzir.base;
25232577}
25242578
25252579fn zirCmp(
......@@ -2531,9 +2585,10 @@ fn zirCmp(
25312585 const tracy = trace(@src());
25322586 defer tracy.end();
25332587
2588 const src: LazySrcLoc = .todo;
25342589 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2535 const lhs = sema.resolveInst(bin_inst.lhs);
2536 const rhs = sema.resolveInst(bin_inst.rhs);
2590 const lhs = try sema.resolveInst(bin_inst.lhs);
2591 const rhs = try sema.resolveInst(bin_inst.rhs);
25372592
25382593 const is_equality_cmp = switch (op) {
25392594 .eq, .neq => true,
......@@ -2543,50 +2598,50 @@ fn zirCmp(
25432598 const rhs_ty_tag = rhs.ty.zigTypeTag();
25442599 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
25452600 // 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);
25472602 } else if (is_equality_cmp and
25482603 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or
25492604 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))
25502605 {
25512606 // comparing null with optionals
25522607 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);
25542609 } else if (is_equality_cmp and
25552610 ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr())))
25562611 {
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", .{});
25582613 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
25592614 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});
25612616 } else if (is_equality_cmp and
25622617 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or
25632618 (rhs_ty_tag == .EnumLiteral and lhs_ty_tag == .Union)))
25642619 {
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", .{});
25662621 } else if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) {
25672622 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)});
25692624 }
25702625 if (rhs.value()) |rval| {
25712626 if (lhs.value()) |lval| {
25722627 // 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));
25742629 }
25752630 }
2576 try sema.requireRuntimeBlock(block, inst.base.src);
2577 return mod.addBinOp(b, inst.base.src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);
2631 try sema.requireRuntimeBlock(block, src);
2632 return block.addBinOp(src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);
25782633 } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) {
25792634 // This operation allows any combination of integer and float types, regardless of the
25802635 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
25812636 // numeric types.
2582 return mod.cmpNumeric(scope, inst.base.src, lhs, rhs, op);
2637 return sema.cmpNumeric(block, src, lhs, rhs, op);
25832638 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
25842639 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)});
25862641 }
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));
25882643 }
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", .{});
25902645}
25912646
25922647fn 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!
25942649 defer tracy.end();
25952650
25962651 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);
25982653 return sema.mod.constType(sema.arena, inst_data.src(), operand.ty);
25992654}
26002655
......@@ -2606,18 +2661,14 @@ fn zirTypeofPeer(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr
26062661 const src = inst_data.src();
26072662 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);
2610 defer mod.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);
2664 const inst_list = try sema.gpa.alloc(*ir.Inst, extra.data.operands_len);
2665 defer sema.gpa.free(inst_list);
26142666
26152667 for (sema.code.extra[extra.end..][0..extra.data.operands_len]) |arg_ref, i| {
2616 inst_list[i] = sema.resolveInst(block, arg_ref);
2617 src_list[i] = .{ .node_offset_builtin_call_argn = inst_data.src_node };
2668 inst_list[i] = try sema.resolveInst(arg_ref);
26182669 }
26192670
2620 const result_type = try sema.resolvePeerTypes(block, inst_list, src_list);
2671 const result_type = try sema.resolvePeerTypes(block, inst_list);
26212672 return sema.mod.constType(sema.arena, src, result_type);
26222673}
26232674
......@@ -2627,12 +2678,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
26272678
26282679 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
26292680 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
26322683 const bool_type = Type.initTag(.bool);
2633 const operand = try sema.coerce(scope, bool_type, uncasted_operand);
2634 if (try mod.resolveDefinedValue(scope, operand)) |val| {
2635 return mod.constBool(sema.arena, src, !val.toBool());
2684 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);
2685 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
2686 return sema.mod.constBool(sema.arena, src, !val.toBool());
26362687 }
26372688 try sema.requireRuntimeBlock(block, src);
26382689 return block.addUnOp(src, bool_type, .not, operand);
......@@ -2647,25 +2698,26 @@ fn zirBoolOp(
26472698 const tracy = trace(@src());
26482699 defer tracy.end();
26492700
2701 const src: LazySrcLoc = .unneeded;
26502702 const bool_type = Type.initTag(.bool);
26512703 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2652 const uncasted_lhs = sema.resolveInst(bin_inst.lhs);
2653 const lhs = try sema.coerce(scope, bool_type, uncasted_lhs);
2654 const uncasted_rhs = sema.resolveInst(bin_inst.rhs);
2655 const rhs = try sema.coerce(scope, bool_type, uncasted_rhs);
2704 const uncasted_lhs = try sema.resolveInst(bin_inst.lhs);
2705 const lhs = try sema.coerce(block, bool_type, uncasted_lhs, uncasted_lhs.src);
2706 const uncasted_rhs = try sema.resolveInst(bin_inst.rhs);
2707 const rhs = try sema.coerce(block, bool_type, uncasted_rhs, uncasted_rhs.src);
26562708
26572709 if (lhs.value()) |lhs_val| {
26582710 if (rhs.value()) |rhs_val| {
26592711 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());
26612713 } 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());
26632715 }
26642716 }
26652717 }
2666 try sema.requireRuntimeBlock(block, inst.base.src);
2718 try sema.requireRuntimeBlock(block, src);
26672719 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);
26692721}
26702722
26712723fn zirIsNull(
......@@ -2679,7 +2731,7 @@ fn zirIsNull(
26792731
26802732 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
26812733 const src = inst_data.src();
2682 const operand = sema.resolveInst(block, inst_data.operand);
2734 const operand = try sema.resolveInst(inst_data.operand);
26832735 return sema.analyzeIsNull(block, src, operand, invert_logic);
26842736}
26852737
......@@ -2694,7 +2746,7 @@ fn zirIsNullPtr(
26942746
26952747 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
26962748 const src = inst_data.src();
2697 const ptr = sema.resolveInst(block, inst_data.operand);
2749 const ptr = try sema.resolveInst(inst_data.operand);
26982750 const loaded = try sema.analyzeDeref(block, src, ptr, src);
26992751 return sema.analyzeIsNull(block, src, loaded, invert_logic);
27002752}
......@@ -2704,8 +2756,8 @@ fn zirIsErr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
27042756 defer tracy.end();
27052757
27062758 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
2707 const operand = sema.resolveInst(block, inst_data.operand);
2708 return mod.analyzeIsErr(scope, inst_data.src(), operand);
2759 const operand = try sema.resolveInst(inst_data.operand);
2760 return sema.analyzeIsErr(block, inst_data.src(), operand);
27092761}
27102762
27112763fn 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
27142766
27152767 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
27162768 const src = inst_data.src();
2717 const ptr = sema.resolveInst(block, inst_data.operand);
2769 const ptr = try sema.resolveInst(inst_data.operand);
27182770 const loaded = try sema.analyzeDeref(block, src, ptr, src);
2719 return mod.analyzeIsErr(scope, src, loaded);
2771 return sema.analyzeIsErr(block, src, loaded);
27202772}
27212773
27222774fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
27232775 const tracy = trace(@src());
27242776 defer tracy.end();
27252777
2726 const uncasted_cond = sema.resolveInst(block, inst.positionals.condition);
2727 const cond = try sema.coerce(scope, Type.initTag(.bool), uncasted_cond);
2778 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
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| {
2730 const body = if (cond_val.toBool()) &inst.positionals.then_body else &inst.positionals.else_body;
2731 try sema.analyzeBody(parent_block, body.*);
2732 return mod.constNoReturn(scope, inst.base.src);
2786 const uncasted_cond = try sema.resolveInst(extra.data.condition);
2787 const cond = try sema.coerce(parent_block, Type.initTag(.bool), uncasted_cond, cond_src);
2788
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);
27332793 }
27342794
27352795 var true_block: Scope.Block = .{
27362796 .parent = parent_block,
2737 .inst_table = parent_block.inst_table,
2738 .func = parent_block.func,
2739 .owner_decl = parent_block.owner_decl,
2797 .sema = sema,
27402798 .src_decl = parent_block.src_decl,
27412799 .instructions = .{},
2742 .arena = sema.arena,
27432800 .inlining = parent_block.inlining,
27442801 .is_comptime = parent_block.is_comptime,
2745 .branch_quota = parent_block.branch_quota,
27462802 };
2747 defer true_block.instructions.deinit(mod.gpa);
2748 try sema.analyzeBody(&true_block, inst.positionals.then_body);
2803 defer true_block.instructions.deinit(sema.gpa);
2804 try sema.analyzeBody(&true_block, then_body);
27492805
27502806 var false_block: Scope.Block = .{
27512807 .parent = parent_block,
2752 .inst_table = parent_block.inst_table,
2753 .func = parent_block.func,
2754 .owner_decl = parent_block.owner_decl,
2808 .sema = sema,
27552809 .src_decl = parent_block.src_decl,
27562810 .instructions = .{},
2757 .arena = sema.arena,
27582811 .inlining = parent_block.inlining,
27592812 .is_comptime = parent_block.is_comptime,
2760 .branch_quota = parent_block.branch_quota,
27612813 };
2762 defer false_block.instructions.deinit(mod.gpa);
2763 try sema.analyzeBody(&false_block, inst.positionals.else_body);
2814 defer false_block.instructions.deinit(sema.gpa);
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) };
2766 const 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);
2817 const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, true_block.instructions.items) };
2818 const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, false_block.instructions.items) };
2819 return parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body);
27682820}
27692821
27702822fn zirUnreachable(
27712823 sema: *Sema,
27722824 block: *Scope.Block,
2773 zir_index: zir.Inst.Index,
2825 inst: zir.Inst.Index,
27742826 safety_check: bool,
27752827) InnerError!*Inst {
27762828 const tracy = trace(@src());
27772829 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);
27802834 // TODO Add compile error for @optimizeFor occurring too late in a scope.
27812835 if (safety_check and block.wantSafety()) {
2782 return mod.safetyPanic(b, zir_index.base.src, .unreach);
2836 return sema.safetyPanic(block, src, .unreach);
27832837 } else {
2784 return block.addNoOp(zir_index.base.src, Type.initTag(.noreturn), .unreach);
2838 return block.addNoOp(src, Type.initTag(.noreturn), .unreach);
27852839 }
27862840}
27872841
2788fn zirRetTok(sema: *Sema, block: *Scope.Block, zir_inst: zir.Inst.Index) InnerError!*Inst {
2789 @compileError("TODO");
2842fn zirRetTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
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);
27902862}
27912863
2792fn zirRetNode(sema: *Sema, block: *Scope.Block, zir_inst: zir.Inst.Index) InnerError!*Inst {
2793 @compileError("TODO");
2864fn analyzeRet(sema: *Sema, block: *Scope.Block, operand: *Inst, src: LazySrcLoc) InnerError!*Inst {
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);
27942874}
27952875
27962876fn floatOpAllowed(tag: zir.Inst.Tag) bool {
......@@ -2826,6 +2906,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
28262906 const tracy = trace(@src());
28272907 defer tracy.end();
28282908
2909 const src: LazySrcLoc = .unneeded;
28292910 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
28302911 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
28552936 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);
28562937 } else 0;
28572938
2858 if (bit_end != 0 and bit_offset >= bit_end * 8)
2859 return sema.mod.fail(&block.base, inst.base.src, "bit offset starts after end of host integer", .{});
2939 if (bit_end != 0 and bit_start >= bit_end * 8)
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(
2864 scope,
2944 const ty = try sema.mod.ptrType(
2945 sema.arena,
28652946 elem_type,
28662947 sentinel,
28672948 abi_align,
......@@ -2872,7 +2953,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
28722953 inst_data.flags.is_volatile,
28732954 inst_data.size,
28742955 );
2875 return sema.mod.constType(sema.arena, .unneeded, ty);
2956 return sema.mod.constType(sema.arena, src, ty);
28762957}
28772958
28782959fn 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
28922973}
28932974
28942975fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
2895 try sema.requireFunctionBlock(scope, src);
2976 try sema.requireFunctionBlock(block, src);
28962977 if (block.is_comptime) {
28972978 return sema.mod.fail(&block.base, src, "unable to resolve comptime value", .{});
28982979 }
......@@ -2900,7 +2981,7 @@ fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void
29002981
29012982fn validateVarType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {
29022983 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});
29042985 }
29052986}
29062987
......@@ -2939,20 +3020,16 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id:
29393020
29403021 var fail_block: Scope.Block = .{
29413022 .parent = parent_block,
2942 .inst_map = parent_block.inst_map,
2943 .func = parent_block.func,
2944 .owner_decl = parent_block.owner_decl,
3023 .sema = sema,
29453024 .src_decl = parent_block.src_decl,
29463025 .instructions = .{},
2947 .arena = sema.arena,
29483026 .inlining = parent_block.inlining,
29493027 .is_comptime = parent_block.is_comptime,
2950 .branch_quota = parent_block.branch_quota,
29513028 };
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
29573034 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:
29693046 };
29703047 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);
29733050}
29743051
29753052fn safetyPanic(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, panic_id: PanicId) !*Inst {
29763053 // 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);
2978 return mod.addNoOp(block, src, Type.initTag(.noreturn), .unreach);
3054 _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
3055 return block.addNoOp(src, Type.initTag(.noreturn), .unreach);
29793056}
29803057
29813058fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
......@@ -3002,16 +3079,16 @@ fn namedFieldPtr(
30023079 switch (elem_ty.zigTypeTag()) {
30033080 .Array => {
30043081 if (mem.eql(u8, field_name, "len")) {
3005 return mod.constInst(scope, src, .{
3082 return sema.mod.constInst(sema.arena, src, .{
30063083 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
30073084 .val = try Value.Tag.ref_val.create(
3008 scope.arena(),
3009 try Value.Tag.int_u64.create(scope.arena(), elem_ty.arrayLen()),
3085 sema.arena,
3086 try Value.Tag.int_u64.create(sema.arena, elem_ty.arrayLen()),
30103087 ),
30113088 });
30123089 } else {
3013 return mod.fail(
3014 scope,
3090 return sema.mod.fail(
3091 &block.base,
30153092 field_name_src,
30163093 "no member named '{s}' in '{}'",
30173094 .{ field_name, elem_ty },
......@@ -3023,16 +3100,16 @@ fn namedFieldPtr(
30233100 switch (ptr_child.zigTypeTag()) {
30243101 .Array => {
30253102 if (mem.eql(u8, field_name, "len")) {
3026 return mod.constInst(scope, src, .{
3103 return sema.mod.constInst(sema.arena, src, .{
30273104 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
30283105 .val = try Value.Tag.ref_val.create(
3029 scope.arena(),
3030 try Value.Tag.int_u64.create(scope.arena(), ptr_child.arrayLen()),
3106 sema.arena,
3107 try Value.Tag.int_u64.create(sema.arena, ptr_child.arrayLen()),
30313108 ),
30323109 });
30333110 } else {
3034 return mod.fail(
3035 scope,
3111 return sema.mod.fail(
3112 &block.base,
30363113 field_name_src,
30373114 "no member named '{s}' in '{}'",
30383115 .{ field_name, elem_ty },
......@@ -3043,10 +3120,10 @@ fn namedFieldPtr(
30433120 }
30443121 },
30453122 .Type => {
3046 _ = try sema.resolveConstValue(scope, object_ptr.src, object_ptr);
3123 _ = try sema.resolveConstValue(block, object_ptr.src, object_ptr);
30473124 const result = try sema.analyzeDeref(block, src, object_ptr, object_ptr.src);
30483125 const val = result.value().?;
3049 const child_type = try val.toType(scope.arena());
3126 const child_type = try val.toType(sema.arena);
30503127 switch (child_type.zigTypeTag()) {
30513128 .ErrorSet => {
30523129 var name: []const u8 = undefined;
......@@ -3054,18 +3131,18 @@ fn namedFieldPtr(
30543131 if (val.castTag(.error_set)) |payload|
30553132 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
30563133 else
3057 name = (try mod.getErrorValue(field_name)).key;
3134 name = (try sema.mod.getErrorValue(field_name)).key;
30583135
30593136 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)
30613138 else
30623139 child_type;
30633140
3064 return mod.constInst(scope, src, .{
3065 .ty = try mod.simplePtrType(scope.arena(), result_type, false, .One),
3141 return sema.mod.constInst(sema.arena, src, .{
3142 .ty = try sema.mod.simplePtrType(sema.arena, result_type, false, .One),
30663143 .val = try Value.Tag.ref_val.create(
3067 scope.arena(),
3068 try Value.Tag.@"error".create(scope.arena(), .{
3144 sema.arena,
3145 try Value.Tag.@"error".create(sema.arena, .{
30693146 .name = name,
30703147 }),
30713148 ),
......@@ -3073,12 +3150,12 @@ fn namedFieldPtr(
30733150 },
30743151 .Struct => {
30753152 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| {
30773154 // TODO if !decl.is_pub and inDifferentFiles() "{} is private"
30783155 return sema.analyzeDeclRef(block, src, decl);
30793156 }
30803157
3081 if (container_scope.file_scope == mod.root_scope) {
3158 if (container_scope.file_scope == sema.mod.root_scope) {
30823159 return sema.mod.fail(&block.base, src, "root source file has no member called '{s}'", .{field_name});
30833160 } else {
30843161 return sema.mod.fail(&block.base, src, "container '{}' has no member called '{s}'", .{ child_type, field_name });
......@@ -3117,11 +3194,11 @@ fn elemPtr(
31173194 const index_u64 = index_val.toUnsignedInt();
31183195 // @intCast here because it would have been impossible to construct a value that
31193196 // 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));
31213198 const pointee_type = elem_ty.elemType().elemType();
31223199
3123 return mod.constInst(scope, src, .{
3124 .ty = try Type.Tag.single_const_pointer.create(scope.arena(), pointee_type),
3200 return sema.mod.constInst(sema.arena, src, .{
3201 .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
31253202 .val = elem_ptr,
31263203 });
31273204 }
......@@ -3131,9 +3208,15 @@ fn elemPtr(
31313208 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{});
31323209}
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 {
31353218 if (dest_type.tag() == .var_args_param) {
3136 return sema.coerceVarArgParam(scope, inst);
3219 return sema.coerceVarArgParam(block, inst);
31373220 }
31383221 // If the types are the same, we can return the operand.
31393222 if (dest_type.eql(inst.ty))
......@@ -3141,20 +3224,20 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
31413224
31423225 const in_memory_result = coerceInMemoryAllowed(dest_type, inst.ty);
31433226 if (in_memory_result == .ok) {
3144 return sema.bitcast(scope, dest_type, inst);
3227 return sema.bitcast(block, dest_type, inst);
31453228 }
31463229
31473230 // undefined to anything
31483231 if (inst.value()) |val| {
31493232 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 });
31513234 }
31523235 }
31533236 assert(inst.ty.zigTypeTag() != .Undefined);
31543237
31553238 // null to ?T
31563239 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) });
31583241 }
31593242
31603243 // T to ?T
......@@ -3162,15 +3245,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
31623245 var buf: Type.Payload.ElemType = undefined;
31633246 const child_type = dest_type.optionalChild(&buf);
31643247 if (child_type.eql(inst.ty)) {
3165 return mod.wrapOptional(scope, dest_type, inst);
3166 } else if (try sema.coerceNum(scope, child_type, inst)) |some| {
3167 return mod.wrapOptional(scope, dest_type, some);
3248 return sema.wrapOptional(block, dest_type, inst);
3249 } else if (try sema.coerceNum(block, child_type, inst)) |some| {
3250 return sema.wrapOptional(block, dest_type, some);
31683251 }
31693252 }
31703253
31713254 // T to E!T or E to E!T
31723255 if (dest_type.tag() == .error_union) {
3173 return try mod.wrapErrorUnion(scope, dest_type, inst);
3256 return try sema.wrapErrorUnion(block, dest_type, inst);
31743257 }
31753258
31763259 // 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
31913274 switch (dest_type.ptrSize()) {
31923275 .Slice => {
31933276 // *[N]T to []T
3194 return sema.coerceArrayPtrToSlice(scope, dest_type, inst);
3277 return sema.coerceArrayPtrToSlice(block, dest_type, inst);
31953278 },
31963279 .C => {
31973280 // *[N]T to [*c]T
3198 return sema.coerceArrayPtrToMany(scope, dest_type, inst);
3281 return sema.coerceArrayPtrToMany(block, dest_type, inst);
31993282 },
32003283 .Many => {
32013284 // *[N]T to [*]T
......@@ -3203,12 +3286,12 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
32033286 const src_sentinel = array_type.sentinel();
32043287 const dst_sentinel = dest_type.sentinel();
32053288 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
32083291 if (src_sentinel) |src_s| {
32093292 if (dst_sentinel) |dst_s| {
32103293 if (src_s.eql(dst_s)) {
3211 return sema.coerceArrayPtrToMany(scope, dest_type, inst);
3294 return sema.coerceArrayPtrToMany(block, dest_type, inst);
32123295 }
32133296 }
32143297 }
......@@ -3218,21 +3301,23 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
32183301 }
32193302
32203303 // 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|
32223305 return some;
32233306
3307 const target = sema.mod.getTarget();
3308
32243309 // integer widening
32253310 if (inst.ty.zigTypeTag() == .Int and dest_type.zigTypeTag() == .Int) {
32263311 assert(inst.value() == null); // handled above
32273312
3228 const src_info = inst.ty.intInfo(mod.getTarget());
3229 const dst_info = dest_type.intInfo(mod.getTarget());
3313 const src_info = inst.ty.intInfo(target);
3314 const dst_info = dest_type.intInfo(target);
32303315 if ((src_info.signedness == dst_info.signedness and dst_info.bits >= src_info.bits) or
32313316 // small enough unsigned ints can get casted to large enough signed ints
32323317 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))
32333318 {
3234 try sema.requireRuntimeBlock(block, inst.src);
3235 return mod.addUnOp(b, inst.src, dest_type, .intcast, inst);
3319 try sema.requireRuntimeBlock(block, inst_src);
3320 return block.addUnOp(inst_src, dest_type, .intcast, inst);
32363321 }
32373322 }
32383323
......@@ -3240,15 +3325,15 @@ fn coerce(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) InnerE
32403325 if (inst.ty.zigTypeTag() == .Float and dest_type.zigTypeTag() == .Float) {
32413326 assert(inst.value() == null); // handled above
32423327
3243 const src_bits = inst.ty.floatBits(mod.getTarget());
3244 const dst_bits = dest_type.floatBits(mod.getTarget());
3328 const src_bits = inst.ty.floatBits(target);
3329 const dst_bits = dest_type.floatBits(target);
32453330 if (dst_bits >= src_bits) {
3246 try sema.requireRuntimeBlock(block, inst.src);
3247 return mod.addUnOp(b, inst.src, dest_type, .floatcast, inst);
3331 try sema.requireRuntimeBlock(block, inst_src);
3332 return block.addUnOp(inst_src, dest_type, .floatcast, inst);
32483333 }
32493334 }
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 });
32523337}
32533338
32543339const InMemoryCoercionResult = enum {
......@@ -3270,6 +3355,8 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn
32703355 const src_zig_tag = inst.ty.zigTypeTag();
32713356 const dst_zig_tag = dest_type.zigTypeTag();
32723357
3358 const target = sema.mod.getTarget();
3359
32733360 if (dst_zig_tag == .ComptimeInt or dst_zig_tag == .Int) {
32743361 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
32753362 if (val.floatHasFraction()) {
......@@ -3277,23 +3364,23 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) Inn
32773364 }
32783365 return sema.mod.fail(&block.base, inst.src, "TODO float to int", .{});
32793366 } 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)) {
32813368 return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });
32823369 }
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 });
32843371 }
32853372 } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) {
32863373 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) {
3288 error.Overflow => return mod.fail(
3289 scope,
3374 const res = val.floatCast(sema.arena, dest_type, target) catch |err| switch (err) {
3375 error.Overflow => return sema.mod.fail(
3376 &block.base,
32903377 inst.src,
32913378 "cast of value {} to type '{}' loses information",
32923379 .{ val, dest_type },
32933380 ),
32943381 error.OutOfMemory => return error.OutOfMemory,
32953382 };
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 });
32973384 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
32983385 return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{});
32993386 }
......@@ -3310,12 +3397,18 @@ fn coerceVarArgParam(sema: *Sema, block: *Scope.Block, inst: *Inst) !*Inst {
33103397 return inst;
33113398}
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 {
33143407 if (ptr.ty.isConstPtr())
33153408 return sema.mod.fail(&block.base, src, "cannot assign to constant", .{});
33163409
33173410 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);
33193412 if (elem_ty.onePossibleValue() != null)
33203413 return sema.mod.constVoid(sema.arena, .unneeded);
33213414
......@@ -3323,23 +3416,23 @@ fn storePtr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ptr: *Inst, uncas
33233416 // TODO handle if the element type requires comptime
33243417
33253418 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);
33273420}
33283421
33293422fn bitcast(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
33303423 if (inst.value()) |val| {
33313424 // 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 });
33333426 }
33343427 // TODO validate the type size and other compile errors
33353428 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);
33373430}
33383431
33393432fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
33403433 if (inst.value()) |val| {
33413434 // 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 });
33433436 }
33443437 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
33453438}
......@@ -3347,7 +3440,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst
33473440fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
33483441 if (inst.value()) |val| {
33493442 // 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 });
33513444 }
33523445 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});
33533446}
......@@ -3358,44 +3451,39 @@ fn analyzeDeclVal(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl
33583451}
33593452
33603453fn analyzeDeclRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, decl: *Decl) InnerError!*Inst {
3361 const scope_decl = scope.ownerDecl().?;
3362 try mod.declareDeclDependency(scope_decl, decl);
3363 mod.ensureDeclAnalyzed(decl) catch |err| {
3364 if (scope.cast(Scope.Block)) |block| {
3365 if (block.func) |func| {
3366 func.state = .dependency_failure;
3367 } else {
3368 block.owner_decl.analysis = .dependency_failure;
3369 }
3454 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
3455 sema.mod.ensureDeclAnalyzed(decl) catch |err| {
3456 if (sema.func) |func| {
3457 func.state = .dependency_failure;
33703458 } else {
3371 scope_decl.analysis = .dependency_failure;
3459 sema.owner_decl.analysis = .dependency_failure;
33723460 }
33733461 return err;
33743462 };
33753463
33763464 const decl_tv = try decl.typedValue();
33773465 if (decl_tv.val.tag() == .variable) {
3378 return mod.analyzeVarRef(scope, src, decl_tv);
3466 return sema.analyzeVarRef(block, src, decl_tv);
33793467 }
3380 return mod.constInst(scope.arena(), src, .{
3381 .ty = try mod.simplePtrType(scope.arena(), decl_tv.ty, false, .One),
3382 .val = try Value.Tag.decl_ref.create(scope.arena(), decl),
3468 return sema.mod.constInst(sema.arena, src, .{
3469 .ty = try sema.mod.simplePtrType(sema.arena, decl_tv.ty, false, .One),
3470 .val = try Value.Tag.decl_ref.create(sema.arena, decl),
33833471 });
33843472}
33853473
33863474fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedValue) InnerError!*Inst {
33873475 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);
33903478 if (!variable.is_mutable and !variable.is_extern) {
3391 return mod.constInst(scope.arena(), src, .{
3479 return sema.mod.constInst(sema.arena, src, .{
33923480 .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),
33943482 });
33953483 }
33963484
33973485 try sema.requireRuntimeBlock(block, src);
3398 const inst = try b.arena.create(Inst.VarPtr);
3486 const inst = try sema.arena.create(Inst.VarPtr);
33993487 inst.* = .{
34003488 .base = .{
34013489 .tag = .varptr,
......@@ -3404,7 +3492,7 @@ fn analyzeVarRef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, tv: TypedVal
34043492 },
34053493 .variable = variable,
34063494 };
3407 try b.instructions.append(mod.gpa, &inst.base);
3495 try block.instructions.append(sema.gpa, &inst.base);
34083496 return &inst.base;
34093497}
34103498
......@@ -3414,12 +3502,12 @@ fn analyzeRef(
34143502 src: LazySrcLoc,
34153503 operand: *Inst,
34163504) 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
34193507 if (operand.value()) |val| {
3420 return mod.constInst(scope.arena(), src, .{
3508 return sema.mod.constInst(sema.arena, src, .{
34213509 .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),
34233511 });
34243512 }
34253513
......@@ -3439,14 +3527,14 @@ fn analyzeDeref(
34393527 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr.ty}),
34403528 };
34413529 if (ptr.value()) |val| {
3442 return mod.constInst(scope.arena(), src, .{
3530 return sema.mod.constInst(sema.arena, src, .{
34433531 .ty = elem_ty,
3444 .val = try val.pointerDeref(scope.arena()),
3532 .val = try val.pointerDeref(sema.arena),
34453533 });
34463534 }
34473535
34483536 try sema.requireRuntimeBlock(block, src);
3449 return mod.addUnOp(b, src, elem_ty, .load, ptr);
3537 return block.addUnOp(src, elem_ty, .load, ptr);
34503538}
34513539
34523540fn analyzeIsNull(
......@@ -3459,23 +3547,23 @@ fn analyzeIsNull(
34593547 if (operand.value()) |opt_val| {
34603548 const is_null = opt_val.isNull();
34613549 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);
34633551 }
34643552 try sema.requireRuntimeBlock(block, src);
34653553 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);
34673555}
34683556
34693557fn analyzeIsErr(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, operand: *Inst) InnerError!*Inst {
34703558 const ot = operand.ty.zigTypeTag();
3471 if (ot != .ErrorSet and ot != .ErrorUnion) return mod.constBool(sema.arena, src, false);
3472 if (ot == .ErrorSet) return mod.constBool(sema.arena, src, true);
3559 if (ot != .ErrorSet and ot != .ErrorUnion) return sema.mod.constBool(sema.arena, src, false);
3560 if (ot == .ErrorSet) return sema.mod.constBool(sema.arena, src, true);
34733561 assert(ot == .ErrorUnion);
34743562 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);
34763564 }
34773565 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);
34793567}
34803568
34813569fn analyzeSlice(
......@@ -3511,7 +3599,7 @@ fn analyzeSlice(
35113599 };
35123600
35133601 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);
35153603 break :blk try sema.resolveConstValue(block, sentinel_src, casted);
35163604 } else null;
35173605
......@@ -3531,13 +3619,13 @@ fn analyzeSlice(
35313619 array_type.sentinel()
35323620 else
35333621 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);
35353623 return_ptr_size = .One;
35363624 }
35373625 }
35383626 }
3539 const return_type = try mod.ptrType(
3540 scope,
3627 const return_type = try sema.mod.ptrType(
3628 sema.arena,
35413629 return_elem_type,
35423630 if (end_opt == null) slice_sentinel else null,
35433631 0, // TODO alignment
......@@ -3553,24 +3641,24 @@ fn analyzeSlice(
35533641}
35543642
35553643fn 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;
35573645 const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse ".";
35583646 const found_pkg = cur_pkg.table.get(target_string);
35593647
35603648 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 })
35623650 else
3563 try std.fs.path.resolve(mod.gpa, &[_][]const u8{ cur_pkg_dir_path, target_string });
3564 errdefer mod.gpa.free(resolved_path);
3651 try std.fs.path.resolve(sema.gpa, &[_][]const u8{ cur_pkg_dir_path, target_string });
3652 errdefer sema.gpa.free(resolved_path);
35653653
3566 if (mod.import_table.get(resolved_path)) |some| {
3567 mod.gpa.free(resolved_path);
3654 if (sema.mod.import_table.get(resolved_path)) |some| {
3655 sema.gpa.free(resolved_path);
35683656 return some;
35693657 }
35703658
35713659 if (found_pkg == null) {
3572 const resolved_root_path = try std.fs.path.resolve(mod.gpa, &[_][]const u8{cur_pkg_dir_path});
3573 defer mod.gpa.free(resolved_root_path);
3660 const resolved_root_path = try std.fs.path.resolve(sema.gpa, &[_][]const u8{cur_pkg_dir_path});
3661 defer sema.gpa.free(resolved_root_path);
35743662
35753663 if (!mem.startsWith(u8, resolved_path, resolved_root_path)) {
35763664 return error.ImportOutsidePkgPath;
......@@ -3578,10 +3666,10 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin
35783666 }
35793667
35803668 // TODO Scope.Container arena for ty and sub_file_path
3581 const file_scope = try mod.gpa.create(Scope.File);
3582 errdefer mod.gpa.destroy(file_scope);
3583 const struct_ty = try Type.Tag.empty_struct.create(mod.gpa, &file_scope.root_container);
3584 errdefer mod.gpa.destroy(struct_ty.castTag(.empty_struct).?);
3669 const file_scope = try sema.gpa.create(Scope.File);
3670 errdefer sema.gpa.destroy(file_scope);
3671 const struct_ty = try Type.Tag.empty_struct.create(sema.gpa, &file_scope.root_container);
3672 errdefer sema.gpa.destroy(struct_ty.castTag(.empty_struct).?);
35853673
35863674 file_scope.* = .{
35873675 .sub_file_path = resolved_path,
......@@ -3595,13 +3683,13 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin
35953683 .ty = struct_ty,
35963684 },
35973685 };
3598 mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {
3686 sema.mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {
35993687 error.AnalysisFail => {
3600 assert(mod.comp.totalErrorCount() != 0);
3688 assert(sema.mod.comp.totalErrorCount() != 0);
36013689 },
36023690 else => |e| return e,
36033691 };
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);
36053693 return file_scope;
36063694}
36073695
......@@ -3637,7 +3725,7 @@ fn cmpNumeric(
36373725
36383726 if (lhs.value()) |lhs_val| {
36393727 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));
36413729 }
36423730 }
36433731
......@@ -3658,6 +3746,7 @@ fn cmpNumeric(
36583746 .Float, .ComptimeFloat => true,
36593747 else => false,
36603748 };
3749 const target = sema.mod.getTarget();
36613750 if (lhs_is_float and rhs_is_float) {
36623751 // Implicit cast the smaller one to the larger one.
36633752 const dest_type = x: {
......@@ -3666,15 +3755,15 @@ fn cmpNumeric(
36663755 } else if (rhs_ty_tag == .ComptimeFloat) {
36673756 break :x lhs.ty;
36683757 }
3669 if (lhs.ty.floatBits(mod.getTarget()) >= rhs.ty.floatBits(mod.getTarget())) {
3758 if (lhs.ty.floatBits(target) >= rhs.ty.floatBits(target)) {
36703759 break :x lhs.ty;
36713760 } else {
36723761 break :x rhs.ty;
36733762 }
36743763 };
3675 const casted_lhs = try sema.coerce(scope, dest_type, lhs);
3676 const casted_rhs = try sema.coerce(scope, dest_type, rhs);
3677 return mod.addBinOp(b, src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
3764 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
3765 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
3766 return block.addBinOp(src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
36783767 }
36793768 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.
36803769 // For mixed signed and unsigned integers, implicit cast both operands to a signed
......@@ -3697,16 +3786,16 @@ fn cmpNumeric(
36973786 var lhs_bits: usize = undefined;
36983787 if (lhs.value()) |lhs_val| {
36993788 if (lhs_val.isUndef())
3700 return mod.constUndef(scope, src, Type.initTag(.bool));
3789 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
37013790 const is_unsigned = if (lhs_is_float) x: {
37023791 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);
37043793 defer bigint.deinit();
37053794 const zcmp = lhs_val.orderAgainstZero();
37063795 if (lhs_val.floatHasFraction()) {
37073796 switch (op) {
3708 .eq => return mod.constBool(sema.arena, src, false),
3709 .neq => return mod.constBool(sema.arena, src, true),
3797 .eq => return sema.mod.constBool(sema.arena, src, false),
3798 .neq => return sema.mod.constBool(sema.arena, src, true),
37103799 else => {},
37113800 }
37123801 if (zcmp == .lt) {
......@@ -3725,23 +3814,23 @@ fn cmpNumeric(
37253814 } else if (lhs_is_float) {
37263815 dest_float_type = lhs.ty;
37273816 } else {
3728 const int_info = lhs.ty.intInfo(mod.getTarget());
3817 const int_info = lhs.ty.intInfo(target);
37293818 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
37303819 }
37313820
37323821 var rhs_bits: usize = undefined;
37333822 if (rhs.value()) |rhs_val| {
37343823 if (rhs_val.isUndef())
3735 return mod.constUndef(scope, src, Type.initTag(.bool));
3824 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
37363825 const is_unsigned = if (rhs_is_float) x: {
37373826 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);
37393828 defer bigint.deinit();
37403829 const zcmp = rhs_val.orderAgainstZero();
37413830 if (rhs_val.floatHasFraction()) {
37423831 switch (op) {
3743 .eq => return mod.constBool(sema.arena, src, false),
3744 .neq => return mod.constBool(sema.arena, src, true),
3832 .eq => return sema.mod.constBool(sema.arena, src, false),
3833 .neq => return sema.mod.constBool(sema.arena, src, true),
37453834 else => {},
37463835 }
37473836 if (zcmp == .lt) {
......@@ -3760,7 +3849,7 @@ fn cmpNumeric(
37603849 } else if (rhs_is_float) {
37613850 dest_float_type = rhs.ty;
37623851 } else {
3763 const int_info = rhs.ty.intInfo(mod.getTarget());
3852 const int_info = rhs.ty.intInfo(target);
37643853 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
37653854 }
37663855
......@@ -3769,21 +3858,21 @@ fn cmpNumeric(
37693858 const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {
37703859 error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}),
37713860 };
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);
37733862 };
3774 const casted_lhs = try sema.coerce(scope, dest_type, lhs);
3775 const casted_rhs = try sema.coerce(scope, dest_type, rhs);
3863 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
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);
37783867}
37793868
37803869fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst {
37813870 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 });
37833872 }
37843873
37853874 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);
37873876}
37883877
37893878fn 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
37913880 const err_union = dest_type.castTag(.error_union).?;
37923881 if (inst.value()) |val| {
37933882 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);
37953884 break :blk val;
37963885 } else switch (err_union.data.error_set.tag()) {
37973886 .anyerror => val,
......@@ -3810,11 +3899,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst
38103899 else => unreachable,
38113900 };
38123901
3813 return mod.constInst(scope.arena(), inst.src, .{
3902 return sema.mod.constInst(sema.arena, inst.src, .{
38143903 .ty = dest_type,
38153904 // creating a SubValue for the error_union payload
38163905 .val = try Value.Tag.error_union.create(
3817 scope.arena(),
3906 sema.arena,
38183907 to_wrap,
38193908 ),
38203909 });
......@@ -3824,11 +3913,11 @@ fn wrapErrorUnion(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst
38243913
38253914 // we are coercing from E to E!T
38263915 if (inst.ty.zigTypeTag() == .ErrorSet) {
3827 var coerced = try sema.coerce(scope, err_union.data.error_set, inst);
3828 return mod.addUnOp(b, inst.src, dest_type, .wrap_errunion_err, coerced);
3916 var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);
3917 return block.addUnOp(inst.src, dest_type, .wrap_errunion_err, coerced);
38293918 } else {
3830 var coerced = try sema.coerce(scope, err_union.data.payload, inst);
3831 return mod.addUnOp(b, inst.src, dest_type, .wrap_errunion_payload, coerced);
3919 var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);
3920 return block.addUnOp(inst.src, dest_type, .wrap_errunion_payload, coerced);
38323921 }
38333922}
38343923
......@@ -3839,6 +3928,8 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty
38393928 if (instructions.len == 1)
38403929 return instructions[0].ty;
38413930
3931 const target = sema.mod.getTarget();
3932
38423933 var chosen = instructions[0];
38433934 for (instructions[1..]) |candidate| {
38443935 if (candidate.ty.eql(chosen.ty))
......@@ -3859,13 +3950,13 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, instructions: []*Inst) !Ty
38593950 candidate.ty.isInt() and
38603951 chosen.ty.isSignedInt() == candidate.ty.isSignedInt())
38613952 {
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) {
38633954 chosen = candidate;
38643955 }
38653956 continue;
38663957 }
38673958 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)) {
38693960 chosen = candidate;
38703961 }
38713962 continue;
src/astgen.zig+38-28
......@@ -25,18 +25,18 @@ pub const ResultLoc = union(enum) {
2525 /// of an assignment uses this kind of result location.
2626 ref,
2727 /// 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,
2929 /// The expression must store its result into this typed pointer. The result instruction
3030 /// from the expression must be ignored.
31 ptr: zir.Inst.Index,
31 ptr: zir.Inst.Ref,
3232 /// The expression must store its result into this allocation, which has an inferred type.
3333 /// The result instruction from the expression must be ignored.
3434 /// Always an instruction with tag `alloc_inferred`.
35 inferred_ptr: zir.Inst.Index,
35 inferred_ptr: zir.Inst.Ref,
3636 /// The expression must store its result into this pointer, which is a typed pointer that
3737 /// has been bitcasted to whatever the expression's type is.
3838 /// The result instruction from the expression must be ignored.
39 bitcasted_ptr: zir.Inst.Index,
39 bitcasted_ptr: zir.Inst.Ref,
4040 /// There is a pointer for the expression to store its result into, however, its type
4141 /// is inferred based on peer type resolution for a `zir.Inst.Block`.
4242 /// The result instruction from the expression must be ignored.
......@@ -1133,10 +1133,9 @@ fn varDecl(
11331133 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
11341134 // the variable, no memory location needed.
11351135 if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {
1136 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0)
1137 .{ .ty = try typeExpr(mod, scope, var_decl.ast.type_node) }
1138 else
1139 .none;
1136 const result_loc: ResultLoc = if (var_decl.ast.type_node != 0) .{
1137 .ty = try typeExpr(mod, scope, var_decl.ast.type_node),
1138 } else .none;
11401139 const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);
11411140 const sub_scope = try block_arena.create(Scope.LocalVal);
11421141 sub_scope.* = .{
......@@ -2539,16 +2538,13 @@ fn switchExpr(
25392538 if (underscore_src != null) special_prong = .underscore;
25402539 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)
2543 .{
2544 .rl = .ref,
2545 .tag = .switchbr_ref,
2546 }
2547 else
2548 .{
2549 .rl = .none,
2550 .tag = .switchbr,
2551 };
2541 const rl_and_tag: struct { rl: ResultLoc, tag: zir.Inst.Tag } = if (any_payload_is_ref) .{
2542 .rl = .ref,
2543 .tag = .switchbr_ref,
2544 } else .{
2545 .rl = .none,
2546 .tag = .switchbr,
2547 };
25522548 const target = try expr(mod, &block_scope.base, rl_and_tag.rl, target_node);
25532549 const switch_inst = try addZirInstT(mod, &block_scope.base, switch_src, zir.Inst.SwitchBr, rl_and_tag.tag, .{
25542550 .target = target,
......@@ -2980,11 +2976,12 @@ fn integerLiteral(
29802976 const main_tokens = tree.nodes.items(.main_token);
29812977 const int_token = main_tokens[int_lit];
29822978 const prefixed_bytes = tree.tokenSlice(int_token);
2979 const gz = scope.getGenZir();
29832980 if (std.fmt.parseInt(u64, prefixed_bytes, 0)) |small_int| {
29842981 const result: zir.Inst.Index = switch (small_int) {
29852982 0 => @enumToInt(zir.Const.zero),
29862983 1 => @enumToInt(zir.Const.one),
2987 else => try addZirInt(small_int),
2984 else => try gz.addInt(small_int),
29882985 };
29892986 return rvalue(mod, scope, rl, result);
29902987 } else |err| {
......@@ -3418,6 +3415,10 @@ fn callExpr(
34183415 node: ast.Node.Index,
34193416 call: ast.full.Call,
34203417) InnerError!*zir.Inst {
3418 if (true) {
3419 @panic("TODO update for zir-memory-layout branch");
3420 }
3421
34213422 if (call.async_token) |async_token| {
34223423 return mod.failTok(scope, async_token, "TODO implement async fn call", .{});
34233424 }
......@@ -3512,7 +3513,7 @@ fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Inde
35123513 const tree = scope.tree();
35133514 var child_scope = Scope.Nosuspend{
35143515 .parent = scope,
3515 .gen_zir = scope.getGenZIR(),
3516 .gen_zir = scope.getGenZir(),
35163517 .src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]],
35173518 };
35183519
......@@ -3808,33 +3809,42 @@ fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
38083809/// result locations must call this function on their result.
38093810/// As an example, if the `ResultLoc` is `ptr`, it will write the result to the pointer.
38103811/// 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();
38123820 switch (rl) {
38133821 .none => return result,
38143822 .discard => {
38153823 // 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);
38173825 return result;
38183826 },
38193827 .ref => {
38203828 // 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);
38223832 },
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),
38243834 .ptr => |ptr_inst| {
3825 _ = try addZIRBinOp(mod, scope, result.src, .store, ptr_inst, result);
3835 _ = try gz.addBin(.store, ptr_inst, result);
38263836 return result;
38273837 },
38283838 .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", .{});
38303840 },
38313841 .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);
38333843 return result;
38343844 },
38353845 .block_ptr => |block_scope| {
38363846 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);
38383848 return result;
38393849 },
38403850 }
src/codegen.zig+21-21
......@@ -17,6 +17,7 @@ const DW = std.dwarf;
1717const leb128 = std.leb;
1818const log = std.log.scoped(.codegen);
1919const build_options = @import("build_options");
20const LazySrcLoc = Module.LazySrcLoc;
2021
2122/// The codegen-related data that is stored in `ir.Inst.Block` instructions.
2223pub const BlockData = struct {
......@@ -978,7 +979,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
978979 /// Copies a value to a register without tracking the register. The register is not considered
979980 /// allocated. A second call to `copyToTmpRegister` may return the same register.
980981 /// 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 {
982983 const reg = self.findUnusedReg() orelse b: {
983984 // We'll take over the first register. Move the instruction that was previously
984985 // there to a stack allocation.
......@@ -1457,7 +1458,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
14571458
14581459 fn genArmBinOpCode(
14591460 self: *Self,
1460 src: usize,
1461 src: LazySrcLoc,
14611462 dst_reg: Register,
14621463 lhs_mcv: MCValue,
14631464 rhs_mcv: MCValue,
......@@ -1620,7 +1621,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
16201621
16211622 fn genX8664BinMathCode(
16221623 self: *Self,
1623 src: usize,
1624 src: LazySrcLoc,
16241625 dst_ty: Type,
16251626 dst_mcv: MCValue,
16261627 src_mcv: MCValue,
......@@ -1706,7 +1707,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
17061707 }
17071708 }
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 {
17101711 const abi_size = ty.abiSize(self.target.*);
17111712 const adj_off = off + abi_size;
17121713 try self.code.ensureCapacity(self.code.items.len + 7);
......@@ -1807,7 +1808,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
18071808 return result;
18081809 }
18091810
1810 fn genBreakpoint(self: *Self, src: usize) !MCValue {
1811 fn genBreakpoint(self: *Self, src: LazySrcLoc) !MCValue {
18111812 switch (arch) {
18121813 .i386, .x86_64 => {
18131814 try self.code.append(0xcc); // int3
......@@ -2221,7 +2222,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22212222 }
22222223 }
22232224
2224 fn ret(self: *Self, src: usize, mcv: MCValue) !MCValue {
2225 fn ret(self: *Self, src: LazySrcLoc, mcv: MCValue) !MCValue {
22252226 const ret_ty = self.fn_type.fnReturnType();
22262227 try self.setRegOrMem(src, ret_ty, self.ret_mcv, mcv);
22272228 switch (arch) {
......@@ -2558,7 +2559,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
25582559 }
25592560
25602561 /// 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 {
25622563 switch (arch) {
25632564 .i386, .x86_64 => {
25642565 try self.code.ensureCapacity(self.code.items.len + 5);
......@@ -2615,7 +2616,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26152616 }
26162617 }
26172618
2618 fn performReloc(self: *Self, src: usize, reloc: Reloc) !void {
2619 fn performReloc(self: *Self, src: LazySrcLoc, reloc: Reloc) !void {
26192620 switch (reloc) {
26202621 .rel32 => |pos| {
26212622 const amt = self.code.items.len - (pos + 4);
......@@ -2679,7 +2680,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26792680 }
26802681 }
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 {
26832684 if (operand.ty.hasCodeGenBits()) {
26842685 const operand_mcv = try self.resolveInst(operand);
26852686 const block_mcv = @bitCast(MCValue, block.codegen.mcv);
......@@ -2692,7 +2693,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26922693 return self.brVoid(src, block);
26932694 }
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 {
26962697 // Emit a jump with a relocation. It will be patched up after the block ends.
26972698 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 {
28962897 }
28972898
28982899 /// 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 {
29002901 switch (loc) {
29012902 .none => return,
29022903 .register => |reg| return self.genSetReg(src, ty, reg, val),
......@@ -2908,7 +2909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
29082909 }
29092910 }
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 {
29122913 switch (arch) {
29132914 .arm, .armeb => switch (mcv) {
29142915 .dead => unreachable,
......@@ -3111,7 +3112,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
31113112 4, 8 => {
31123113 const offset = if (math.cast(i9, adj_off)) |imm|
31133114 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 }));
31153117 const rn: Register = switch (arch) {
31163118 .aarch64, .aarch64_be => .x29,
31173119 .aarch64_32 => .w29,
......@@ -3140,7 +3142,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
31403142 }
31413143 }
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 {
31443146 switch (arch) {
31453147 .arm, .armeb => switch (mcv) {
31463148 .dead => unreachable,
......@@ -3762,7 +3764,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
37623764 return mcv;
37633765 }
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 {
37663768 if (typed_value.val.isUndef())
37673769 return MCValue{ .undef = {} };
37683770 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
......@@ -3835,7 +3837,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
38353837 };
38363838
38373839 /// 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 {
38393841 const cc = fn_ty.fnCallingConvention();
38403842 const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen());
38413843 defer self.gpa.free(param_types);
......@@ -4049,13 +4051,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
40494051 };
40504052 }
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 {
40534055 @setCold(true);
40544056 assert(self.err_msg == null);
4055 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, .{
4056 .file_scope = self.src_loc.file_scope,
4057 .byte_offset = src,
4058 }, format, args);
4057 const src_loc = src.toSrcLocWithDecl(self.mod_fn.owner_decl);
4058 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, src_loc, format, args);
40594059 return error.CodegenFail;
40604060 }
40614061
src/ir.zig+21-15
......@@ -591,7 +591,7 @@ pub const Body = struct {
591591};
592592
593593/// 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 {
595595 const allocator = old_module.gpa;
596596 var ctx: DumpTzir = .{
597597 .allocator = allocator,
......@@ -622,10 +622,10 @@ pub fn dumpFn(old_module: IrModule, module_fn: *IrModule.Fn) void {
622622}
623623
624624const DumpTzir = struct {
625 allocator: *Allocator,
625 allocator: *std.mem.Allocator,
626626 arena: std.heap.ArenaAllocator,
627 old_module: *const IrModule,
628 module_fn: *IrModule.Fn,
627 old_module: *const Module,
628 module_fn: *Module.Fn,
629629 indent: usize,
630630 inst_table: InstTable,
631631 partial_inst_table: InstTable,
......@@ -634,12 +634,12 @@ const DumpTzir = struct {
634634 next_partial_index: usize = 0,
635635 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 instructions
639 /// TODO: Improve this code to include a stack of Body and store the instructions
640640 /// in there. Now we are putting all the instructions in a function local table,
641641 /// 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 {
643643 // First pass to pre-populate the table so that we can show even invalid references.
644644 // Must iterate the same order we iterate the second time.
645645 // We also look for constants and put them in the const_table.
......@@ -657,7 +657,7 @@ const DumpTzir = struct {
657657 return dtz.dumpBody(body, writer);
658658 }
659659
660 fn fetchInstsAndResolveConsts(dtz: *DumpTzir, body: ir.Body) error{OutOfMemory}!void {
660 fn fetchInstsAndResolveConsts(dtz: *DumpTzir, body: Body) error{OutOfMemory}!void {
661661 for (body.instructions) |inst| {
662662 try dtz.inst_table.put(inst, dtz.next_index);
663663 dtz.next_index += 1;
......@@ -694,13 +694,16 @@ const DumpTzir = struct {
694694 .unwrap_errunion_payload_ptr,
695695 .unwrap_errunion_err_ptr,
696696 => {
697 const un_op = inst.cast(ir.Inst.UnOp).?;
697 const un_op = inst.cast(Inst.UnOp).?;
698698 try dtz.findConst(un_op.operand);
699699 },
700700
701701 .add,
702 .addwrap,
702703 .sub,
704 .subwrap,
703705 .mul,
706 .mulwrap,
704707 .cmp_lt,
705708 .cmp_lte,
706709 .cmp_eq,
......@@ -714,7 +717,7 @@ const DumpTzir = struct {
714717 .bit_or,
715718 .xor,
716719 => {
717 const bin_op = inst.cast(ir.Inst.BinOp).?;
720 const bin_op = inst.cast(Inst.BinOp).?;
718721 try dtz.findConst(bin_op.lhs);
719722 try dtz.findConst(bin_op.rhs);
720723 },
......@@ -770,7 +773,7 @@ const DumpTzir = struct {
770773 }
771774 }
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 {
774777 for (body.instructions) |inst| {
775778 const my_index = dtz.next_partial_index;
776779 try dtz.partial_inst_table.put(inst, my_index);
......@@ -812,7 +815,7 @@ const DumpTzir = struct {
812815 .unwrap_errunion_payload_ptr,
813816 .unwrap_errunion_err_ptr,
814817 => {
815 const un_op = inst.cast(ir.Inst.UnOp).?;
818 const un_op = inst.cast(Inst.UnOp).?;
816819 const kinky = try dtz.writeInst(writer, un_op.operand);
817820 if (kinky != null) {
818821 try writer.writeAll(") // Instruction does not dominate all uses!\n");
......@@ -822,8 +825,11 @@ const DumpTzir = struct {
822825 },
823826
824827 .add,
828 .addwrap,
825829 .sub,
830 .subwrap,
826831 .mul,
832 .mulwrap,
827833 .cmp_lt,
828834 .cmp_lte,
829835 .cmp_eq,
......@@ -837,7 +843,7 @@ const DumpTzir = struct {
837843 .bit_or,
838844 .xor,
839845 => {
840 const bin_op = inst.cast(ir.Inst.BinOp).?;
846 const bin_op = inst.cast(Inst.BinOp).?;
841847
842848 const lhs_kinky = try dtz.writeInst(writer, bin_op.lhs);
843849 try writer.writeAll(", ");
......@@ -1008,7 +1014,7 @@ const DumpTzir = struct {
10081014 }
10091015 }
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 {
10121018 if (dtz.partial_inst_table.get(inst)) |operand_index| {
10131019 try writer.print("%{d}", .{operand_index});
10141020 return null;
......@@ -1024,7 +1030,7 @@ const DumpTzir = struct {
10241030 }
10251031 }
10261032
1027 fn findConst(dtz: *DumpTzir, operand: *ir.Inst) !void {
1033 fn findConst(dtz: *DumpTzir, operand: *Inst) !void {
10281034 if (operand.tag == .constant) {
10291035 try dtz.const_table.put(operand, dtz.next_const_index);
10301036 dtz.next_const_index += 1;
src/link/Coff.zig+1-1
......@@ -727,7 +727,7 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void {
727727 self.offset_table_free_list.append(self.base.allocator, decl.link.coff.offset_table_index) catch {};
728728}
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 {
731731 if (self.llvm_ir_module) |_| return;
732732
733733 for (exports) |exp| {
src/link/Elf.zig+1-1
......@@ -2670,7 +2670,7 @@ fn writeDeclDebugInfo(self: *Elf, text_block: *TextBlock, dbg_info_buf: []const
26702670pub fn updateDeclExports(
26712671 self: *Elf,
26722672 module: *Module,
2673 decl: *const Module.Decl,
2673 decl: *Module.Decl,
26742674 exports: []const *Module.Export,
26752675) !void {
26762676 if (self.llvm_ir_module) |_| return;
src/link/MachO.zig+2-2
......@@ -834,7 +834,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
834834 }
835835 },
836836 else => {
837 log.err("{s} terminated", .{ argv.items[0] });
837 log.err("{s} terminated", .{argv.items[0]});
838838 return error.LLDCrashed;
839839 },
840840 }
......@@ -1323,7 +1323,7 @@ pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.D
13231323pub fn updateDeclExports(
13241324 self: *MachO,
13251325 module: *Module,
1326 decl: *const Module.Decl,
1326 decl: *Module.Decl,
13271327 exports: []const *Module.Export,
13281328) !void {
13291329 const tracy = trace(@src());
src/type.zig+3-100
......@@ -94,9 +94,7 @@ pub const Type = extern union {
9494
9595 .anyframe_T, .@"anyframe" => return .AnyFrame,
9696
97 .@"struct", .empty_struct => return .Struct,
98 .@"enum" => return .Enum,
99 .@"union" => return .Union,
97 .empty_struct => return .Struct,
10098
10199 .var_args_param => unreachable, // can be any type
102100 }
......@@ -484,9 +482,6 @@ pub const Type = extern union {
484482 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
485483 .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),
490485 .@"opaque" => return self.copyPayloadShallow(allocator, Payload.Opaque),
491486 }
492487 }
......@@ -725,9 +720,6 @@ pub const Type = extern union {
725720 .inferred_alloc_const => return out_stream.writeAll("(inferred_alloc_const)"),
726721 .inferred_alloc_mut => return out_stream.writeAll("(inferred_alloc_mut)"),
727722 // 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 {}"),
731723 .@"opaque" => return out_stream.writeAll("opaque {}"),
732724 }
733725 unreachable;
......@@ -839,10 +831,6 @@ pub const Type = extern union {
839831 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
840832 },
841833
842 .@"enum" => @panic("TODO"),
843 .@"struct" => @panic("TODO"),
844 .@"union" => @panic("TODO"),
845
846834 .c_void,
847835 .void,
848836 .type,
......@@ -864,7 +852,7 @@ pub const Type = extern union {
864852
865853 pub fn isNoReturn(self: Type) bool {
866854 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);
868856 assert(fast_result == definitely_correct_result);
869857 return fast_result;
870858 }
......@@ -970,10 +958,6 @@ pub const Type = extern union {
970958 @panic("TODO abiAlignment error union");
971959 },
972960
973 .@"enum" => self.cast(Payload.Enum).?.abiAlignment(target),
974 .@"struct" => @panic("TODO"),
975 .@"union" => @panic("TODO"),
976
977961 .c_void,
978962 .void,
979963 .type,
......@@ -1122,10 +1106,6 @@ pub const Type = extern union {
11221106 }
11231107 @panic("TODO abiSize error union");
11241108 },
1125
1126 .@"enum" => @panic("TODO"),
1127 .@"struct" => @panic("TODO"),
1128 .@"union" => @panic("TODO"),
11291109 };
11301110 }
11311111
......@@ -1195,9 +1175,6 @@ pub const Type = extern union {
11951175 .error_set,
11961176 .error_set_single,
11971177 .empty_struct,
1198 .@"enum",
1199 .@"struct",
1200 .@"union",
12011178 .@"opaque",
12021179 .var_args_param,
12031180 => false,
......@@ -1273,9 +1250,6 @@ pub const Type = extern union {
12731250 .error_set,
12741251 .error_set_single,
12751252 .empty_struct,
1276 .@"enum",
1277 .@"struct",
1278 .@"union",
12791253 .@"opaque",
12801254 .var_args_param,
12811255 => unreachable,
......@@ -1372,9 +1346,6 @@ pub const Type = extern union {
13721346 .empty_struct,
13731347 .inferred_alloc_const,
13741348 .inferred_alloc_mut,
1375 .@"enum",
1376 .@"struct",
1377 .@"union",
13781349 .@"opaque",
13791350 .var_args_param,
13801351 => false,
......@@ -1453,9 +1424,6 @@ pub const Type = extern union {
14531424 .empty_struct,
14541425 .inferred_alloc_const,
14551426 .inferred_alloc_mut,
1456 .@"enum",
1457 .@"struct",
1458 .@"union",
14591427 .@"opaque",
14601428 .var_args_param,
14611429 => false,
......@@ -1543,9 +1511,6 @@ pub const Type = extern union {
15431511 .empty_struct,
15441512 .inferred_alloc_const,
15451513 .inferred_alloc_mut,
1546 .@"enum",
1547 .@"struct",
1548 .@"union",
15491514 .@"opaque",
15501515 .var_args_param,
15511516 => false,
......@@ -1628,9 +1593,6 @@ pub const Type = extern union {
16281593 .empty_struct,
16291594 .inferred_alloc_const,
16301595 .inferred_alloc_mut,
1631 .@"enum",
1632 .@"struct",
1633 .@"union",
16341596 .@"opaque",
16351597 .var_args_param,
16361598 => false,
......@@ -1755,9 +1717,6 @@ pub const Type = extern union {
17551717 .empty_struct => unreachable,
17561718 .inferred_alloc_const => unreachable,
17571719 .inferred_alloc_mut => unreachable,
1758 .@"enum" => unreachable,
1759 .@"struct" => unreachable,
1760 .@"union" => unreachable,
17611720 .@"opaque" => unreachable,
17621721 .var_args_param => unreachable,
17631722
......@@ -1908,9 +1867,6 @@ pub const Type = extern union {
19081867 .empty_struct,
19091868 .inferred_alloc_const,
19101869 .inferred_alloc_mut,
1911 .@"enum",
1912 .@"struct",
1913 .@"union",
19141870 .@"opaque",
19151871 .var_args_param,
19161872 => unreachable,
......@@ -1983,9 +1939,6 @@ pub const Type = extern union {
19831939 .empty_struct,
19841940 .inferred_alloc_const,
19851941 .inferred_alloc_mut,
1986 .@"enum",
1987 .@"struct",
1988 .@"union",
19891942 .@"opaque",
19901943 .var_args_param,
19911944 => unreachable,
......@@ -2073,9 +2026,6 @@ pub const Type = extern union {
20732026 .empty_struct,
20742027 .inferred_alloc_const,
20752028 .inferred_alloc_mut,
2076 .@"enum",
2077 .@"struct",
2078 .@"union",
20792029 .@"opaque",
20802030 .var_args_param,
20812031 => false,
......@@ -2159,9 +2109,6 @@ pub const Type = extern union {
21592109 .empty_struct,
21602110 .inferred_alloc_const,
21612111 .inferred_alloc_mut,
2162 .@"enum",
2163 .@"struct",
2164 .@"union",
21652112 .@"opaque",
21662113 .var_args_param,
21672114 => false,
......@@ -2231,9 +2178,6 @@ pub const Type = extern union {
22312178 .empty_struct,
22322179 .inferred_alloc_const,
22332180 .inferred_alloc_mut,
2234 .@"enum",
2235 .@"struct",
2236 .@"union",
22372181 .@"opaque",
22382182 .var_args_param,
22392183 => unreachable,
......@@ -2331,9 +2275,6 @@ pub const Type = extern union {
23312275 .empty_struct,
23322276 .inferred_alloc_const,
23332277 .inferred_alloc_mut,
2334 .@"enum",
2335 .@"struct",
2336 .@"union",
23372278 .@"opaque",
23382279 .var_args_param,
23392280 => false,
......@@ -2452,9 +2393,6 @@ pub const Type = extern union {
24522393 .empty_struct,
24532394 .inferred_alloc_const,
24542395 .inferred_alloc_mut,
2455 .@"enum",
2456 .@"struct",
2457 .@"union",
24582396 .@"opaque",
24592397 .var_args_param,
24602398 => unreachable,
......@@ -2539,9 +2477,6 @@ pub const Type = extern union {
25392477 .empty_struct,
25402478 .inferred_alloc_const,
25412479 .inferred_alloc_mut,
2542 .@"enum",
2543 .@"struct",
2544 .@"union",
25452480 .@"opaque",
25462481 .var_args_param,
25472482 => unreachable,
......@@ -2625,9 +2560,6 @@ pub const Type = extern union {
26252560 .empty_struct,
26262561 .inferred_alloc_const,
26272562 .inferred_alloc_mut,
2628 .@"enum",
2629 .@"struct",
2630 .@"union",
26312563 .@"opaque",
26322564 .var_args_param,
26332565 => unreachable,
......@@ -2711,9 +2643,6 @@ pub const Type = extern union {
27112643 .empty_struct,
27122644 .inferred_alloc_const,
27132645 .inferred_alloc_mut,
2714 .@"enum",
2715 .@"struct",
2716 .@"union",
27172646 .@"opaque",
27182647 .var_args_param,
27192648 => unreachable,
......@@ -2794,9 +2723,6 @@ pub const Type = extern union {
27942723 .empty_struct,
27952724 .inferred_alloc_const,
27962725 .inferred_alloc_mut,
2797 .@"enum",
2798 .@"struct",
2799 .@"union",
28002726 .@"opaque",
28012727 .var_args_param,
28022728 => unreachable,
......@@ -2877,9 +2803,6 @@ pub const Type = extern union {
28772803 .empty_struct,
28782804 .inferred_alloc_const,
28792805 .inferred_alloc_mut,
2880 .@"enum",
2881 .@"struct",
2882 .@"union",
28832806 .@"opaque",
28842807 .var_args_param,
28852808 => unreachable,
......@@ -2960,9 +2883,6 @@ pub const Type = extern union {
29602883 .empty_struct,
29612884 .inferred_alloc_const,
29622885 .inferred_alloc_mut,
2963 .@"enum",
2964 .@"struct",
2965 .@"union",
29662886 .@"opaque",
29672887 .var_args_param,
29682888 => false,
......@@ -3028,10 +2948,6 @@ pub const Type = extern union {
30282948 .var_args_param,
30292949 => return null,
30302950
3031 .@"enum" => @panic("TODO onePossibleValue enum"),
3032 .@"struct" => @panic("TODO onePossibleValue struct"),
3033 .@"union" => @panic("TODO onePossibleValue union"),
3034
30352951 .empty_struct => return Value.initTag(.empty_struct_value),
30362952 .void => return Value.initTag(.void_value),
30372953 .noreturn => return Value.initTag(.unreachable_value),
......@@ -3139,9 +3055,6 @@ pub const Type = extern union {
31393055 .empty_struct,
31403056 .inferred_alloc_const,
31413057 .inferred_alloc_mut,
3142 .@"enum",
3143 .@"struct",
3144 .@"union",
31453058 .@"opaque",
31463059 .var_args_param,
31473060 => return false,
......@@ -3237,9 +3150,6 @@ pub const Type = extern union {
32373150 => unreachable,
32383151
32393152 .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,
32433153 .@"opaque" => &self.castTag(.@"opaque").?.scope,
32443154 };
32453155 }
......@@ -3386,9 +3296,6 @@ pub const Type = extern union {
33863296 error_set,
33873297 error_set_single,
33883298 empty_struct,
3389 @"enum",
3390 @"struct",
3391 @"union",
33923299 @"opaque",
33933300
33943301 pub const last_no_payload_tag = Tag.inferred_alloc_const;
......@@ -3467,11 +3374,7 @@ pub const Type = extern union {
34673374 .int_unsigned,
34683375 => Payload.Bits,
34693376
3470 .error_set,
3471 .@"enum",
3472 .@"struct",
3473 .@"union",
3474 => Payload.Decl,
3377 .error_set => Payload.Decl,
34753378
34763379 .array => Payload.Array,
34773380 .array_sentinel => Payload.ArraySentinel,
src/zir.zig+42-15
......@@ -34,6 +34,7 @@ pub const Code = struct {
3434 /// The meaning of this data is determined by `Inst.Tag` value.
3535 extra: []u32,
3636 /// First ZIR instruction in this `Code`.
37 /// `extra` at this index contains a `Ref` for every root member.
3738 root_start: Inst.Index,
3839 /// Number of ZIR instructions in the implicit root block of the `Code`.
3940 root_len: u32,
......@@ -358,10 +359,9 @@ pub const Inst = struct {
358359 /// Same as `alloc` except mutable.
359360 alloc_mut,
360361 /// Same as `alloc` except the type is inferred.
361 /// lhs and rhs unused.
362 /// The operand is unused.
362363 alloc_inferred,
363364 /// Same as `alloc_inferred` except mutable.
364 /// lhs and rhs unused.
365365 alloc_inferred_mut,
366366 /// Create an `anyframe->T`.
367367 /// Uses the `un_node` field. AST node is the `anyframe->T` syntax. Operand is the type.
......@@ -370,9 +370,11 @@ pub const Inst = struct {
370370 array_cat,
371371 /// Array multiplication `a ** b`
372372 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.
374375 array_type,
375 /// lhs is length, ArrayTypeSentinel[rhs]
376 /// `[N:S]T` syntax. No source location provided.
377 /// Uses the `array_type_sentinel` field.
376378 array_type_sentinel,
377379 /// Given a pointer to an indexable object, returns the len property. This is
378380 /// used by for loops. This instruction also emits a for-loop specific compile
......@@ -407,10 +409,11 @@ pub const Inst = struct {
407409 /// Bitwise OR. `|`
408410 bit_or,
409411 /// 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`.
411413 block,
412414 /// A block of code, which can return a value. There are no instructions that break out of
413415 /// this block; it is implied that the final instruction is the result.
416 /// Uses the `pl_node` union field. Payload is `MultiOp`.
414417 block_flat,
415418 /// Same as `block` but additionally makes the inner instructions execute at comptime.
416419 block_comptime,
......@@ -433,7 +436,7 @@ pub const Inst = struct {
433436 /// the operand is assumed to be the void value.
434437 /// Uses the `un_tok` union field.
435438 break_void_tok,
436 /// lhs and rhs unused.
439 /// Uses the `node` union field.
437440 breakpoint,
438441 /// Function call with modifier `.auto`.
439442 /// Uses `pl_node`. AST node is the function call. Payload is `Call`.
......@@ -471,8 +474,11 @@ pub const Inst = struct {
471474 /// The payload is `MultiOp`.
472475 compile_log,
473476 /// 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`.
474479 condbr,
475480 /// Special case, has no textual representation.
481 /// Uses the `const` union field.
476482 @"const",
477483 /// Declares the beginning of a statement. Used for debug info.
478484 /// Uses the `node` union field.
......@@ -512,7 +518,7 @@ pub const Inst = struct {
512518 error_union_type,
513519 /// Create an error set. extra[lhs..rhs]. The values are token index offsets.
514520 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.
516522 error_value,
517523 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
518524 /// 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 {
532538 field_val_named,
533539 /// Convert a larger float type to any other float type, possibly causing
534540 /// 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.
535543 floatcast,
536544 /// Returns a function type, assuming unspecified calling convention.
537545 /// Uses the `fn_type` union field. `payload_index` points to a `FnType`.
......@@ -550,6 +558,8 @@ pub const Inst = struct {
550558 int,
551559 /// Convert an integer value to another integer type, asserting that the destination type
552560 /// 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.
553563 intcast,
554564 /// Make an integer type out of signedness and bit count.
555565 /// lhs is signedness, rhs is bit count.
......@@ -574,7 +584,8 @@ pub const Inst = struct {
574584 is_err_ptr,
575585 /// A labeled block of code that loops forever. At the end of the body it is implied
576586 /// 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`.
578589 loop,
579590 /// Merge two error sets into one, `E1 || E2`.
580591 merge_error_sets,
......@@ -677,12 +688,12 @@ pub const Inst = struct {
677688 typeof_peer,
678689 /// Asserts control-flow will not reach this instruction. Not safety checked - the compiler
679690 /// will assume the correctness of this instruction.
680 /// lhs and rhs unused.
691 /// Uses the `node` union field.
681692 unreachable_unsafe,
682693 /// Asserts control-flow will not reach this instruction. In safety-checked modes,
683694 /// this will generate a call to the panic function unless it can be proven unreachable
684695 /// by the compiler.
685 /// lhs and rhs unused.
696 /// Uses the `node` union field.
686697 unreachable_safe,
687698 /// Bitwise XOR. `^`
688699 xor,
......@@ -742,7 +753,7 @@ pub const Inst = struct {
742753 /// Takes a *E!T and raises a compiler error if T != void
743754 /// Uses the `un_tok` field.
744755 ensure_err_payload_void,
745 /// An enum literal. Uses the `str` union field.
756 /// An enum literal. Uses the `str_tok` union field.
746757 enum_literal,
747758 /// Suspend an async function. The suspend block has 0 or 1 statements in it.
748759 /// Uses the `un_node` union field.
......@@ -995,6 +1006,7 @@ pub const Inst = struct {
9951006 bin: Bin,
9961007 decl: *Module.Decl,
9971008 @"const": *TypedValue,
1009 /// For strings which may contain null bytes.
9981010 str: struct {
9991011 /// Offset into `string_bytes`.
10001012 start: u32,
......@@ -1005,14 +1017,28 @@ pub const Inst = struct {
10051017 return code.string_bytes[self.start..][0..self.len];
10061018 }
10071019 },
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 },
10081034 /// Offset from Decl AST token index.
10091035 tok: ast.TokenIndex,
10101036 /// Offset from Decl AST node index.
10111037 node: ast.Node.Index,
10121038 int: u64,
1013 condbr: struct {
1014 condition: Ref,
1015 /// index into extra.
1039 array_type_sentinel: struct {
1040 len: Ref,
1041 /// index into extra, points to an `ArrayTypeSentinel`
10161042 payload_index: u32,
10171043 },
10181044 ptr_type_simple: struct {
......@@ -1100,10 +1126,11 @@ pub const Inst = struct {
11001126 args_len: u32,
11011127 };
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`:
11041130 /// * 0. the then body, according to `then_body_len`.
11051131 /// * 1. the else body, according to `else_body_len`.
11061132 pub const CondBr = struct {
1133 condition: Ref,
11071134 then_body_len: u32,
11081135 else_body_len: u32,
11091136 };