authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-14 19:04:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
log27be4f31402557972ae28d552f4ec4617357d454
treee8c88a0307752dcc00946e261e4e18b4f25a0f89
parent7bb2d13a090f700b3806127a639e164726af8e03

Sema: more AIR memory layout reworking progress

Additionally: ZIR encoding for floats now supports float literals up to f64, not only f32. This is because we no longer need a source location for this instruction.

5 files changed, 486 insertions(+), 517 deletions(-)

src/Air.zig+6-5
......@@ -94,6 +94,11 @@ pub const Inst = struct {
9494 bitcast,
9595 /// Uses the `ty_pl` field with payload `Block`.
9696 block,
97 /// A labeled block of code that loops forever. At the end of the body it is implied
98 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
99 /// Result type is always noreturn; no instructions in a block follow this one.
100 /// Uses the `ty_pl` field. Payload is `Block`.
101 loop,
97102 /// Return from a block with a result.
98103 /// Result type is always noreturn; no instructions in a block follow this one.
99104 /// Uses the `br` field.
......@@ -181,11 +186,6 @@ pub const Inst = struct {
181186 /// Read a value from a pointer.
182187 /// Uses the `ty_op` field.
183188 load,
184 /// A labeled block of code that loops forever. At the end of the body it is implied
185 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
186 /// Result type is always noreturn; no instructions in a block follow this one.
187 /// Uses the `ty_pl` field. Payload is `Block`.
188 loop,
189189 /// Converts a pointer to its address. Result type is always `usize`.
190190 /// Uses the `un_op` field.
191191 ptrtoint,
......@@ -279,6 +279,7 @@ pub const Inst = struct {
279279 /// this union. `Tag` determines which union field is active, as well as
280280 /// how to interpret the data within.
281281 pub const Data = union {
282 no_op: void,
282283 un_op: Ref,
283284 bin_op: struct {
284285 lhs: Ref,
src/AstGen.zig+5-8
......@@ -6589,12 +6589,12 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir
65896589 } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) {
65906590 error.InvalidCharacter => unreachable, // validated by tokenizer
65916591 };
6592 // If the value fits into a f32 without losing any precision, store it that way.
6592 // If the value fits into a f64 without losing any precision, store it that way.
65936593 @setFloatMode(.Strict);
6594 const smaller_float = @floatCast(f32, float_number);
6594 const smaller_float = @floatCast(f64, float_number);
65956595 const bigger_again: f128 = smaller_float;
65966596 if (bigger_again == float_number) {
6597 const result = try gz.addFloat(smaller_float, node);
6597 const result = try gz.addFloat(smaller_float);
65986598 return rvalue(gz, rl, result, node);
65996599 }
66006600 // We need to use 128 bits. Break the float into 4 u32 values so we can
......@@ -9145,13 +9145,10 @@ const GenZir = struct {
91459145 return indexToRef(new_index);
91469146 }
91479147
9148 fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref {
9148 fn addFloat(gz: *GenZir, number: f64) !Zir.Inst.Ref {
91499149 return gz.add(.{
91509150 .tag = .float,
9151 .data = .{ .float = .{
9152 .src_node = gz.nodeIndexToRelative(src_node),
9153 .number = number,
9154 } },
9151 .data = .{ .float = number },
91559152 });
91569153 }
91579154
src/Module.zig+32
......@@ -1226,6 +1226,17 @@ pub const Scope = struct {
12261226 return block.src_decl.namespace.file_scope;
12271227 }
12281228
1229 pub fn addTy(
1230 block: *Block,
1231 tag: Air.Inst.Tag,
1232 ty: Type,
1233 ) error{OutOfMemory}!Air.Inst.Ref {
1234 return block.addInst(.{
1235 .tag = tag,
1236 .data = .{ .ty = ty },
1237 });
1238 }
1239
12291240 pub fn addTyOp(
12301241 block: *Block,
12311242 tag: Air.Inst.Tag,
......@@ -1241,6 +1252,13 @@ pub const Scope = struct {
12411252 });
12421253 }
12431254
1255 pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref {
1256 return block.addInst(.{
1257 .tag = tag,
1258 .data = .no_op,
1259 });
1260 }
1261
12441262 pub fn addUnOp(
12451263 block: *Block,
12461264 tag: Air.Inst.Tag,
......@@ -1252,6 +1270,20 @@ pub const Scope = struct {
12521270 });
12531271 }
12541272
1273 pub fn addBr(
1274 block: *Block,
1275 target_block: Air.Inst.Index,
1276 operand: Air.Inst.Ref,
1277 ) error{OutOfMemory}!Air.Inst.Ref {
1278 return block.addInst(.{
1279 .tag = .br,
1280 .data = .{ .br = .{
1281 .block_inst = target_block,
1282 .operand = operand,
1283 } },
1284 });
1285 }
1286
12551287 pub fn addBinOp(
12561288 block: *Block,
12571289 tag: Air.Inst.Tag,
src/Sema.zig+439-489
......@@ -372,14 +372,14 @@ pub fn analyzeBody(
372372 //.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
373373 //.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func),
374374
375 //.add => try sema.zirArithmetic(block, inst),
376 //.addwrap => try sema.zirArithmetic(block, inst),
377 //.div => try sema.zirArithmetic(block, inst),
378 //.mod_rem => try sema.zirArithmetic(block, inst),
379 //.mul => try sema.zirArithmetic(block, inst),
380 //.mulwrap => try sema.zirArithmetic(block, inst),
381 //.sub => try sema.zirArithmetic(block, inst),
382 //.subwrap => try sema.zirArithmetic(block, inst),
375 .add => try sema.zirArithmetic(block, inst),
376 .addwrap => try sema.zirArithmetic(block, inst),
377 .div => try sema.zirArithmetic(block, inst),
378 .mod_rem => try sema.zirArithmetic(block, inst),
379 .mul => try sema.zirArithmetic(block, inst),
380 .mulwrap => try sema.zirArithmetic(block, inst),
381 .sub => try sema.zirArithmetic(block, inst),
382 .subwrap => try sema.zirArithmetic(block, inst),
383383
384384 //// Instructions that we know to *always* be noreturn based solely on their tag.
385385 //// These functions match the return type of analyzeBody so that we can
......@@ -505,35 +505,35 @@ pub fn analyzeBody(
505505 i = 0;
506506 continue;
507507 },
508 //.block_inline => blk: {
509 // // Directly analyze the block body without introducing a new block.
510 // const inst_data = datas[inst].pl_node;
511 // const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
512 // const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
513 // const break_inst = try sema.analyzeBody(block, inline_body);
514 // const break_data = datas[break_inst].@"break";
515 // if (inst == break_data.block_inst) {
516 // break :blk sema.resolveInst(break_data.operand);
517 // } else {
518 // return break_inst;
519 // }
520 //},
521 //.condbr_inline => blk: {
522 // const inst_data = datas[inst].pl_node;
523 // const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
524 // const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
525 // const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
526 // const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
527 // const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition);
528 // const inline_body = if (cond.val.toBool()) then_body else else_body;
529 // const break_inst = try sema.analyzeBody(block, inline_body);
530 // const break_data = datas[break_inst].@"break";
531 // if (inst == break_data.block_inst) {
532 // break :blk sema.resolveInst(break_data.operand);
533 // } else {
534 // return break_inst;
535 // }
536 //},
508 .block_inline => blk: {
509 // Directly analyze the block body without introducing a new block.
510 const inst_data = datas[inst].pl_node;
511 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
512 const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
513 const break_inst = try sema.analyzeBody(block, inline_body);
514 const break_data = datas[break_inst].@"break";
515 if (inst == break_data.block_inst) {
516 break :blk sema.resolveInst(break_data.operand);
517 } else {
518 return break_inst;
519 }
520 },
521 .condbr_inline => blk: {
522 const inst_data = datas[inst].pl_node;
523 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
524 const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
525 const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len];
526 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
527 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition);
528 const inline_body = if (cond.val.toBool()) then_body else else_body;
529 const break_inst = try sema.analyzeBody(block, inline_body);
530 const break_data = datas[break_inst].@"break";
531 if (inst == break_data.block_inst) {
532 break :blk sema.resolveInst(break_data.operand);
533 } else {
534 return break_inst;
535 }
536 },
537537 else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"),
538538 };
539539 if (sema.getTypeOf(air_inst).isNoReturn())
......@@ -1186,7 +1186,7 @@ fn zirRetPtr(
11861186 const fn_ty = sema.func.?.owner_decl.ty;
11871187 const ret_type = fn_ty.fnReturnType();
11881188 const ptr_type = try Module.simplePtrType(sema.arena, ret_type, true, .One);
1189 return block.addNoOp(src, ptr_type, .alloc);
1189 return block.addTy(.alloc, ptr_type);
11901190}
11911191
11921192fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -1230,7 +1230,8 @@ fn ensureResultUsed(
12301230 operand: Air.Inst.Ref,
12311231 src: LazySrcLoc,
12321232) CompileError!void {
1233 switch (operand.ty.zigTypeTag()) {
1233 const operand_ty = sema.getTypeOf(operand);
1234 switch (operand_ty.zigTypeTag()) {
12341235 .Void, .NoReturn => return,
12351236 else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}),
12361237 }
......@@ -1243,7 +1244,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
12431244 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
12441245 const operand = sema.resolveInst(inst_data.operand);
12451246 const src = inst_data.src();
1246 switch (operand.ty.zigTypeTag()) {
1247 const operand_ty = sema.getTypeOf(operand);
1248 switch (operand_ty.zigTypeTag()) {
12471249 .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}),
12481250 else => return,
12491251 }
......@@ -1257,7 +1259,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
12571259 const src = inst_data.src();
12581260 const array_ptr = sema.resolveInst(inst_data.operand);
12591261
1260 const elem_ty = array_ptr.ty.elemType();
1262 const elem_ty = sema.getTypeOf(array_ptr).elemType();
12611263 if (!elem_ty.isIndexable()) {
12621264 const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node };
12631265 const msg = msg: {
......@@ -1317,7 +1319,6 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp
13171319 defer tracy.end();
13181320
13191321 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1320 const src = inst_data.src();
13211322 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
13221323 const var_type = try sema.resolveType(block, ty_src, inst_data.operand);
13231324 const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
......@@ -1329,10 +1330,7 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp
13291330 .val = undefined, // astgen guarantees there will be a store before the first load
13301331 },
13311332 };
1332 return sema.mod.constInst(sema.arena, src, .{
1333 .ty = ptr_type,
1334 .val = Value.initPayload(&val_payload.base),
1335 });
1333 return sema.addConstant(ptr_type, Value.initPayload(&val_payload.base));
13361334}
13371335
13381336fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -1351,7 +1349,7 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError
13511349 const var_type = try sema.resolveType(block, ty_src, inst_data.operand);
13521350 const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
13531351 try sema.requireRuntimeBlock(block, var_decl_src);
1354 return block.addNoOp(var_decl_src, ptr_type, .alloc);
1352 return block.addTy(.alloc, ptr_type);
13551353}
13561354
13571355fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -1365,7 +1363,7 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
13651363 try sema.validateVarType(block, ty_src, var_type);
13661364 const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
13671365 try sema.requireRuntimeBlock(block, var_decl_src);
1368 return block.addNoOp(var_decl_src, ptr_type, .alloc);
1366 return block.addTy(.alloc, ptr_type);
13691367}
13701368
13711369fn zirAllocInferred(
......@@ -1388,12 +1386,9 @@ fn zirAllocInferred(
13881386 // not needed in the case of constant values. However here, we plan to "downgrade"
13891387 // to a normal instruction when we hit `resolve_inferred_alloc`. So we append
13901388 // to the block even though it is currently a `.constant`.
1391 const result = try sema.mod.constInst(sema.arena, src, .{
1392 .ty = inferred_alloc_ty,
1393 .val = Value.initPayload(&val_payload.base),
1394 });
1389 const result = try sema.addConstant(inferred_alloc_ty, Value.initPayload(&val_payload.base));
13951390 try sema.requireFunctionBlock(block, src);
1396 try block.instructions.append(sema.gpa, result);
1391 try block.instructions.append(sema.gpa, refToIndex(result).?);
13971392 return result;
13981393}
13991394
......@@ -1630,18 +1625,21 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
16301625 const tracy = trace(@src());
16311626 defer tracy.end();
16321627
1633 const src: LazySrcLoc = .unneeded;
1628 const src = sema.src;
1629 const fn_inst_src = sema.src;
1630
16341631 const inst_data = sema.code.instructions.items(.data)[inst].param_type;
16351632 const fn_inst = sema.resolveInst(inst_data.callee);
1633 const fn_inst_ty = sema.getTypeOf(fn_inst);
16361634 const param_index = inst_data.param_index;
16371635
1638 const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) {
1639 .Fn => fn_inst.ty,
1636 const fn_ty: Type = switch (fn_inst_ty.zigTypeTag()) {
1637 .Fn => fn_inst_ty,
16401638 .BoundFn => {
1641 return sema.mod.fail(&block.base, fn_inst.src, "TODO implement zirParamType for method call syntax", .{});
1639 return sema.mod.fail(&block.base, fn_inst_src, "TODO implement zirParamType for method call syntax", .{});
16421640 },
16431641 else => {
1644 return sema.mod.fail(&block.base, fn_inst.src, "expected function, found '{}'", .{fn_inst.ty});
1642 return sema.mod.fail(&block.base, fn_inst_src, "expected function, found '{}'", .{fn_inst_ty});
16451643 },
16461644 };
16471645
......@@ -1711,23 +1709,20 @@ fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
17111709 const limbs = try arena.alloc(std.math.big.Limb, int.len);
17121710 mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes);
17131711
1714 return sema.mod.constInst(arena, .unneeded, .{
1715 .ty = Type.initTag(.comptime_int),
1716 .val = try Value.Tag.int_big_positive.create(arena, limbs),
1717 });
1712 return sema.addConstant(
1713 Type.initTag(.comptime_int),
1714 try Value.Tag.int_big_positive.create(arena, limbs),
1715 );
17181716}
17191717
17201718fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17211719 _ = block;
17221720 const arena = sema.arena;
1723 const inst_data = sema.code.instructions.items(.data)[inst].float;
1724 const src = inst_data.src();
1725 const number = inst_data.number;
1726
1727 return sema.mod.constInst(arena, src, .{
1728 .ty = Type.initTag(.comptime_float),
1729 .val = try Value.Tag.float_32.create(arena, number),
1730 });
1721 const number = sema.code.instructions.items(.data)[inst].float;
1722 return sema.addConstant(
1723 Type.initTag(.comptime_float),
1724 try Value.Tag.float_64.create(arena, number),
1725 );
17311726}
17321727
17331728fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -1735,13 +1730,11 @@ fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
17351730 const arena = sema.arena;
17361731 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
17371732 const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data;
1738 const src = inst_data.src();
17391733 const number = extra.get();
1740
1741 return sema.mod.constInst(arena, src, .{
1742 .ty = Type.initTag(.comptime_float),
1743 .val = try Value.Tag.float_128.create(arena, number),
1744 });
1734 return sema.addConstant(
1735 Type.initTag(.comptime_float),
1736 try Value.Tag.float_128.create(arena, number),
1737 );
17451738}
17461739
17471740fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
......@@ -1785,10 +1778,7 @@ fn zirCompileLog(
17851778 if (!gop.found_existing) {
17861779 gop.value_ptr.* = src_node;
17871780 }
1788 return sema.mod.constInst(sema.arena, src, .{
1789 .ty = Type.initTag(.void),
1790 .val = Value.initTag(.void_value),
1791 });
1781 return Air.Inst.Ref.void_value;
17921782}
17931783
17941784fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
......@@ -1817,18 +1807,26 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil
18171807 const src = inst_data.src();
18181808 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
18191809 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
1810 const gpa = sema.gpa;
18201811
18211812 // AIR expects a block outside the loop block too.
1822 const block_inst = try sema.arena.create(Inst.Block);
1823 block_inst.* = .{
1824 .base = .{
1825 .tag = Inst.Block.base_tag,
1826 .ty = undefined,
1827 .src = src,
1828 },
1829 .body = undefined,
1830 };
1831
1813 // Reserve space for a Loop instruction so that generated Break instructions can
1814 // point to it, even if it doesn't end up getting used because the code ends up being
1815 // comptime evaluated.
1816 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
1817 const loop_inst = block_inst + 1;
1818 try sema.air_instructions.ensureUnusedCapacity(gpa, 2);
1819 sema.air_instructions.appendAssumeCapacity(.{
1820 .tag = .block,
1821 .data = undefined,
1822 });
1823 sema.air_instructions.appendAssumeCapacity(.{
1824 .tag = .loop,
1825 .data = .{ .ty_pl = .{
1826 .ty = .noreturn_type,
1827 .payload = undefined,
1828 } },
1829 });
18321830 var label: Scope.Block.Label = .{
18331831 .zir_block = inst,
18341832 .merges = .{
......@@ -1844,33 +1842,24 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil
18441842 child_block.runtime_index += 1;
18451843 const merges = &child_block.label.?.merges;
18461844
1847 defer child_block.instructions.deinit(sema.gpa);
1848 defer merges.results.deinit(sema.gpa);
1849 defer merges.br_list.deinit(sema.gpa);
1850
1851 // Reserve space for a Loop instruction so that generated Break instructions can
1852 // point to it, even if it doesn't end up getting used because the code ends up being
1853 // comptime evaluated.
1854 const loop_inst = try sema.arena.create(Inst.Loop);
1855 loop_inst.* = .{
1856 .base = .{
1857 .tag = Inst.Loop.base_tag,
1858 .ty = Type.initTag(.noreturn),
1859 .src = src,
1860 },
1861 .body = undefined,
1862 };
1845 defer child_block.instructions.deinit(gpa);
1846 defer merges.results.deinit(gpa);
1847 defer merges.br_list.deinit(gpa);
18631848
18641849 var loop_block = child_block.makeSubBlock();
1865 defer loop_block.instructions.deinit(sema.gpa);
1850 defer loop_block.instructions.deinit(gpa);
18661851
18671852 _ = try sema.analyzeBody(&loop_block, body);
18681853
18691854 // Loop repetition is implied so the last instruction may or may not be a noreturn instruction.
1855 try child_block.instructions.append(gpa, loop_inst);
18701856
1871 try child_block.instructions.append(sema.gpa, &loop_inst.base);
1872 loop_inst.body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, loop_block.instructions.items) };
1873
1857 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
1858 loop_block.instructions.items.len);
1859 sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity(
1860 Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) },
1861 );
1862 sema.air_extra.appendAssumeCapacity(loop_block.instructions.items);
18741863 return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
18751864}
18761865
......@@ -1890,27 +1879,28 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index
18901879 return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirSuspendBlock", .{});
18911880}
18921881
1893fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1882fn zirBlock(
1883 sema: *Sema,
1884 parent_block: *Scope.Block,
1885 inst: Zir.Inst.Index,
1886) CompileError!Air.Inst.Ref {
18941887 const tracy = trace(@src());
18951888 defer tracy.end();
18961889
1897 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1898 const src = inst_data.src();
1899 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
1890 const pl_node = sema.code.instructions.items(.data)[inst].pl_node;
1891 const src = pl_node.src();
1892 const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index);
19001893 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
1894 const gpa = sema.gpa;
19011895
19021896 // Reserve space for a Block instruction so that generated Break instructions can
19031897 // point to it, even if it doesn't end up getting used because the code ends up being
19041898 // comptime evaluated.
1905 const block_inst = try sema.arena.create(Inst.Block);
1906 block_inst.* = .{
1907 .base = .{
1908 .tag = Inst.Block.base_tag,
1909 .ty = undefined, // Set after analysis.
1910 .src = src,
1911 },
1912 .body = undefined,
1913 };
1899 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
1900 try sema.air_instructions.append(gpa, .{
1901 .tag = .block,
1902 .data = undefined,
1903 });
19141904
19151905 var label: Scope.Block.Label = .{
19161906 .zir_block = inst,
......@@ -1932,9 +1922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compi
19321922 };
19331923 const merges = &child_block.label.?.merges;
19341924
1935 defer child_block.instructions.deinit(sema.gpa);
1936 defer merges.results.deinit(sema.gpa);
1937 defer merges.br_list.deinit(sema.gpa);
1925 defer child_block.instructions.deinit(gpa);
1926 defer merges.results.deinit(gpa);
1927 defer merges.br_list.deinit(gpa);
19381928
19391929 _ = try sema.analyzeBody(&child_block, body);
19401930
......@@ -1963,6 +1953,8 @@ fn analyzeBlockBody(
19631953 const tracy = trace(@src());
19641954 defer tracy.end();
19651955
1956 const gpa = sema.gpa;
1957
19661958 // Blocks must terminate with noreturn instruction.
19671959 assert(child_block.instructions.items.len != 0);
19681960 assert(child_block.instructions.items[child_block.instructions.items.len - 1].ty.isNoReturn());
......@@ -1971,7 +1963,7 @@ fn analyzeBlockBody(
19711963 // No need for a block instruction. We can put the new instructions
19721964 // directly into the parent block.
19731965 const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items);
1974 try parent_block.instructions.appendSlice(sema.gpa, copied_instructions);
1966 try parent_block.instructions.appendSlice(gpa, copied_instructions);
19751967 return copied_instructions[copied_instructions.len - 1];
19761968 }
19771969 if (merges.results.items.len == 1) {
......@@ -1982,7 +1974,7 @@ fn analyzeBlockBody(
19821974 // No need for a block instruction. We can put the new instructions directly
19831975 // into the parent block. Here we omit the break instruction.
19841976 const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items[0..last_inst_index]);
1985 try parent_block.instructions.appendSlice(sema.gpa, copied_instructions);
1977 try parent_block.instructions.appendSlice(gpa, copied_instructions);
19861978 return merges.results.items[0];
19871979 }
19881980 }
......@@ -1992,21 +1984,26 @@ fn analyzeBlockBody(
19921984
19931985 // Need to set the type and emit the Block instruction. This allows machine code generation
19941986 // to emit a jump instruction to after the block when it encounters the break.
1995 try parent_block.instructions.append(sema.gpa, &merges.block_inst.base);
1987 try parent_block.instructions.append(gpa, merges.block_inst);
19961988 const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items);
1997 merges.block_inst.base.ty = resolved_ty;
1998 merges.block_inst.body = .{
1999 .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items),
2000 };
1989 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
1990 child_block.instructions.items.len);
1991 sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{
1992 .ty = try sema.addType(resolved_ty),
1993 .payload = sema.addExtraAssumeCapacity(Air.Block{
1994 .body_len = @intCast(u32, child_block.instructions.items.len),
1995 }),
1996 } };
1997 sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items);
20011998 // Now that the block has its type resolved, we need to go back into all the break
20021999 // instructions, and insert type coercion on the operands.
20032000 for (merges.br_list.items) |br| {
2004 if (br.operand.ty.eql(resolved_ty)) {
2001 if (sema.getTypeOf(br.operand).eql(resolved_ty)) {
20052002 // No type coercion needed.
20062003 continue;
20072004 }
20082005 var coerce_block = parent_block.makeSubBlock();
2009 defer coerce_block.instructions.deinit(sema.gpa);
2006 defer coerce_block.instructions.deinit(gpa);
20102007 const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, br.operand.src);
20112008 // If no instructions were produced, such as in the case of a coercion of a
20122009 // constant value to a new type, we can simply point the br operand to it.
......@@ -2032,7 +2029,7 @@ fn analyzeBlockBody(
20322029 },
20332030 };
20342031 }
2035 return &merges.block_inst.base;
2032 return indexToRef(merges.block_inst);
20362033}
20372034
20382035fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -2104,7 +2101,7 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
21042101 const src_node = sema.code.instructions.items(.data)[inst].node;
21052102 const src: LazySrcLoc = .{ .node_offset = src_node };
21062103 try sema.requireRuntimeBlock(block, src);
2107 _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
2104 _ = try block.addNoOp(.breakpoint);
21082105}
21092106
21102107fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -2311,6 +2308,8 @@ fn analyzeCall(
23112308 }),
23122309 }
23132310
2311 const gpa = sema.gpa;
2312
23142313 const ret_type = func.ty.fnReturnType();
23152314
23162315 const is_comptime_call = block.is_comptime or modifier == .compile_time;
......@@ -2331,15 +2330,11 @@ fn analyzeCall(
23312330 // set to in the `Scope.Block`.
23322331 // This block instruction will be used to capture the return value from the
23332332 // inlined function.
2334 const block_inst = try sema.arena.create(Inst.Block);
2335 block_inst.* = .{
2336 .base = .{
2337 .tag = Inst.Block.base_tag,
2338 .ty = ret_type,
2339 .src = call_src,
2340 },
2341 .body = undefined,
2342 };
2333 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
2334 try sema.air_instructions.append(gpa, .{
2335 .tag = .block,
2336 .data = undefined,
2337 });
23432338 // This one is shared among sub-blocks within the same callee, but not
23442339 // shared among the entire inline/comptime call stack.
23452340 var inlining: Scope.Block.Inlining = .{
......@@ -2358,7 +2353,7 @@ fn analyzeCall(
23582353 const parent_inst_map = sema.inst_map;
23592354 sema.inst_map = .{};
23602355 defer {
2361 sema.inst_map.deinit(sema.gpa);
2356 sema.inst_map.deinit(gpa);
23622357 sema.inst_map = parent_inst_map;
23632358 }
23642359
......@@ -2390,9 +2385,9 @@ fn analyzeCall(
23902385
23912386 const merges = &child_block.inlining.?.merges;
23922387
2393 defer child_block.instructions.deinit(sema.gpa);
2394 defer merges.results.deinit(sema.gpa);
2395 defer merges.br_list.deinit(sema.gpa);
2388 defer child_block.instructions.deinit(gpa);
2389 defer merges.results.deinit(gpa);
2390 defer merges.br_list.deinit(gpa);
23962391
23972392 try sema.emitBackwardBranch(&child_block, call_src);
23982393
......@@ -2525,17 +2520,16 @@ fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
25252520 defer tracy.end();
25262521
25272522 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
2528 const src = inst_data.src();
25292523
25302524 // Create an anonymous error set type with only this error value, and return the value.
25312525 const kv = try sema.mod.getErrorValue(inst_data.get(sema.code));
25322526 const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key);
2533 return sema.mod.constInst(sema.arena, src, .{
2534 .ty = result_type,
2535 .val = try Value.Tag.@"error".create(sema.arena, .{
2527 return sema.addConstant(
2528 result_type,
2529 try Value.Tag.@"error".create(sema.arena, .{
25362530 .name = kv.key,
25372531 }),
2538 });
2532 );
25392533}
25402534
25412535fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -2558,10 +2552,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
25582552 .base = .{ .tag = .int_u64 },
25592553 .data = (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value,
25602554 };
2561 return sema.mod.constInst(sema.arena, src, .{
2562 .ty = result_ty,
2563 .val = Value.initPayload(&payload.base),
2564 });
2555 return sema.addConstant(result_ty, Value.initPayload(&payload.base));
25652556 }
25662557
25672558 try sema.requireRuntimeBlock(block, src);
......@@ -2587,10 +2578,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile
25872578 .base = .{ .tag = .@"error" },
25882579 .data = .{ .name = sema.mod.error_name_list.items[@intCast(usize, int)] },
25892580 };
2590 return sema.mod.constInst(sema.arena, src, .{
2591 .ty = Type.initTag(.anyerror),
2592 .val = Value.initPayload(&payload.base),
2593 });
2581 return sema.addConstant(Type.initTag(.anyerror), Value.initPayload(&payload.base));
25942582 }
25952583 try sema.requireRuntimeBlock(block, src);
25962584 if (block.wantSafety()) {
......@@ -2630,10 +2618,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com
26302618
26312619 // Anything merged with anyerror is anyerror.
26322620 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
2633 return sema.mod.constInst(sema.arena, src, .{
2634 .ty = Type.initTag(.type),
2635 .val = Value.initTag(.anyerror_type),
2636 });
2621 return Air.Inst.Ref.anyerror_type;
26372622 }
26382623 // When we support inferred error sets, we'll want to use a data structure that can
26392624 // represent a merged set of errors without forcing them to be resolved here. Until then
......@@ -2685,10 +2670,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com
26852670 .names_len = @intCast(u32, new_names.len),
26862671 };
26872672 const error_set_ty = try Type.Tag.error_set.create(sema.arena, new_error_set);
2688 return sema.mod.constInst(sema.arena, src, .{
2689 .ty = Type.initTag(.type),
2690 .val = try Value.Tag.ty.create(sema.arena, error_set_ty),
2691 });
2673 return sema.addConstant(Type.initTag(.type), try Value.Tag.ty.create(sema.arena, error_set_ty));
26922674}
26932675
26942676fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -2697,12 +2679,11 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
26972679 defer tracy.end();
26982680
26992681 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
2700 const src = inst_data.src();
27012682 const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code));
2702 return sema.mod.constInst(sema.arena, src, .{
2703 .ty = Type.initTag(.enum_literal),
2704 .val = try Value.Tag.enum_literal.create(sema.arena, duped_name),
2705 });
2683 return sema.addConstant(
2684 Type.initTag(.enum_literal),
2685 try Value.Tag.enum_literal.create(sema.arena, duped_name),
2686 );
27062687}
27072688
27082689fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -2712,11 +2693,12 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
27122693 const src = inst_data.src();
27132694 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
27142695 const operand = sema.resolveInst(inst_data.operand);
2696 const operand_ty = sema.getTypeOf(operand);
27152697
2716 const enum_tag: Air.Inst.Ref = switch (operand.ty.zigTypeTag()) {
2698 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) {
27172699 .Enum => operand,
27182700 .Union => {
2719 //if (!operand.ty.unionHasTag()) {
2701 //if (!operand_ty.unionHasTag()) {
27202702 // return mod.fail(
27212703 // &block.base,
27222704 // operand_src,
......@@ -2728,58 +2710,44 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
27282710 },
27292711 else => {
27302712 return mod.fail(&block.base, operand_src, "expected enum or tagged union, found {}", .{
2731 operand.ty,
2713 operand_ty,
27322714 });
27332715 },
27342716 };
2717 const enum_tag_ty = sema.getTypeOf(enum_tag);
27352718
27362719 var int_tag_type_buffer: Type.Payload.Bits = undefined;
2737 const int_tag_ty = try enum_tag.ty.intTagType(&int_tag_type_buffer).copy(arena);
2720 const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena);
27382721
2739 if (try sema.typeHasOnePossibleValue(block, src, enum_tag.ty)) |opv| {
2740 return mod.constInst(arena, src, .{
2741 .ty = int_tag_ty,
2742 .val = opv,
2743 });
2722 if (try sema.typeHasOnePossibleValue(block, src, enum_tag_ty)) |opv| {
2723 return sema.addConstant(int_tag_ty, opv);
27442724 }
27452725
27462726 if (try sema.resolvePossiblyUndefinedValue(block, operand_src, enum_tag)) |enum_tag_val| {
27472727 if (enum_tag_val.castTag(.enum_field_index)) |enum_field_payload| {
27482728 const field_index = enum_field_payload.data;
2749 switch (enum_tag.ty.tag()) {
2729 switch (enum_tag_ty.tag()) {
27502730 .enum_full => {
2751 const enum_full = enum_tag.ty.castTag(.enum_full).?.data;
2731 const enum_full = enum_tag_ty.castTag(.enum_full).?.data;
27522732 if (enum_full.values.count() != 0) {
27532733 const val = enum_full.values.keys()[field_index];
2754 return mod.constInst(arena, src, .{
2755 .ty = int_tag_ty,
2756 .val = val,
2757 });
2734 return sema.addConstant(int_tag_ty, val);
27582735 } else {
27592736 // Field index and integer values are the same.
27602737 const val = try Value.Tag.int_u64.create(arena, field_index);
2761 return mod.constInst(arena, src, .{
2762 .ty = int_tag_ty,
2763 .val = val,
2764 });
2738 return sema.addConstant(int_tag_ty, val);
27652739 }
27662740 },
27672741 .enum_simple => {
27682742 // Field index and integer values are the same.
27692743 const val = try Value.Tag.int_u64.create(arena, field_index);
2770 return mod.constInst(arena, src, .{
2771 .ty = int_tag_ty,
2772 .val = val,
2773 });
2744 return sema.addConstant(int_tag_ty, val);
27742745 },
27752746 else => unreachable,
27762747 }
27772748 } else {
27782749 // Assume it is already an integer and return it directly.
2779 return mod.constInst(arena, src, .{
2780 .ty = int_tag_ty,
2781 .val = enum_tag_val,
2782 });
2750 return sema.addConstant(int_tag_ty, enum_tag_val);
27832751 }
27842752 }
27852753
......@@ -2790,7 +2758,6 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
27902758fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
27912759 const mod = sema.mod;
27922760 const target = mod.getTarget();
2793 const arena = sema.arena;
27942761 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
27952762 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
27962763 const src = inst_data.src();
......@@ -2805,10 +2772,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
28052772
28062773 if (try sema.resolvePossiblyUndefinedValue(block, operand_src, operand)) |int_val| {
28072774 if (dest_ty.isNonexhaustiveEnum()) {
2808 return mod.constInst(arena, src, .{
2809 .ty = dest_ty,
2810 .val = int_val,
2811 });
2775 return sema.addConstant(dest_ty, int_val);
28122776 }
28132777 if (int_val.isUndef()) {
28142778 return sema.failWithUseOfUndef(block, operand_src);
......@@ -2832,10 +2796,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
28322796 };
28332797 return mod.failWithOwnedErrorMsg(&block.base, msg);
28342798 }
2835 return mod.constInst(arena, src, .{
2836 .ty = dest_ty,
2837 .val = int_val,
2838 });
2799 return sema.addConstant(dest_ty, int_val);
28392800 }
28402801
28412802 try sema.requireRuntimeBlock(block, src);
......@@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr(
28542815
28552816 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
28562817 const optional_ptr = sema.resolveInst(inst_data.operand);
2857 assert(optional_ptr.ty.zigTypeTag() == .Pointer);
2818 const optional_ptr_ty = sema.getTypeOf(optional_ptr);
2819 assert(optional_ptr_ty.zigTypeTag() == .Pointer);
28582820 const src = inst_data.src();
28592821
2860 const opt_type = optional_ptr.ty.elemType();
2822 const opt_type = optional_ptr_ty.elemType();
28612823 if (opt_type.zigTypeTag() != .Optional) {
28622824 return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});
28632825 }
28642826
28652827 const child_type = try opt_type.optionalChildAlloc(sema.arena);
2866 const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr.ty.isConstPtr(), .One);
2828 const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr_ty.isConstPtr(), .One);
28672829
28682830 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| {
28692831 const val = try pointer_val.pointerDeref(sema.arena);
......@@ -2871,10 +2833,7 @@ fn zirOptionalPayloadPtr(
28712833 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
28722834 }
28732835 // The same Value represents the pointer to the optional and the payload.
2874 return sema.mod.constInst(sema.arena, src, .{
2875 .ty = child_pointer,
2876 .val = pointer_val,
2877 });
2836 return sema.addConstant(child_pointer, pointer_val);
28782837 }
28792838
28802839 try sema.requireRuntimeBlock(block, src);
......@@ -2898,7 +2857,8 @@ fn zirOptionalPayload(
28982857 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
28992858 const src = inst_data.src();
29002859 const operand = sema.resolveInst(inst_data.operand);
2901 const opt_type = operand.ty;
2860 const operand_ty = sema.getTypeOf(operand);
2861 const opt_type = operand_ty;
29022862 if (opt_type.zigTypeTag() != .Optional) {
29032863 return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type});
29042864 }
......@@ -2909,10 +2869,7 @@ fn zirOptionalPayload(
29092869 if (val.isNull()) {
29102870 return sema.mod.fail(&block.base, src, "unable to unwrap null", .{});
29112871 }
2912 return sema.mod.constInst(sema.arena, src, .{
2913 .ty = child_type,
2914 .val = val,
2915 });
2872 return sema.addConstant(child_type, val);
29162873 }
29172874
29182875 try sema.requireRuntimeBlock(block, src);
......@@ -2936,25 +2893,27 @@ fn zirErrUnionPayload(
29362893 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
29372894 const src = inst_data.src();
29382895 const operand = sema.resolveInst(inst_data.operand);
2939 if (operand.ty.zigTypeTag() != .ErrorUnion)
2940 return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty});
2896 const operand_src = src;
2897 const operand_ty = sema.getTypeOf(operand);
2898 if (operand_ty.zigTypeTag() != .ErrorUnion)
2899 return sema.mod.fail(&block.base, operand_src, "expected error union type, found '{}'", .{operand_ty});
29412900
29422901 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
29432902 if (val.getError()) |name| {
29442903 return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name});
29452904 }
29462905 const data = val.castTag(.error_union).?.data;
2947 return sema.mod.constInst(sema.arena, src, .{
2948 .ty = operand.ty.castTag(.error_union).?.data.payload,
2949 .val = data,
2950 });
2906 return sema.addConstant(
2907 operand_ty.castTag(.error_union).?.data.payload,
2908 data,
2909 );
29512910 }
29522911 try sema.requireRuntimeBlock(block, src);
29532912 if (safety_check and block.wantSafety()) {
29542913 const is_non_err = try block.addUnOp(.is_err, operand);
29552914 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
29562915 }
2957 const result_ty = operand.ty.castTag(.error_union).?.data.payload;
2916 const result_ty = operand_ty.castTag(.error_union).?.data.payload;
29582917 return block.addTyOp(.unwrap_errunion_payload, result_ty, operand);
29592918}
29602919
......@@ -2971,12 +2930,13 @@ fn zirErrUnionPayloadPtr(
29712930 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
29722931 const src = inst_data.src();
29732932 const operand = sema.resolveInst(inst_data.operand);
2974 assert(operand.ty.zigTypeTag() == .Pointer);
2933 const operand_ty = sema.getTypeOf(operand);
2934 assert(operand_ty.zigTypeTag() == .Pointer);
29752935
2976 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
2977 return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()});
2936 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
2937 return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()});
29782938
2979 const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand.ty.elemType().castTag(.error_union).?.data.payload, !operand.ty.isConstPtr(), .One);
2939 const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand_ty.elemType().castTag(.error_union).?.data.payload, !operand_ty.isConstPtr(), .One);
29802940
29812941 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
29822942 const val = try pointer_val.pointerDeref(sema.arena);
......@@ -2985,13 +2945,13 @@ fn zirErrUnionPayloadPtr(
29852945 }
29862946 const data = val.castTag(.error_union).?.data;
29872947 // The same Value represents the pointer to the error union and the payload.
2988 return sema.mod.constInst(sema.arena, src, .{
2989 .ty = operand_pointer_ty,
2990 .val = try Value.Tag.ref_val.create(
2948 return sema.addConstant(
2949 operand_pointer_ty,
2950 try Value.Tag.ref_val.create(
29912951 sema.arena,
29922952 data,
29932953 ),
2994 });
2954 );
29952955 }
29962956
29972957 try sema.requireRuntimeBlock(block, src);
......@@ -3010,18 +2970,16 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi
30102970 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
30112971 const src = inst_data.src();
30122972 const operand = sema.resolveInst(inst_data.operand);
3013 if (operand.ty.zigTypeTag() != .ErrorUnion)
3014 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
2973 const operand_ty = sema.getTypeOf(operand);
2974 if (operand_ty.zigTypeTag() != .ErrorUnion)
2975 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty});
30152976
3016 const result_ty = operand.ty.castTag(.error_union).?.data.error_set;
2977 const result_ty = operand_ty.castTag(.error_union).?.data.error_set;
30172978
30182979 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
30192980 assert(val.getError() != null);
30202981 const data = val.castTag(.error_union).?.data;
3021 return sema.mod.constInst(sema.arena, src, .{
3022 .ty = result_ty,
3023 .val = data,
3024 });
2982 return sema.addConstant(result_ty, data);
30252983 }
30262984
30272985 try sema.requireRuntimeBlock(block, src);
......@@ -3036,21 +2994,19 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
30362994 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
30372995 const src = inst_data.src();
30382996 const operand = sema.resolveInst(inst_data.operand);
3039 assert(operand.ty.zigTypeTag() == .Pointer);
2997 const operand_ty = sema.getTypeOf(operand);
2998 assert(operand_ty.zigTypeTag() == .Pointer);
30402999
3041 if (operand.ty.elemType().zigTypeTag() != .ErrorUnion)
3042 return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()});
3000 if (operand_ty.elemType().zigTypeTag() != .ErrorUnion)
3001 return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()});
30433002
3044 const result_ty = operand.ty.elemType().castTag(.error_union).?.data.error_set;
3003 const result_ty = operand_ty.elemType().castTag(.error_union).?.data.error_set;
30453004
30463005 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
30473006 const val = try pointer_val.pointerDeref(sema.arena);
30483007 assert(val.getError() != null);
30493008 const data = val.castTag(.error_union).?.data;
3050 return sema.mod.constInst(sema.arena, src, .{
3051 .ty = result_ty,
3052 .val = data,
3053 });
3009 return sema.addConstant(result_ty, data);
30543010 }
30553011
30563012 try sema.requireRuntimeBlock(block, src);
......@@ -3064,9 +3020,10 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
30643020 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
30653021 const src = inst_data.src();
30663022 const operand = sema.resolveInst(inst_data.operand);
3067 if (operand.ty.zigTypeTag() != .ErrorUnion)
3068 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty});
3069 if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) {
3023 const operand_ty = sema.getTypeOf(operand);
3024 if (operand_ty.zigTypeTag() != .ErrorUnion)
3025 return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty});
3026 if (operand_ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) {
30703027 return sema.mod.fail(&block.base, src, "expression value is ignored", .{});
30713028 }
30723029}
......@@ -3233,10 +3190,10 @@ fn funcCommon(
32333190 }
32343191
32353192 if (is_extern) {
3236 return sema.mod.constInst(sema.arena, src, .{
3237 .ty = fn_ty,
3238 .val = try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl),
3239 });
3193 return sema.addConstant(
3194 fn_ty,
3195 try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl),
3196 );
32403197 }
32413198
32423199 if (body_inst == 0) {
......@@ -3261,11 +3218,7 @@ fn funcCommon(
32613218 .base = .{ .tag = .function },
32623219 .data = new_func,
32633220 };
3264 const result = try sema.mod.constInst(sema.arena, src, .{
3265 .ty = fn_ty,
3266 .val = Value.initPayload(&fn_payload.base),
3267 });
3268 return result;
3221 return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base));
32693222}
32703223
32713224fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -3324,7 +3277,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
33243277 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
33253278 const field_name = sema.code.nullTerminatedString(extra.field_name_start);
33263279 const object = sema.resolveInst(extra.lhs);
3327 const object_ptr = if (object.ty.zigTypeTag() == .Pointer)
3280 const object_ptr = if (sema.getTypeOf(object).zigTypeTag() == .Pointer)
33283281 object
33293282 else
33303283 try sema.analyzeRef(block, src, object);
......@@ -3397,13 +3350,14 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
33973350 ),
33983351 };
33993352
3400 switch (operand.ty.zigTypeTag()) {
3353 const operand_ty = sema.getTypeOf(operand);
3354 switch (operand_ty.zigTypeTag()) {
34013355 .ComptimeInt, .Int => {},
34023356 else => return sema.mod.fail(
34033357 &block.base,
34043358 operand_src,
34053359 "expected integer type, found '{}'",
3406 .{operand.ty},
3360 .{operand_ty},
34073361 ),
34083362 }
34093363
......@@ -3454,13 +3408,14 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
34543408 ),
34553409 };
34563410
3457 switch (operand.ty.zigTypeTag()) {
3411 const operand_ty = sema.getTypeOf(operand);
3412 switch (operand_ty.zigTypeTag()) {
34583413 .ComptimeFloat, .Float, .ComptimeInt => {},
34593414 else => return sema.mod.fail(
34603415 &block.base,
34613416 operand_src,
34623417 "expected float type, found '{}'",
3463 .{operand.ty},
3418 .{operand_ty},
34643419 ),
34653420 }
34663421
......@@ -3479,7 +3434,8 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
34793434
34803435 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
34813436 const array = sema.resolveInst(bin_inst.lhs);
3482 const array_ptr = if (array.ty.zigTypeTag() == .Pointer)
3437 const array_ty = sema.getTypeOf(array);
3438 const array_ptr = if (array_ty.zigTypeTag() == .Pointer)
34833439 array
34843440 else
34853441 try sema.analyzeRef(block, sema.src, array);
......@@ -3497,7 +3453,8 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
34973453 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
34983454 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
34993455 const array = sema.resolveInst(extra.lhs);
3500 const array_ptr = if (array.ty.zigTypeTag() == .Pointer)
3456 const array_ty = sema.getTypeOf(array);
3457 const array_ptr = if (array_ty.zigTypeTag() == .Pointer)
35013458 array
35023459 else
35033460 try sema.analyzeRef(block, src, array);
......@@ -3705,9 +3662,10 @@ fn analyzeSwitch(
37053662 const src: LazySrcLoc = .{ .node_offset = src_node_offset };
37063663 const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset };
37073664 const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
3665 const operand_ty = sema.getTypeOf(operand);
37083666
37093667 // Validate usage of '_' prongs.
3710 if (special_prong == .under and !operand.ty.isNonexhaustiveEnum()) {
3668 if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) {
37113669 const msg = msg: {
37123670 const msg = try mod.errMsg(
37133671 &block.base,
......@@ -3729,9 +3687,9 @@ fn analyzeSwitch(
37293687 }
37303688
37313689 // Validate for duplicate items, missing else prong, and invalid range.
3732 switch (operand.ty.zigTypeTag()) {
3690 switch (operand_ty.zigTypeTag()) {
37333691 .Enum => {
3734 var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand.ty.enumFieldCount());
3692 var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
37353693 defer gpa.free(seen_fields);
37363694
37373695 mem.set(?Module.SwitchProngSrc, seen_fields, null);
......@@ -3777,7 +3735,7 @@ fn analyzeSwitch(
37773735 );
37783736 }
37793737
3780 try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset);
3738 try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset);
37813739 }
37823740 }
37833741 const all_tags_handled = for (seen_fields) |seen_src| {
......@@ -3798,7 +3756,7 @@ fn analyzeSwitch(
37983756 for (seen_fields) |seen_src, i| {
37993757 if (seen_src != null) continue;
38003758
3801 const field_name = operand.ty.enumFieldName(i);
3759 const field_name = operand_ty.enumFieldName(i);
38023760
38033761 // TODO have this point to the tag decl instead of here
38043762 try mod.errNote(
......@@ -3810,10 +3768,10 @@ fn analyzeSwitch(
38103768 );
38113769 }
38123770 try mod.errNoteNonLazy(
3813 operand.ty.declSrcLoc(),
3771 operand_ty.declSrcLoc(),
38143772 msg,
38153773 "enum '{}' declared here",
3816 .{operand.ty},
3774 .{operand_ty},
38173775 );
38183776 break :msg msg;
38193777 };
......@@ -3908,12 +3866,12 @@ fn analyzeSwitch(
39083866 }
39093867
39103868 check_range: {
3911 if (operand.ty.zigTypeTag() == .Int) {
3869 if (operand_ty.zigTypeTag() == .Int) {
39123870 var arena = std.heap.ArenaAllocator.init(gpa);
39133871 defer arena.deinit();
39143872
3915 const min_int = try operand.ty.minInt(&arena, mod.getTarget());
3916 const max_int = try operand.ty.maxInt(&arena, mod.getTarget());
3873 const min_int = try operand_ty.minInt(&arena, mod.getTarget());
3874 const max_int = try operand_ty.maxInt(&arena, mod.getTarget());
39173875 if (try range_set.spans(min_int, max_int)) {
39183876 if (special_prong == .@"else") {
39193877 return mod.fail(
......@@ -3983,7 +3941,7 @@ fn analyzeSwitch(
39833941 );
39843942 }
39853943
3986 try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset);
3944 try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset);
39873945 }
39883946 }
39893947 switch (special_prong) {
......@@ -4015,7 +3973,7 @@ fn analyzeSwitch(
40153973 &block.base,
40163974 src,
40173975 "else prong required when switching on type '{}'",
4018 .{operand.ty},
3976 .{operand_ty},
40193977 );
40203978 }
40213979
......@@ -4063,7 +4021,7 @@ fn analyzeSwitch(
40634021 );
40644022 }
40654023
4066 try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset);
4024 try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset);
40674025 }
40684026 }
40694027 },
......@@ -4083,20 +4041,15 @@ fn analyzeSwitch(
40834041 .ComptimeFloat,
40844042 .Float,
40854043 => return mod.fail(&block.base, operand_src, "invalid switch operand type '{}'", .{
4086 operand.ty,
4044 operand_ty,
40874045 }),
40884046 }
40894047
4090 const block_inst = try sema.arena.create(Inst.Block);
4091 block_inst.* = .{
4092 .base = .{
4093 .tag = Inst.Block.base_tag,
4094 .ty = undefined, // Set after analysis.
4095 .src = src,
4096 },
4097 .body = undefined,
4098 };
4099
4048 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
4049 try sema.air_instructions.append(gpa, .{
4050 .tag = .block,
4051 .data = undefined,
4052 });
41004053 var label: Scope.Block.Label = .{
41014054 .zir_block = switch_inst,
41024055 .merges = .{
......@@ -4634,7 +4587,7 @@ fn zirBitwise(
46344587 const lhs_ty = sema.getTypeOf(lhs);
46354588 const rhs_ty = sema.getTypeOf(rhs);
46364589
4637 const instructions = &[_]Air.Inst.Index{ lhs, rhs };
4590 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
46384591 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
46394592 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
46404593 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
......@@ -4763,18 +4716,8 @@ fn analyzeArithmetic(
47634716 lhs_src: LazySrcLoc,
47644717 rhs_src: LazySrcLoc,
47654718) CompileError!Air.Inst.Ref {
4766 const instructions = &[_]Air.Inst.Index{ lhs, rhs };
4767 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
4768 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
4769 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
4770
4771 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
4772 resolved_type.elemType()
4773 else
4774 resolved_type;
4775
4776 const scalar_tag = scalar_type.zigTypeTag();
4777
4719 const lhs_ty = sema.getTypeOf(lhs);
4720 const rhs_ty = sema.getTypeOf(rhs);
47784721 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
47794722 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
47804723 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
......@@ -4790,6 +4733,18 @@ fn analyzeArithmetic(
47904733 });
47914734 }
47924735
4736 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
4737 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
4738 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
4739 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
4740
4741 const scalar_type = if (resolved_type.zigTypeTag() == .Vector)
4742 resolved_type.elemType()
4743 else
4744 resolved_type;
4745
4746 const scalar_tag = scalar_type.zigTypeTag();
4747
47934748 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
47944749 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
47954750
......@@ -4807,10 +4762,7 @@ fn analyzeArithmetic(
48074762 if (rhs_val.compareWithZero(.eq)) {
48084763 switch (zir_tag) {
48094764 .add, .addwrap, .sub, .subwrap => {
4810 return sema.mod.constInst(sema.arena, src, .{
4811 .ty = scalar_type,
4812 .val = lhs_val,
4813 });
4765 return sema.addConstant(scalar_type, lhs_val);
48144766 },
48154767 else => {},
48164768 }
......@@ -4850,10 +4802,7 @@ fn analyzeArithmetic(
48504802
48514803 log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value });
48524804
4853 return sema.mod.constInst(sema.arena, src, .{
4854 .ty = scalar_type,
4855 .val = value,
4856 });
4805 return sema.addConstant(scalar_type, value);
48574806 }
48584807 }
48594808
......@@ -5167,16 +5116,16 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
51675116 // args: []const FnArg,
51685117 field_values[5] = Value.initTag(.null_value); // TODO
51695118
5170 return sema.mod.constInst(sema.arena, src, .{
5171 .ty = type_info_ty,
5172 .val = try Value.Tag.@"union".create(sema.arena, .{
5119 return sema.addConstant(
5120 type_info_ty,
5121 try Value.Tag.@"union".create(sema.arena, .{
51735122 .tag = try Value.Tag.enum_field_index.create(
51745123 sema.arena,
51755124 @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn),
51765125 ),
51775126 .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr),
51785127 }),
5179 });
5128 );
51805129 },
51815130 else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{
51825131 @tagName(t),
......@@ -5189,7 +5138,8 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
51895138 const zir_datas = sema.code.instructions.items(.data);
51905139 const inst_data = zir_datas[inst].un_node;
51915140 const operand = sema.resolveInst(inst_data.operand);
5192 return sema.addType(operand.ty);
5141 const operand_ty = sema.getTypeOf(operand);
5142 return sema.addType(operand_ty);
51935143}
51945144
51955145fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -5241,11 +5191,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
52415191
52425192 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
52435193 const src = inst_data.src();
5194 const operand_src = src; // TODO put this on the operand, not the `!`
52445195 const uncasted_operand = sema.resolveInst(inst_data.operand);
52455196
52465197 const bool_type = Type.initTag(.bool);
5247 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);
5248 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
5198 const operand = try sema.coerce(block, bool_type, uncasted_operand, operand_src);
5199 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
52495200 if (val.toBool()) {
52505201 return Air.Inst.Ref.bool_false;
52515202 } else {
......@@ -5267,12 +5218,13 @@ fn zirBoolBr(
52675218
52685219 const datas = sema.code.instructions.items(.data);
52695220 const inst_data = datas[inst].bool_br;
5270 const src: LazySrcLoc = .unneeded;
52715221 const lhs = sema.resolveInst(inst_data.lhs);
5222 const lhs_src = sema.src;
52725223 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
52735224 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
5225 const gpa = sema.gpa;
52745226
5275 if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| {
5227 if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| {
52765228 if (lhs_val.toBool() == is_bool_or) {
52775229 if (is_bool_or) {
52785230 return Air.Inst.Ref.bool_true;
......@@ -5286,49 +5238,59 @@ fn zirBoolBr(
52865238 return sema.resolveBody(parent_block, body);
52875239 }
52885240
5289 const block_inst = try sema.arena.create(Inst.Block);
5290 block_inst.* = .{
5291 .base = .{
5292 .tag = Inst.Block.base_tag,
5293 .ty = Type.initTag(.bool),
5294 .src = src,
5295 },
5296 .body = undefined,
5297 };
5241 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
5242 try sema.air_instructions.append(gpa, .{
5243 .tag = .block,
5244 .data = .{ .ty_pl = .{
5245 .ty = .bool_type,
5246 .payload = undefined,
5247 } },
5248 });
52985249
52995250 var child_block = parent_block.makeSubBlock();
53005251 child_block.runtime_loop = null;
5301 child_block.runtime_cond = lhs.src;
5252 child_block.runtime_cond = lhs_src;
53025253 child_block.runtime_index += 1;
5303 defer child_block.instructions.deinit(sema.gpa);
5254 defer child_block.instructions.deinit(gpa);
53045255
53055256 var then_block = child_block.makeSubBlock();
5306 defer then_block.instructions.deinit(sema.gpa);
5257 defer then_block.instructions.deinit(gpa);
53075258
53085259 var else_block = child_block.makeSubBlock();
5309 defer else_block.instructions.deinit(sema.gpa);
5260 defer else_block.instructions.deinit(gpa);
53105261
53115262 const lhs_block = if (is_bool_or) &then_block else &else_block;
53125263 const rhs_block = if (is_bool_or) &else_block else &then_block;
53135264
5314 const lhs_result = try sema.mod.constInst(sema.arena, src, .{
5315 .ty = Type.initTag(.bool),
5316 .val = if (is_bool_or) Value.initTag(.bool_true) else Value.initTag(.bool_false),
5317 });
5318 _ = try lhs_block.addBr(src, block_inst, lhs_result);
5265 const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false;
5266 _ = try lhs_block.addBr(block_inst, lhs_result);
53195267
53205268 const rhs_result = try sema.resolveBody(rhs_block, body);
5321 _ = try rhs_block.addBr(src, block_inst, rhs_result);
5269 _ = try rhs_block.addBr(block_inst, rhs_result);
53225270
5323 const air_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, then_block.instructions.items) };
5324 const air_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, else_block.instructions.items) };
5325 _ = try child_block.addCondBr(src, lhs, air_then_body, air_else_body);
5271 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
5272 then_block.instructions.items.len + else_block.instructions.items.len +
5273 @typeInfo(Air.Block).Struct.fields.len + child_block.instructions.items.len);
53265274
5327 block_inst.body = .{
5328 .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items),
5329 };
5330 try parent_block.instructions.append(sema.gpa, &block_inst.base);
5331 return &block_inst.base;
5275 sema.air_instructions.items(.data)[block_inst].ty_pl.payload = sema.addExtraAssumeCapacity(
5276 Air.Block{ .body_len = @intCast(u32, child_block.instructions.items.len) },
5277 );
5278 sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items);
5279
5280 const cond_br_payload = sema.addExtraAssumeCapacity(Air.CondBr{
5281 .then_body_len = @intCast(u32, then_block.instructions.items.len),
5282 .else_body_len = @intCast(u32, else_block.instructions.items.len),
5283 });
5284 sema.air_extra.appendSliceAssumeCapacity(then_block.instructions.items);
5285 sema.air_extra.appendSliceAssumeCapacity(else_block.instructions.items);
5286
5287 _ = try child_block.addInst(.{ .tag = .cond_br, .data = .{ .pl_op = .{
5288 .operand = lhs,
5289 .payload = cond_br_payload,
5290 } } });
5291
5292 try parent_block.instructions.append(gpa, block_inst);
5293 return indexToRef(block_inst);
53325294}
53335295
53345296fn zirIsNonNull(
......@@ -5439,7 +5401,7 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
54395401 if (safety_check and block.wantSafety()) {
54405402 return sema.safetyPanic(block, src, .unreach);
54415403 } else {
5442 _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach);
5404 _ = try block.addNoOp(.unreach);
54435405 return always_noreturn;
54445406 }
54455407}
......@@ -5461,10 +5423,10 @@ fn zirRetErrValue(
54615423 }
54625424 // Return the error code from the function.
54635425 const kv = try sema.mod.getErrorValue(err_name);
5464 const result_inst = try sema.mod.constInst(sema.arena, src, .{
5465 .ty = try Type.Tag.error_set_single.create(sema.arena, kv.key),
5466 .val = try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
5467 });
5426 const result_inst = try sema.addConstant(
5427 try Type.Tag.error_set_single.create(sema.arena, kv.key),
5428 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
5429 );
54685430 return sema.analyzeRet(block, result_inst, src, true);
54695431}
54705432
......@@ -5505,7 +5467,7 @@ fn analyzeRet(
55055467 if (block.inlining) |inlining| {
55065468 // We are inlining a function call; rewrite the `ret` as a `break`.
55075469 try inlining.merges.results.append(sema.gpa, operand);
5508 _ = try block.addBr(src, inlining.merges.block_inst, operand);
5470 _ = try block.addBr(inlining.merges.block_inst, operand);
55095471 return always_noreturn;
55105472 }
55115473
......@@ -5613,10 +5575,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
56135575 const src = inst_data.src();
56145576 const struct_type = try sema.resolveType(block, src, inst_data.operand);
56155577
5616 return sema.mod.constInst(sema.arena, src, .{
5617 .ty = struct_type,
5618 .val = Value.initTag(.empty_struct_value),
5619 });
5578 return sema.addConstant(struct_type, Value.initTag(.empty_struct_value));
56205579}
56215580
56225581fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -5696,10 +5655,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
56965655 root_msg = try mod.errMsg(&block.base, src, template, args);
56975656 }
56985657 } else {
5699 field_inits[i] = try mod.constInst(sema.arena, src, .{
5700 .ty = field.ty,
5701 .val = field.default_val,
5702 });
5658 field_inits[i] = try sema.addConstant(field.ty, field.default_val);
57035659 }
57045660 }
57055661 if (root_msg) |msg| {
......@@ -5729,10 +5685,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref:
57295685 for (field_inits) |field_init, i| {
57305686 values[i] = field_init.value().?;
57315687 }
5732 return mod.constInst(sema.arena, src, .{
5733 .ty = struct_ty,
5734 .val = try Value.Tag.@"struct".create(sema.arena, values.ptr),
5735 });
5688 return sema.addConstant(struct_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr));
57365689 }
57375690
57385691 return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{});
......@@ -5913,20 +5866,13 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
59135866 .base = .{ .tag = .int_u64 },
59145867 .data = addr,
59155868 };
5916 return sema.mod.constInst(sema.arena, src, .{
5917 .ty = type_res,
5918 .val = Value.initPayload(&val_payload.base),
5919 });
5869 return sema.addConstant(type_res, Value.initPayload(&val_payload.base));
59205870 }
59215871
59225872 try sema.requireRuntimeBlock(block, src);
59235873 if (block.wantSafety()) {
5924 const zero = try sema.mod.constInst(sema.arena, src, .{
5925 .ty = Type.initTag(.u64),
5926 .val = Value.initTag(.zero),
5927 });
59285874 if (!type_res.isAllowzeroPtr()) {
5929 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, zero);
5875 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
59305876 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
59315877 }
59325878
......@@ -5936,12 +5882,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
59365882 .base = .{ .tag = .int_u64 },
59375883 .data = ptr_align - 1,
59385884 };
5939 const align_minus_1 = try sema.mod.constInst(sema.arena, src, .{
5940 .ty = Type.initTag(.u64),
5941 .val = Value.initPayload(&val_payload.base),
5942 });
5885 const align_minus_1 = try sema.addConstant(
5886 Type.initTag(.usize),
5887 Value.initPayload(&val_payload.base),
5888 );
59435889 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
5944 const is_aligned = try block.addBinOp(.cmp_eq, remainder, zero);
5890 const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize);
59455891 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);
59465892 }
59475893 }
......@@ -6217,10 +6163,10 @@ fn zirVarExtended(
62176163 .is_mutable = true, // TODO get rid of this unused field
62186164 .is_threadlocal = small.is_threadlocal,
62196165 };
6220 const result = try sema.mod.constInst(sema.arena, src, .{
6221 .ty = var_ty,
6222 .val = try Value.Tag.variable.create(sema.arena, new_var),
6223 });
6166 const result = try sema.addConstant(
6167 var_ty,
6168 try Value.Tag.variable.create(sema.arena, new_var),
6169 );
62246170 return result;
62256171}
62266172
......@@ -6380,32 +6326,13 @@ pub const PanicId = enum {
63806326 invalid_error_code,
63816327};
63826328
6383fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, panic_id: PanicId) !void {
6384 const block_inst = try sema.arena.create(Inst.Block);
6385 block_inst.* = .{
6386 .base = .{
6387 .tag = Inst.Block.base_tag,
6388 .ty = Type.initTag(.void),
6389 .src = ok.src,
6390 },
6391 .body = .{
6392 .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the condbr.
6393 },
6394 };
6395
6396 const ok_body: ir.Body = .{
6397 .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the br_void.
6398 };
6399 const br_void = try sema.arena.create(Inst.BrVoid);
6400 br_void.* = .{
6401 .base = .{
6402 .tag = .br_void,
6403 .ty = Type.initTag(.noreturn),
6404 .src = ok.src,
6405 },
6406 .block = block_inst,
6407 };
6408 ok_body.instructions[0] = &br_void.base;
6329fn addSafetyCheck(
6330 sema: *Sema,
6331 parent_block: *Scope.Block,
6332 ok: Air.Inst.Ref,
6333 panic_id: PanicId,
6334) !void {
6335 const gpa = sema.gpa;
64096336
64106337 var fail_block: Scope.Block = .{
64116338 .parent = parent_block,
......@@ -6416,26 +6343,55 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, pan
64166343 .is_comptime = parent_block.is_comptime,
64176344 };
64186345
6419 defer fail_block.instructions.deinit(sema.gpa);
6346 defer fail_block.instructions.deinit(gpa);
64206347
6421 _ = try sema.safetyPanic(&fail_block, ok.src, panic_id);
6348 _ = try sema.safetyPanic(&fail_block, .unneeded, panic_id);
64226349
6423 const fail_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, fail_block.instructions.items) };
6350 try parent_block.instructions.ensureUnusedCapacity(gpa, 1);
64246351
6425 const condbr = try sema.arena.create(Inst.CondBr);
6426 condbr.* = .{
6427 .base = .{
6428 .tag = .condbr,
6429 .ty = Type.initTag(.noreturn),
6430 .src = ok.src,
6431 },
6432 .condition = ok,
6433 .then_body = ok_body,
6434 .else_body = fail_body,
6435 };
6436 block_inst.body.instructions[0] = &condbr.base;
6352 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
6353 1 + // The main block only needs space for the cond_br.
6354 @typeInfo(Air.CondBr).Struct.fields.len +
6355 1 + // The ok branch of the cond_br only needs space for the br.
6356 fail_block.instructions.items.len);
64376357
6438 try parent_block.instructions.append(sema.gpa, &block_inst.base);
6358 try sema.air_instructions.ensureUnusedCapacity(gpa, 3);
6359 const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
6360 const cond_br_inst = block_inst + 1;
6361 const br_inst = cond_br_inst + 1;
6362 sema.air_instructions.appendAssumeCapacity(gpa, .{
6363 .tag = .block,
6364 .data = .{ .ty_pl = .{
6365 .ty = .void_type,
6366 .payload = sema.addExtraAssumeCapacity(Air.Block{
6367 .body_len = 1,
6368 }),
6369 } },
6370 });
6371 sema.air_extra.appendAssumeCapacity(cond_br_inst);
6372
6373 sema.air_instructions.appendAssumeCapacity(gpa, .{
6374 .tag = .cond_br,
6375 .data = .{ .pl_op = .{
6376 .operand = ok,
6377 .payload = sema.addExtraAssumeCapacity(Air.CondBr{
6378 .then_body_len = 1,
6379 .else_body_len = @intCast(u32, fail_block.instructions.items.len),
6380 }),
6381 } },
6382 });
6383 sema.air_extra.appendAssumeCapacity(br_inst);
6384 sema.air_extra.appendSliceAssumeCapacity(fail_block.instructions.items);
6385
6386 sema.air_instructions.appendAssumeCapacity(gpa, .{
6387 .tag = .br,
6388 .data = .{ .br = .{
6389 .block_inst = block_inst,
6390 .operand = .void_value,
6391 } },
6392 });
6393
6394 parent_block.instructions.appendAssumeCapacity(block_inst);
64396395}
64406396
64416397fn panicWithMsg(
......@@ -6451,18 +6407,18 @@ fn panicWithMsg(
64516407 mod.comp.bin_file.options.object_format == .c;
64526408 if (!this_feature_is_implemented_in_the_backend) {
64536409 // TODO implement this feature in all the backends and then delete this branch
6454 _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint);
6455 _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach);
6410 _ = try block.addNoOp(.breakpoint);
6411 _ = try block.addNoOp(.unreach);
64566412 return always_noreturn;
64576413 }
64586414 const panic_fn = try sema.getBuiltin(block, src, "panic");
64596415 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
64606416 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
64616417 const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One);
6462 const null_stack_trace = try mod.constInst(arena, src, .{
6463 .ty = try mod.optionalType(arena, ptr_stack_trace_ty),
6464 .val = Value.initTag(.null_value),
6465 });
6418 const null_stack_trace = try sema.addConstant(
6419 try mod.optionalType(arena, ptr_stack_trace_ty),
6420 Value.initTag(.null_value),
6421 );
64666422 const args = try arena.create([2]Air.Inst.Index);
64676423 args.* = .{ msg_inst, null_stack_trace };
64686424 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args);
......@@ -6503,7 +6459,6 @@ fn safetyPanic(
65036459 };
65046460
65056461 const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src);
6506
65076462 return sema.panicWithMsg(block, src, casted_msg_inst);
65086463}
65096464
......@@ -6533,13 +6488,13 @@ fn namedFieldPtr(
65336488 switch (elem_ty.zigTypeTag()) {
65346489 .Array => {
65356490 if (mem.eql(u8, field_name, "len")) {
6536 return mod.constInst(arena, src, .{
6537 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
6538 .val = try Value.Tag.ref_val.create(
6491 return sema.addConstant(
6492 Type.initTag(.single_const_pointer_to_comptime_int),
6493 try Value.Tag.ref_val.create(
65396494 arena,
65406495 try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()),
65416496 ),
6542 });
6497 );
65436498 } else {
65446499 return mod.fail(
65456500 &block.base,
......@@ -6554,13 +6509,13 @@ fn namedFieldPtr(
65546509 switch (ptr_child.zigTypeTag()) {
65556510 .Array => {
65566511 if (mem.eql(u8, field_name, "len")) {
6557 return mod.constInst(arena, src, .{
6558 .ty = Type.initTag(.single_const_pointer_to_comptime_int),
6559 .val = try Value.Tag.ref_val.create(
6512 return sema.addConstant(
6513 Type.initTag(.single_const_pointer_to_comptime_int),
6514 try Value.Tag.ref_val.create(
65606515 arena,
65616516 try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()),
65626517 ),
6563 });
6518 );
65646519 } else {
65656520 return mod.fail(
65666521 &block.base,
......@@ -6597,15 +6552,15 @@ fn namedFieldPtr(
65976552 });
65986553 } else (try mod.getErrorValue(field_name)).key;
65996554
6600 return mod.constInst(arena, src, .{
6601 .ty = try Module.simplePtrType(arena, child_type, false, .One),
6602 .val = try Value.Tag.ref_val.create(
6555 return sema.addConstant(
6556 try Module.simplePtrType(arena, child_type, false, .One),
6557 try Value.Tag.ref_val.create(
66036558 arena,
66046559 try Value.Tag.@"error".create(arena, .{
66056560 .name = name,
66066561 }),
66076562 ),
6608 });
6563 );
66096564 },
66106565 .Struct, .Opaque, .Union => {
66116566 if (child_type.getNamespace()) |namespace| {
......@@ -6651,10 +6606,10 @@ fn namedFieldPtr(
66516606 };
66526607 const field_index_u32 = @intCast(u32, field_index);
66536608 const enum_val = try Value.Tag.enum_field_index.create(arena, field_index_u32);
6654 return mod.constInst(arena, src, .{
6655 .ty = try Module.simplePtrType(arena, child_type, false, .One),
6656 .val = try Value.Tag.ref_val.create(arena, enum_val),
6657 });
6609 return sema.addConstant(
6610 try Module.simplePtrType(arena, child_type, false, .One),
6611 try Value.Tag.ref_val.create(arena, enum_val),
6612 );
66586613 },
66596614 else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}),
66606615 }
......@@ -6701,7 +6656,6 @@ fn analyzeStructFieldPtr(
67016656 field_name_src: LazySrcLoc,
67026657 unresolved_struct_ty: Type,
67036658) CompileError!Air.Inst.Ref {
6704 const mod = sema.mod;
67056659 const arena = sema.arena;
67066660 assert(unresolved_struct_ty.zigTypeTag() == .Struct);
67076661
......@@ -6714,13 +6668,13 @@ fn analyzeStructFieldPtr(
67146668 const ptr_field_ty = try Module.simplePtrType(arena, field.ty, true, .One);
67156669
67166670 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
6717 return mod.constInst(arena, src, .{
6718 .ty = ptr_field_ty,
6719 .val = try Value.Tag.field_ptr.create(arena, .{
6671 return sema.addConstant(
6672 ptr_field_ty,
6673 try Value.Tag.field_ptr.create(arena, .{
67206674 .container_ptr = struct_ptr_val,
67216675 .field_index = field_index,
67226676 }),
6723 });
6677 );
67246678 }
67256679
67266680 try sema.requireRuntimeBlock(block, src);
......@@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr(
67516705
67526706 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| {
67536707 // TODO detect inactive union field and emit compile error
6754 return mod.constInst(arena, src, .{
6755 .ty = ptr_field_ty,
6756 .val = try Value.Tag.field_ptr.create(arena, .{
6708 return sema.addConstant(
6709 ptr_field_ty,
6710 try Value.Tag.field_ptr.create(arena, .{
67576711 .container_ptr = union_ptr_val,
67586712 .field_index = field_index,
67596713 }),
6760 });
6714 );
67616715 }
67626716
67636717 try sema.requireRuntimeBlock(block, src);
......@@ -6808,10 +6762,10 @@ fn elemPtrArray(
68086762 const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
68096763 const pointee_type = array_ptr.ty.elemType().elemType();
68106764
6811 return sema.mod.constInst(sema.arena, src, .{
6812 .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
6813 .val = elem_ptr,
6814 });
6765 return sema.addConstant(
6766 try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
6767 elem_ptr,
6768 );
68156769 }
68166770 }
68176771 _ = elem_index;
......@@ -6870,7 +6824,7 @@ fn coerce(
68706824 .Optional => {
68716825 // null to ?T
68726826 if (inst_ty.zigTypeTag() == .Null) {
6873 return mod.constInst(arena, inst_src, .{ .ty = dest_type, .val = Value.initTag(.null_value) });
6827 return sema.addConstant(dest_type, Value.initTag(.null_value));
68746828 }
68756829
68766830 // T to ?T
......@@ -6981,10 +6935,10 @@ fn coerce(
69816935 };
69826936 return mod.failWithOwnedErrorMsg(&block.base, msg);
69836937 };
6984 return mod.constInst(arena, inst_src, .{
6985 .ty = resolved_dest_type,
6986 .val = try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)),
6987 });
6938 return sema.addConstant(
6939 resolved_dest_type,
6940 try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)),
6941 );
69886942 }
69896943 },
69906944 else => {},
......@@ -7024,7 +6978,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R
70246978 if (!val.intFitsInType(dest_type, target)) {
70256979 return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val });
70266980 }
7027 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
6981 return sema.addConstant(dest_type, val);
70286982 }
70296983 } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) {
70306984 if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) {
......@@ -7037,7 +6991,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R
70376991 ),
70386992 error.OutOfMemory => return error.OutOfMemory,
70396993 };
7040 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = res });
6994 return sema.addConstant(dest_type, res);
70416995 } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) {
70426996 return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{});
70436997 }
......@@ -7132,7 +7086,7 @@ fn bitcast(
71327086fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref {
71337087 if (inst.value()) |val| {
71347088 // The comptime Value representation is compatible with both types.
7135 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
7089 return sema.addConstant(dest_type, val);
71367090 }
71377091 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{});
71387092}
......@@ -7140,7 +7094,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst
71407094fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref {
71417095 if (inst.value()) |val| {
71427096 // The comptime Value representation is compatible with both types.
7143 return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val });
7097 return sema.addConstant(dest_type, val);
71447098 }
71457099 return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{});
71467100}
......@@ -7200,13 +7154,11 @@ fn analyzeRef(
72007154 src: LazySrcLoc,
72017155 operand: Air.Inst.Ref,
72027156) CompileError!Air.Inst.Ref {
7203 const ptr_type = try sema.mod.simplePtrType(sema.arena, operand.ty, false, .One);
7157 const operand_ty = sema.getTypeOf(operand);
7158 const ptr_type = try sema.mod.simplePtrType(sema.arena, operand_ty, false, .One);
72047159
72057160 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |val| {
7206 return sema.mod.constInst(sema.arena, src, .{
7207 .ty = ptr_type,
7208 .val = try Value.Tag.ref_val.create(sema.arena, val),
7209 });
7161 return sema.addConstant(ptr_type, try Value.Tag.ref_val.create(sema.arena, val));
72107162 }
72117163
72127164 try sema.requireRuntimeBlock(block, src);
......@@ -7267,7 +7219,8 @@ fn analyzeIsNonErr(
72677219 src: LazySrcLoc,
72687220 operand: Air.Inst.Ref,
72697221) CompileError!Air.Inst.Ref {
7270 const ot = operand.ty.zigTypeTag();
7222 const operand_ty = sema.getTypeOf(operand);
7223 const ot = operand_ty.zigTypeTag();
72717224 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
72727225 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
72737226 assert(ot == .ErrorUnion);
......@@ -7549,7 +7502,7 @@ fn cmpNumeric(
75497502
75507503fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {
75517504 if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| {
7552 return sema.mod.constInst(sema.arena, inst_src, .{ .ty = dest_type, .val = val });
7505 return sema.addConstant(dest_type, val);
75537506 }
75547507
75557508 try sema.requireRuntimeBlock(block, inst.src);
......@@ -7614,11 +7567,8 @@ fn wrapErrorUnion(
76147567 else => unreachable,
76157568 }
76167569
7617 return sema.mod.constInst(sema.arena, inst.src, .{
7618 .ty = dest_type,
7619 // creating a SubValue for the error_union payload
7620 .val = try Value.Tag.error_union.create(sema.arena, val),
7621 });
7570 // Create a SubValue for the error_union payload.
7571 return sema.addConstant(dest_type, try Value.Tag.error_union.create(sema.arena, val));
76227572 }
76237573
76247574 try sema.requireRuntimeBlock(block, inst.src);
src/Zir.zig+4-15
......@@ -386,7 +386,7 @@ pub const Inst = struct {
386386 int,
387387 /// Arbitrary sized integer literal. Uses the `str` union field.
388388 int_big,
389 /// A float literal that fits in a f32. Uses the float union value.
389 /// A float literal that fits in a f64. Uses the float union value.
390390 float,
391391 /// A float literal that fits in a f128. Uses the `pl_node` union value.
392392 /// Payload is `Float128`.
......@@ -2058,16 +2058,7 @@ pub const Inst = struct {
20582058 /// Offset from Decl AST node index.
20592059 node: i32,
20602060 int: u64,
2061 float: struct {
2062 /// Offset from Decl AST node index.
2063 /// `Tag` determines which kind of AST node this points to.
2064 src_node: i32,
2065 number: f32,
2066
2067 pub fn src(self: @This()) LazySrcLoc {
2068 return .{ .node_offset = self.src_node };
2069 }
2070 },
2061 float: f64,
20712062 array_type_sentinel: struct {
20722063 len: Ref,
20732064 /// index into extra, points to an `ArrayTypeSentinel`
......@@ -3256,10 +3247,8 @@ const Writer = struct {
32563247 }
32573248
32583249 fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3259 const inst_data = self.code.instructions.items(.data)[inst].float;
3260 const src = inst_data.src();
3261 try stream.print("{d}) ", .{inst_data.number});
3262 try self.writeSrc(stream, src);
3250 const number = self.code.instructions.items(.data)[inst].float;
3251 try stream.print("{d})", .{number});
32633252 }
32643253
32653254 fn writeFloat128(self: *Writer, stream: anytype, inst: Inst.Index) !void {