authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-13 21:49:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
logdbd3529d1fa02d5e720df0fbf2436d646f5a4f57
treeb75125e6b9847fe962c69550ae9e9e9ce9169e79
parentf17a05bfb7ca0ff010fef9654264eed7342298d2

Sema: first pass reworking for AIR memory layout


3 files changed, 286 insertions(+), 297 deletions(-)

BRANCH_TODO-89
......@@ -569,95 +569,6 @@ const DumpAir = struct {
569569 }
570570};
571571
572pub fn constInst(mod: *Module, arena: *Allocator, src: LazySrcLoc, typed_value: TypedValue) !*ir.Inst {
573 _ = mod;
574 const const_inst = try arena.create(ir.Inst.Constant);
575 const_inst.* = .{
576 .base = .{
577 .tag = ir.Inst.Constant.base_tag,
578 .ty = typed_value.ty,
579 .src = src,
580 },
581 .val = typed_value.val,
582 };
583 return &const_inst.base;
584}
585
586pub fn constType(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
587 return mod.constInst(arena, src, .{
588 .ty = Type.initTag(.type),
589 .val = try ty.toValue(arena),
590 });
591}
592
593pub fn constVoid(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
594 return mod.constInst(arena, src, .{
595 .ty = Type.initTag(.void),
596 .val = Value.initTag(.void_value),
597 });
598}
599
600pub fn constNoReturn(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
601 return mod.constInst(arena, src, .{
602 .ty = Type.initTag(.noreturn),
603 .val = Value.initTag(.unreachable_value),
604 });
605}
606
607pub fn constUndef(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
608 return mod.constInst(arena, src, .{
609 .ty = ty,
610 .val = Value.initTag(.undef),
611 });
612}
613
614pub fn constBool(mod: *Module, arena: *Allocator, src: LazySrcLoc, v: bool) !*ir.Inst {
615 return mod.constInst(arena, src, .{
616 .ty = Type.initTag(.bool),
617 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],
618 });
619}
620
621pub fn constIntUnsigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: u64) !*ir.Inst {
622 return mod.constInst(arena, src, .{
623 .ty = ty,
624 .val = try Value.Tag.int_u64.create(arena, int),
625 });
626}
627
628pub fn constIntSigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: i64) !*ir.Inst {
629 return mod.constInst(arena, src, .{
630 .ty = ty,
631 .val = try Value.Tag.int_i64.create(arena, int),
632 });
633}
634
635pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, big_int: BigIntConst) !*ir.Inst {
636 if (big_int.positive) {
637 if (big_int.to(u64)) |x| {
638 return mod.constIntUnsigned(arena, src, ty, x);
639 } else |err| switch (err) {
640 error.NegativeIntoUnsigned => unreachable,
641 error.TargetTooSmall => {}, // handled below
642 }
643 return mod.constInst(arena, src, .{
644 .ty = ty,
645 .val = try Value.Tag.int_big_positive.create(arena, big_int.limbs),
646 });
647 } else {
648 if (big_int.to(i64)) |x| {
649 return mod.constIntSigned(arena, src, ty, x);
650 } else |err| switch (err) {
651 error.NegativeIntoUnsigned => unreachable,
652 error.TargetTooSmall => {}, // handled below
653 }
654 return mod.constInst(arena, src, .{
655 .ty = ty,
656 .val = try Value.Tag.int_big_negative.create(arena, big_int.limbs),
657 });
658 }
659}
660
661572pub fn dumpInst(mod: *Module, scope: *Scope, inst: *ir.Inst) void {
662573 const zir_module = scope.namespace();
663574 const source = zir_module.getSource(mod) catch @panic("dumpInst failed to get source");
src/Module.zig+40-10
......@@ -1232,22 +1232,52 @@ pub const Scope = struct {
12321232 ty: Type,
12331233 operand: Air.Inst.Ref,
12341234 ) error{OutOfMemory}!Air.Inst.Ref {
1235 return block.addInst(.{
1236 .tag = tag,
1237 .data = .{ .ty_op = .{
1238 .ty = try block.sema.addType(ty),
1239 .operand = operand,
1240 } },
1241 });
1242 }
1243
1244 pub fn addUnOp(
1245 block: *Block,
1246 tag: Air.Inst.Tag,
1247 operand: Air.Inst.Ref,
1248 ) error{OutOfMemory}!Air.Inst.Ref {
1249 return block.addInst(.{
1250 .tag = tag,
1251 .data = .{ .un_op = operand },
1252 });
1253 }
1254
1255 pub fn addBinOp(
1256 block: *Block,
1257 tag: Air.Inst.Tag,
1258 lhs: Air.Inst.Ref,
1259 rhs: Air.Inst.Ref,
1260 ) error{OutOfMemory}!Air.Inst.Ref {
1261 return block.addInst(.{
1262 .tag = tag,
1263 .data = .{ .bin_op = .{
1264 .lhs = lhs,
1265 .rhs = rhs,
1266 } },
1267 });
1268 }
1269
1270 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {
12351271 const sema = block.sema;
12361272 const gpa = sema.gpa;
12371273
12381274 try sema.air_instructions.ensureUnusedCapacity(gpa, 1);
12391275 try block.instructions.ensureUnusedCapacity(gpa, 1);
12401276
1241 const inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
1242 sema.air_instructions.appendAssumeCapacity(.{
1243 .tag = tag,
1244 .data = .{ .ty_op = .{
1245 .ty = try sema.addType(ty),
1246 .operand = operand,
1247 } },
1248 });
1249 block.instructions.appendAssumeCapacity(inst);
1250 return Sema.indexToRef(inst);
1277 const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len);
1278 sema.air_instructions.appendAssumeCapacity(inst);
1279 block.instructions.appendAssumeCapacity(result_index);
1280 return Sema.indexToRef(result_index);
12511281 }
12521282 };
12531283};
src/Sema.zig+246-198
......@@ -534,7 +534,7 @@ pub fn analyzeBody(
534534 //},
535535 else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"),
536536 };
537 if (sema.getAirType(air_inst).isNoReturn())
537 if (sema.getTypeOf(air_inst).isNoReturn())
538538 return always_noreturn;
539539 try map.put(sema.gpa, inst, air_inst);
540540 i += 1;
......@@ -664,7 +664,7 @@ fn resolvePossiblyUndefinedValue(
664664 src: LazySrcLoc,
665665 air_ref: Air.Inst.Ref,
666666) !?Value {
667 const ty = sema.getTypeOfAirRef(air_ref);
667 const ty = sema.getTypeOf(air_ref);
668668 if (try sema.typeHasOnePossibleValue(block, src, ty)) |opv| {
669669 return opv;
670670 }
......@@ -737,7 +737,7 @@ pub fn resolveInstConst(
737737 const air_ref = sema.resolveInst(zir_ref);
738738 const val = try sema.resolveConstValue(block, src, air_ref);
739739 return TypedValue{
740 .ty = sema.getTypeOfAirRef(air_ref),
740 .ty = sema.getTypeOf(air_ref),
741741 .val = val,
742742 };
743743}
......@@ -1208,7 +1208,7 @@ fn zirRetType(
12081208 try sema.requireFunctionBlock(block, src);
12091209 const fn_ty = sema.func.?.owner_decl.ty;
12101210 const ret_type = fn_ty.fnReturnType();
1211 return sema.mod.constType(sema.arena, src, ret_type);
1211 return sema.addType(ret_type);
12121212}
12131213
12141214fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
......@@ -1571,7 +1571,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
15711571 // if expressions should force it when the condition is compile-time known.
15721572 const src: LazySrcLoc = .unneeded;
15731573 try sema.requireRuntimeBlock(block, src);
1574 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
1574 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
15751575 return sema.storePtr(block, src, bitcasted_ptr, value);
15761576}
15771577
......@@ -1590,7 +1590,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
15901590 // Create a runtime bitcast instruction with exactly the type the pointer wants.
15911591 const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One);
15921592 try sema.requireRuntimeBlock(block, src);
1593 const bitcasted_ptr = try block.addUnOp(src, ptr_ty, .bitcast, ptr);
1593 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
15941594 return sema.storePtr(block, src, bitcasted_ptr, value);
15951595}
15961596
......@@ -1646,7 +1646,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
16461646 const param_count = fn_ty.fnParamLen();
16471647 if (param_index >= param_count) {
16481648 if (fn_ty.fnIsVarArgs()) {
1649 return sema.mod.constType(sema.arena, src, Type.initTag(.var_args_param));
1649 return sema.addType(Type.initTag(.var_args_param));
16501650 }
16511651 return sema.mod.fail(&block.base, src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{
16521652 param_index,
......@@ -1657,7 +1657,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
16571657
16581658 // TODO support generic functions
16591659 const param_type = fn_ty.fnParamType(param_index);
1660 return sema.mod.constType(sema.arena, src, param_type);
1660 return sema.addType(param_type);
16611661}
16621662
16631663fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -1694,7 +1694,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air
16941694 defer tracy.end();
16951695
16961696 const int = sema.code.instructions.items(.data)[inst].int;
1697 return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int);
1697 return sema.addIntUnsigned(Type.initTag(.comptime_int), int);
16981698}
16991699
17001700fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2418,10 +2418,9 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
24182418 defer tracy.end();
24192419
24202420 const int_type = sema.code.instructions.items(.data)[inst].int_type;
2421 const src = int_type.src();
24222421 const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);
24232422
2424 return sema.mod.constType(sema.arena, src, ty);
2423 return sema.addType(ty);
24252424}
24262425
24272426fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2433,7 +2432,7 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
24332432 const child_type = try sema.resolveType(block, src, inst_data.operand);
24342433 const opt_type = try sema.mod.optionalType(sema.arena, child_type);
24352434
2436 return sema.mod.constType(sema.arena, src, opt_type);
2435 return sema.addType(opt_type);
24372436}
24382437
24392438fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2441,12 +2440,11 @@ fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
24412440 const src = inst_data.src();
24422441 const array_type = try sema.resolveType(block, src, inst_data.operand);
24432442 const elem_type = array_type.elemType();
2444 return sema.mod.constType(sema.arena, src, elem_type);
2443 return sema.addType(elem_type);
24452444}
24462445
24472446fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
24482447 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2449 const src = inst_data.src();
24502448 const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
24512449 const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
24522450 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
......@@ -2456,7 +2454,7 @@ fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
24562454 .len = len,
24572455 .elem_type = elem_type,
24582456 });
2459 return sema.mod.constType(sema.arena, src, vector_type);
2457 return sema.addType(vector_type);
24602458}
24612459
24622460fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2469,7 +2467,7 @@ fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
24692467 const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs);
24702468 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type);
24712469
2472 return sema.mod.constType(sema.arena, .unneeded, array_ty);
2470 return sema.addType(array_ty);
24732471}
24742472
24752473fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2484,7 +2482,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
24842482 const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type);
24852483 const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type);
24862484
2487 return sema.mod.constType(sema.arena, .unneeded, array_ty);
2485 return sema.addType(array_ty);
24882486}
24892487
24902488fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2492,12 +2490,11 @@ fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
24922490 defer tracy.end();
24932491
24942492 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2495 const src = inst_data.src();
24962493 const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node };
24972494 const return_type = try sema.resolveType(block, operand_src, inst_data.operand);
24982495 const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type);
24992496
2500 return sema.mod.constType(sema.arena, src, anyframe_type);
2497 return sema.addType(anyframe_type);
25012498}
25022499
25032500fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2506,7 +2503,6 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
25062503
25072504 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
25082505 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2509 const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
25102506 const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
25112507 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
25122508 const error_union = try sema.resolveType(block, lhs_src, extra.lhs);
......@@ -2518,7 +2514,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
25182514 });
25192515 }
25202516 const err_union_ty = try sema.mod.errorUnionType(sema.arena, error_union, payload);
2521 return sema.mod.constType(sema.arena, src, err_union_ty);
2517 return sema.addType(err_union_ty);
25222518}
25232519
25242520fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2553,7 +2549,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
25532549
25542550 if (try sema.resolvePossiblyUndefinedValue(block, src, op_coerced)) |val| {
25552551 if (val.isUndef()) {
2556 return sema.mod.constUndef(sema.arena, src, result_ty);
2552 return sema.addConstUndef(result_ty);
25572553 }
25582554 const payload = try sema.arena.create(Value.Payload.U64);
25592555 payload.* = .{
......@@ -2567,7 +2563,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
25672563 }
25682564
25692565 try sema.requireRuntimeBlock(block, src);
2570 return block.addUnOp(src, result_ty, .bitcast, op_coerced);
2566 return block.addTyOp(.bitcast, result_ty, op_coerced);
25712567}
25722568
25732569fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2600,7 +2596,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
26002596 // const is_gt_max = @panic("TODO get max errors in compilation");
26012597 // try sema.addSafetyCheck(block, is_gt_max, .invalid_error_code);
26022598 }
2603 return block.addUnOp(src, Type.initTag(.anyerror), .bitcast, op);
2599 return block.addTyOp(.bitcast, Type.initTag(.anyerror), op);
26042600}
26052601
26062602fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2614,7 +2610,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
26142610 const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
26152611 const lhs = sema.resolveInst(extra.lhs);
26162612 const rhs = sema.resolveInst(extra.rhs);
2617 if (rhs.ty.zigTypeTag() == .Bool and lhs.ty.zigTypeTag() == .Bool) {
2613 const lhs_ty = sema.getTypeOf(lhs);
2614 const rhs_ty = sema.getTypeOf(rhs);
2615 if (rhs_ty.zigTypeTag() == .Bool and lhs_ty.zigTypeTag() == .Bool) {
26182616 const msg = msg: {
26192617 const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{});
26202618 errdefer msg.destroy(sema.gpa);
......@@ -2623,8 +2621,6 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn
26232621 };
26242622 return sema.mod.failWithOwnedErrorMsg(&block.base, msg);
26252623 }
2626 const rhs_ty = try sema.resolveAirAsType(block, rhs_src, rhs);
2627 const lhs_ty = try sema.resolveAirAsType(block, lhs_src, lhs);
26282624 if (rhs_ty.zigTypeTag() != .ErrorSet)
26292625 return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty});
26302626 if (lhs_ty.zigTypeTag() != .ErrorSet)
......@@ -2786,7 +2782,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
27862782 }
27872783
27882784 try sema.requireRuntimeBlock(block, src);
2789 return block.addUnOp(src, int_tag_ty, .bitcast, enum_tag);
2785 return block.addTyOp(.bitcast, int_tag_ty, enum_tag);
27902786}
27912787
27922788fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -2841,7 +2837,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
28412837 }
28422838
28432839 try sema.requireRuntimeBlock(block, src);
2844 return block.addUnOp(src, dest_ty, .bitcast, operand);
2840 return block.addTyOp(.bitcast, dest_ty, operand);
28452841}
28462842
28472843/// Pointer in, pointer out.
......@@ -2881,10 +2877,10 @@ fn zirOptionalPayloadPtr(
28812877
28822878 try sema.requireRuntimeBlock(block, src);
28832879 if (safety_check and block.wantSafety()) {
2884 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null_ptr, optional_ptr);
2880 const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr);
28852881 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
28862882 }
2887 return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr);
2883 return block.addTyOp(.optional_payload_ptr, child_pointer, optional_ptr);
28882884}
28892885
28902886/// Value in, value out.
......@@ -2919,10 +2915,10 @@ fn zirOptionalPayload(
29192915
29202916 try sema.requireRuntimeBlock(block, src);
29212917 if (safety_check and block.wantSafety()) {
2922 const is_non_null = try block.addUnOp(src, Type.initTag(.bool), .is_non_null, operand);
2918 const is_non_null = try block.addUnOp(.is_non_null, operand);
29232919 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
29242920 }
2925 return block.addUnOp(src, child_type, .optional_payload, operand);
2921 return block.addTyOp(.optional_payload, child_type, operand);
29262922}
29272923
29282924/// Value in, value out
......@@ -2953,10 +2949,11 @@ fn zirErrUnionPayload(
29532949 }
29542950 try sema.requireRuntimeBlock(block, src);
29552951 if (safety_check and block.wantSafety()) {
2956 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);
2952 const is_non_err = try block.addUnOp(.is_err, operand);
29572953 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
29582954 }
2959 return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_payload, operand);
2955 const result_ty = operand.ty.castTag(.error_union).?.data.payload;
2956 return block.addTyOp(.unwrap_errunion_payload, result_ty, operand);
29602957}
29612958
29622959/// Pointer in, pointer out.
......@@ -2997,10 +2994,10 @@ fn zirErrUnionPayloadPtr(
29972994
29982995 try sema.requireRuntimeBlock(block, src);
29992996 if (safety_check and block.wantSafety()) {
3000 const is_non_err = try block.addUnOp(src, Type.initTag(.bool), .is_err, operand);
2997 const is_non_err = try block.addUnOp(.is_err, operand);
30012998 try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion);
30022999 }
3003 return block.addUnOp(src, operand_pointer_ty, .unwrap_errunion_payload_ptr, operand);
3000 return block.addTyOp(.unwrap_errunion_payload_ptr, operand_pointer_ty, operand);
30043001}
30053002
30063003/// Value in, value out
......@@ -3026,7 +3023,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner
30263023 }
30273024
30283025 try sema.requireRuntimeBlock(block, src);
3029 return block.addUnOp(src, result_ty, .unwrap_errunion_err, operand);
3026 return block.addTyOp(.unwrap_errunion_err, result_ty, operand);
30303027}
30313028
30323029/// Pointer in, value out
......@@ -3055,7 +3052,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
30553052 }
30563053
30573054 try sema.requireRuntimeBlock(block, src);
3058 return block.addUnOp(src, result_ty, .unwrap_errunion_err_ptr, operand);
3055 return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand);
30593056}
30603057
30613058fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
......@@ -3241,7 +3238,7 @@ fn funcCommon(
32413238 }
32423239
32433240 if (body_inst == 0) {
3244 return mod.constType(sema.arena, src, fn_ty);
3241 return sema.addType(fn_ty);
32453242 }
32463243
32473244 const is_inline = fn_ty.fnCallingConvention() == .Inline;
......@@ -3312,8 +3309,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
33123309 // TODO handle known-pointer-address
33133310 const src = inst_data.src();
33143311 try sema.requireRuntimeBlock(block, src);
3315 const ty = Type.initTag(.usize);
3316 return block.addUnOp(src, ty, .ptrtoint, ptr);
3312 return block.addUnOp(.ptrtoint, ptr);
33173313}
33183314
33193315fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -4244,15 +4240,14 @@ fn analyzeSwitch(
42444240 case_block.instructions.shrinkRetainingCapacity(0);
42454241
42464242 var any_ok: ?Air.Inst.Index = null;
4247 const bool_ty = comptime Type.initTag(.bool);
42484243
42494244 for (items) |item_ref| {
42504245 const item = sema.resolveInst(item_ref);
42514246 _ = try sema.resolveConstValue(&child_block, item.src, item);
42524247
4253 const cmp_ok = try case_block.addBinOp(item.src, bool_ty, .cmp_eq, operand, item);
4248 const cmp_ok = try case_block.addBinOp(.cmp_eq, operand, item);
42544249 if (any_ok) |some| {
4255 any_ok = try case_block.addBinOp(item.src, bool_ty, .bool_or, some, cmp_ok);
4250 any_ok = try case_block.addBinOp(.bool_or, some, cmp_ok);
42564251 } else {
42574252 any_ok = cmp_ok;
42584253 }
......@@ -4271,32 +4266,24 @@ fn analyzeSwitch(
42714266 _ = try sema.resolveConstValue(&child_block, item_first.src, item_first);
42724267 _ = try sema.resolveConstValue(&child_block, item_last.src, item_last);
42734268
4274 const range_src = item_first.src;
4275
42764269 // operand >= first and operand <= last
42774270 const range_first_ok = try case_block.addBinOp(
4278 item_first.src,
4279 bool_ty,
42804271 .cmp_gte,
42814272 operand,
42824273 item_first,
42834274 );
42844275 const range_last_ok = try case_block.addBinOp(
4285 item_last.src,
4286 bool_ty,
42874276 .cmp_lte,
42884277 operand,
42894278 item_last,
42904279 );
42914280 const range_ok = try case_block.addBinOp(
4292 range_src,
4293 bool_ty,
42944281 .bool_and,
42954282 range_first_ok,
42964283 range_last_ok,
42974284 );
42984285 if (any_ok) |some| {
4299 any_ok = try case_block.addBinOp(range_src, bool_ty, .bool_or, some, range_ok);
4286 any_ok = try case_block.addBinOp(.bool_or, some, range_ok);
43004287 } else {
43014288 any_ok = range_ok;
43024289 }
......@@ -4555,13 +4542,11 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
45554542fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
45564543 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
45574544 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
4558 const src = inst_data.src();
45594545 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
45604546 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
45614547 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
45624548 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
45634549 const mod = sema.mod;
4564 const arena = sema.arena;
45654550
45664551 const namespace = container_type.getNamespace() orelse return mod.fail(
45674552 &block.base,
......@@ -4571,10 +4556,10 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
45714556 );
45724557 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {
45734558 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {
4574 return mod.constBool(arena, src, true);
4559 return Air.Inst.Ref.bool_true;
45754560 }
45764561 }
4577 return mod.constBool(arena, src, false);
4562 return Air.Inst.Ref.bool_false;
45784563}
45794564
45804565fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -4599,7 +4584,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
45994584 try mod.semaFile(result.file);
46004585 const file_root_decl = result.file.root_decl.?;
46014586 try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl);
4602 return mod.constType(sema.arena, src, file_root_decl.ty);
4587 return sema.addType(file_root_decl.ty);
46034588}
46044589
46054590fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -4641,6 +4626,8 @@ fn zirBitwise(
46414626 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
46424627 const lhs = sema.resolveInst(extra.lhs);
46434628 const rhs = sema.resolveInst(extra.rhs);
4629 const lhs_ty = sema.getTypeOf(lhs);
4630 const rhs_ty = sema.getTypeOf(rhs);
46444631
46454632 const instructions = &[_]Air.Inst.Index{ lhs, rhs };
46464633 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
......@@ -4654,38 +4641,38 @@ fn zirBitwise(
46544641
46554642 const scalar_tag = scalar_type.zigTypeTag();
46564643
4657 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
4658 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {
4644 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
4645 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
46594646 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
4660 lhs.ty.arrayLen(),
4661 rhs.ty.arrayLen(),
4647 lhs_ty.arrayLen(),
4648 rhs_ty.arrayLen(),
46624649 });
46634650 }
46644651 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBitwise", .{});
4665 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {
4652 } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
46664653 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
4667 lhs.ty,
4668 rhs.ty,
4654 lhs_ty,
4655 rhs_ty,
46694656 });
46704657 }
46714658
46724659 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
46734660
46744661 if (!is_int) {
4675 return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });
4662 return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
46764663 }
46774664
46784665 if (casted_lhs.value()) |lhs_val| {
46794666 if (casted_rhs.value()) |rhs_val| {
46804667 if (lhs_val.isUndef() or rhs_val.isUndef()) {
4681 return sema.mod.constUndef(sema.arena, src, resolved_type);
4668 return sema.addConstUndef(resolved_type);
46824669 }
46834670 return sema.mod.fail(&block.base, src, "TODO implement comptime bitwise operations", .{});
46844671 }
46854672 }
46864673
46874674 try sema.requireRuntimeBlock(block, src);
4688 return block.addBinOp(src, scalar_type, air_tag, casted_lhs, casted_rhs);
4675 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
46894676}
46904677
46914678fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -4783,18 +4770,18 @@ fn analyzeArithmetic(
47834770
47844771 const scalar_tag = scalar_type.zigTypeTag();
47854772
4786 if (lhs.ty.zigTypeTag() == .Vector and rhs.ty.zigTypeTag() == .Vector) {
4787 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {
4773 if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
4774 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
47884775 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
4789 lhs.ty.arrayLen(),
4790 rhs.ty.arrayLen(),
4776 lhs_ty.arrayLen(),
4777 rhs_ty.arrayLen(),
47914778 });
47924779 }
47934780 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBinOp", .{});
4794 } else if (lhs.ty.zigTypeTag() == .Vector or rhs.ty.zigTypeTag() == .Vector) {
4781 } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
47954782 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
4796 lhs.ty,
4797 rhs.ty,
4783 lhs_ty,
4784 rhs_ty,
47984785 });
47994786 }
48004787
......@@ -4802,13 +4789,13 @@ fn analyzeArithmetic(
48024789 const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
48034790
48044791 if (!is_int and !(is_float and floatOpAllowed(zir_tag))) {
4805 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) });
4792 return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
48064793 }
48074794
48084795 if (casted_lhs.value()) |lhs_val| {
48094796 if (casted_rhs.value()) |rhs_val| {
48104797 if (lhs_val.isUndef() or rhs_val.isUndef()) {
4811 return sema.mod.constUndef(sema.arena, src, resolved_type);
4798 return sema.addConstUndef(resolved_type);
48124799 }
48134800 // incase rhs is 0, simply return lhs without doing any calculations
48144801 // TODO Once division is implemented we should throw an error when dividing by 0.
......@@ -4866,7 +4853,7 @@ fn analyzeArithmetic(
48664853 }
48674854
48684855 try sema.requireRuntimeBlock(block, src);
4869 const ir_tag: Inst.Tag = switch (zir_tag) {
4856 const air_tag: Air.Inst.Tag = switch (zir_tag) {
48704857 .add => .add,
48714858 .addwrap => .addwrap,
48724859 .sub => .sub,
......@@ -4877,7 +4864,7 @@ fn analyzeArithmetic(
48774864 else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}),
48784865 };
48794866
4880 return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs);
4867 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
48814868}
48824869
48834870fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -4997,11 +4984,17 @@ fn zirCmp(
49974984 .eq, .neq => true,
49984985 else => false,
49994986 };
5000 const lhs_ty_tag = lhs.ty.zigTypeTag();
5001 const rhs_ty_tag = rhs.ty.zigTypeTag();
4987 const lhs_ty = sema.getTypeOf(lhs);
4988 const rhs_ty = sema.getTypeOf(rhs);
4989 const lhs_ty_tag = lhs_ty.zigTypeTag();
4990 const rhs_ty_tag = rhs_ty.zigTypeTag();
50024991 if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) {
50034992 // null == null, null != null
5004 return mod.constBool(sema.arena, src, op == .eq);
4993 if (op == .eq) {
4994 return Air.Inst.Ref.bool_true;
4995 } else {
4996 return Air.Inst.Ref.bool_false;
4997 }
50054998 } else if (is_equality_cmp and
50064999 ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or
50075000 rhs_ty_tag == .Null and lhs_ty_tag == .Optional))
......@@ -5010,11 +5003,11 @@ fn zirCmp(
50105003 const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs;
50115004 return sema.analyzeIsNull(block, src, opt_operand, op == .neq);
50125005 } else if (is_equality_cmp and
5013 ((lhs_ty_tag == .Null and rhs.ty.isCPtr()) or (rhs_ty_tag == .Null and lhs.ty.isCPtr())))
5006 ((lhs_ty_tag == .Null and rhs_ty.isCPtr()) or (rhs_ty_tag == .Null and lhs_ty.isCPtr())))
50145007 {
50155008 return mod.fail(&block.base, src, "TODO implement C pointer cmp", .{});
50165009 } else if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) {
5017 const non_null_type = if (lhs_ty_tag == .Null) rhs.ty else lhs.ty;
5010 const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty;
50185011 return mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type});
50195012 } else if (is_equality_cmp and
50205013 ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or
......@@ -5025,27 +5018,45 @@ fn zirCmp(
50255018 if (!is_equality_cmp) {
50265019 return mod.fail(&block.base, src, "{s} operator not allowed for errors", .{@tagName(op)});
50275020 }
5028 if (rhs.value()) |rval| {
5029 if (lhs.value()) |lval| {
5030 // 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
5031 return mod.constBool(sema.arena, src, std.mem.eql(u8, lval.castTag(.@"error").?.data.name, rval.castTag(.@"error").?.data.name) == (op == .eq));
5021 if (try sema.resolvePossiblyUndefinedValue(block, lhs_src, lhs)) |lval| {
5022 if (try sema.resolvePossiblyUndefinedValue(block, rhs_src, rhs)) |rval| {
5023 if (lval.isUndef() or rval.isUndef()) {
5024 return sema.addConstUndef(Type.initTag(.bool));
5025 }
5026 // TODO optimisation opportunity: evaluate if mem.eql is faster with the names,
5027 // or calling to Module.getErrorValue to get the values and then compare them is
5028 // faster.
5029 const lhs_name = lval.castTag(.@"error").?.data.name;
5030 const rhs_name = rval.castTag(.@"error").?.data.name;
5031 if (mem.eql(u8, lhs_name, rhs_name) == (op == .eq)) {
5032 return Air.Inst.Ref.bool_true;
5033 } else {
5034 return Air.Inst.Ref.bool_false;
5035 }
50325036 }
50335037 }
50345038 try sema.requireRuntimeBlock(block, src);
5035 return block.addBinOp(src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs);
5036 } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) {
5039 const tag: Air.Inst.Tag = if (op == .eq) .cmp_eq else .cmp_neq;
5040 return block.addBinOp(tag, lhs, rhs);
5041 } else if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) {
50375042 // This operation allows any combination of integer and float types, regardless of the
50385043 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for
50395044 // numeric types.
5040 return sema.cmpNumeric(block, src, lhs, rhs, op);
5045 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
50415046 } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) {
50425047 if (!is_equality_cmp) {
50435048 return mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)});
50445049 }
5045 return mod.constBool(sema.arena, src, lhs.value().?.eql(rhs.value().?) == (op == .eq));
5050 const lhs_as_type = try sema.resolveAirAsType(block, lhs_src, lhs);
5051 const rhs_as_type = try sema.resolveAirAsType(block, rhs_src, rhs);
5052 if (lhs_as_type.eql(rhs_as_type) == (op == .eq)) {
5053 return Air.Inst.Ref.bool_true;
5054 } else {
5055 return Air.Inst.Ref.bool_false;
5056 }
50465057 }
50475058
5048 const instructions = &[_]Air.Inst.Index{ lhs, rhs };
5059 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
50495060 const resolved_type = try sema.resolvePeerTypes(block, src, instructions);
50505061 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
50515062 return mod.fail(&block.base, src, "operator not allowed for type '{}'", .{resolved_type});
......@@ -5057,15 +5068,18 @@ fn zirCmp(
50575068 if (casted_lhs.value()) |lhs_val| {
50585069 if (casted_rhs.value()) |rhs_val| {
50595070 if (lhs_val.isUndef() or rhs_val.isUndef()) {
5060 return sema.mod.constUndef(sema.arena, src, resolved_type);
5071 return sema.addConstUndef(resolved_type);
5072 }
5073 if (lhs_val.compare(op, rhs_val)) {
5074 return Air.Inst.Ref.bool_true;
5075 } else {
5076 return Air.Inst.Ref.bool_false;
50615077 }
5062 const result = lhs_val.compare(op, rhs_val);
5063 return sema.mod.constBool(sema.arena, src, result);
50645078 }
50655079 }
50665080
50675081 try sema.requireRuntimeBlock(block, src);
5068 const tag: Inst.Tag = switch (op) {
5082 const tag: Air.Inst.Tag = switch (op) {
50695083 .lt => .cmp_lt,
50705084 .lte => .cmp_lte,
50715085 .eq => .cmp_eq,
......@@ -5073,28 +5087,26 @@ fn zirCmp(
50735087 .gt => .cmp_gt,
50745088 .neq => .cmp_neq,
50755089 };
5076 const bool_type = Type.initTag(.bool); // TODO handle vectors
5077 return block.addBinOp(src, bool_type, tag, casted_lhs, casted_rhs);
5090 // TODO handle vectors
5091 return block.addBinOp(tag, casted_lhs, casted_rhs);
50785092}
50795093
50805094fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
50815095 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5082 const src = inst_data.src();
50835096 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
50845097 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
50855098 const target = sema.mod.getTarget();
50865099 const abi_size = operand_ty.abiSize(target);
5087 return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), abi_size);
5100 return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size);
50885101}
50895102
50905103fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
50915104 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5092 const src = inst_data.src();
50935105 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
50945106 const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
50955107 const target = sema.mod.getTarget();
50965108 const bit_size = operand_ty.bitSize(target);
5097 return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), bit_size);
5109 return sema.addIntUnsigned(Type.initTag(.comptime_int), bit_size);
50985110}
50995111
51005112fn zirThis(
......@@ -5171,18 +5183,16 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!
51715183 _ = block;
51725184 const zir_datas = sema.code.instructions.items(.data);
51735185 const inst_data = zir_datas[inst].un_node;
5174 const src = inst_data.src();
51755186 const operand = sema.resolveInst(inst_data.operand);
5176 return sema.mod.constType(sema.arena, src, operand.ty);
5187 return sema.addType(operand.ty);
51775188}
51785189
51795190fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
51805191 _ = block;
51815192 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5182 const src = inst_data.src();
51835193 const operand_ptr = sema.resolveInst(inst_data.operand);
51845194 const elem_ty = operand_ptr.ty.elemType();
5185 return sema.mod.constType(sema.arena, src, elem_ty);
5195 return sema.addType(elem_ty);
51865196}
51875197
51885198fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -5217,7 +5227,7 @@ fn zirTypeofPeer(
52175227 }
52185228
52195229 const result_type = try sema.resolvePeerTypes(block, src, inst_list);
5220 return sema.mod.constType(sema.arena, src, result_type);
5230 return sema.addType(result_type);
52215231}
52225232
52235233fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -5231,17 +5241,21 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
52315241 const bool_type = Type.initTag(.bool);
52325242 const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src);
52335243 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
5234 return sema.mod.constBool(sema.arena, src, !val.toBool());
5244 if (val.toBool()) {
5245 return Air.Inst.Ref.bool_false;
5246 } else {
5247 return Air.Inst.Ref.bool_true;
5248 }
52355249 }
52365250 try sema.requireRuntimeBlock(block, src);
5237 return block.addUnOp(src, bool_type, .not, operand);
5251 return block.addTyOp(.not, bool_type, operand);
52385252}
52395253
52405254fn zirBoolOp(
52415255 sema: *Sema,
52425256 block: *Scope.Block,
52435257 inst: Zir.Inst.Index,
5244 comptime is_bool_or: bool,
5258 is_bool_or: bool,
52455259) InnerError!Air.Inst.Ref {
52465260 const tracy = trace(@src());
52475261 defer tracy.end();
......@@ -5257,15 +5271,23 @@ fn zirBoolOp(
52575271 if (lhs.value()) |lhs_val| {
52585272 if (rhs.value()) |rhs_val| {
52595273 if (is_bool_or) {
5260 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() or rhs_val.toBool());
5274 if (lhs_val.toBool() or rhs_val.toBool()) {
5275 return Air.Inst.Ref.bool_true;
5276 } else {
5277 return Air.Inst.Ref.bool_false;
5278 }
52615279 } else {
5262 return sema.mod.constBool(sema.arena, src, lhs_val.toBool() and rhs_val.toBool());
5280 if (lhs_val.toBool() and rhs_val.toBool()) {
5281 return Air.Inst.Ref.bool_true;
5282 } else {
5283 return Air.Inst.Ref.bool_false;
5284 }
52635285 }
52645286 }
52655287 }
52665288 try sema.requireRuntimeBlock(block, src);
52675289 const tag: Air.Inst.Tag = if (is_bool_or) .bool_or else .bool_and;
5268 return block.addBinOp(src, bool_type, tag, lhs, rhs);
5290 return block.addBinOp(tag, lhs, rhs);
52695291}
52705292
52715293fn zirBoolBr(
......@@ -5286,7 +5308,11 @@ fn zirBoolBr(
52865308
52875309 if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| {
52885310 if (lhs_val.toBool() == is_bool_or) {
5289 return sema.mod.constBool(sema.arena, src, is_bool_or);
5311 if (is_bool_or) {
5312 return Air.Inst.Ref.bool_true;
5313 } else {
5314 return Air.Inst.Ref.bool_false;
5315 }
52905316 }
52915317 // comptime-known left-hand side. No need for a block here; the result
52925318 // is simply the rhs expression. Here we rely on there only being 1
......@@ -5522,14 +5548,11 @@ fn analyzeRet(
55225548 const fn_ty = func.owner_decl.ty;
55235549 const fn_ret_ty = fn_ty.fnReturnType();
55245550 const casted_operand = try sema.coerce(block, fn_ret_ty, operand, src);
5525 if (fn_ret_ty.zigTypeTag() == .Void)
5526 _ = try block.addNoOp(src, Type.initTag(.noreturn), .retvoid)
5527 else
5528 _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, casted_operand);
5551 _ = try block.addUnOp(.ret, casted_operand);
55295552 return always_noreturn;
55305553 }
55315554 }
5532 _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, operand);
5555 _ = try block.addUnOp(.ret, operand);
55335556 return always_noreturn;
55345557}
55355558
......@@ -5559,7 +5582,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inne
55595582 inst_data.is_volatile,
55605583 inst_data.size,
55615584 );
5562 return sema.mod.constType(sema.arena, .unneeded, ty);
5585 return sema.addType(ty);
55635586}
55645587
55655588fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -5613,7 +5636,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError
56135636 inst_data.flags.is_volatile,
56145637 inst_data.size,
56155638 );
5616 return sema.mod.constType(sema.arena, src, ty);
5639 return sema.addType(ty);
56175640}
56185641
56195642fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -5794,7 +5817,7 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr
57945817 const struct_obj = struct_ty.castTag(.@"struct").?.data;
57955818 const field = struct_obj.fields.get(field_name) orelse
57965819 return sema.failWithBadFieldAccess(block, struct_obj, src, field_name);
5797 return sema.mod.constType(sema.arena, src, field.ty);
5820 return sema.addType(field.ty);
57985821}
57995822
58005823fn zirErrorReturnTrace(
......@@ -5937,7 +5960,7 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
59375960 .val = Value.initTag(.zero),
59385961 });
59395962 if (!type_res.isAllowzeroPtr()) {
5940 const is_non_zero = try block.addBinOp(src, Type.initTag(.bool), .cmp_neq, operand_coerced, zero);
5963 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, zero);
59415964 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
59425965 }
59435966
......@@ -5951,12 +5974,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
59515974 .ty = Type.initTag(.u64),
59525975 .val = Value.initPayload(&val_payload.base),
59535976 });
5954 const remainder = try block.addBinOp(src, Type.initTag(.u64), .bit_and, operand_coerced, align_minus_1);
5955 const is_aligned = try block.addBinOp(src, Type.initTag(.bool), .cmp_eq, remainder, zero);
5977 const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1);
5978 const is_aligned = try block.addBinOp(.cmp_eq, remainder, zero);
59565979 try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment);
59575980 }
59585981 }
5959 return block.addUnOp(src, type_res, .bitcast, operand_coerced);
5982 return block.addTyOp(.bitcast, type_res, operand_coerced);
59605983}
59615984
59625985fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref {
......@@ -6841,7 +6864,7 @@ fn coerce(
68416864 return sema.coerceVarArgParam(block, inst, inst_src);
68426865 }
68436866
6844 const inst_ty = sema.getTypeOfAirRef(inst);
6867 const inst_ty = sema.getTypeOf(inst);
68456868 // If the types are the same, we can return the operand.
68466869 if (dest_type.eql(inst_ty))
68476870 return inst;
......@@ -6950,7 +6973,7 @@ fn coerce(
69506973 (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits))
69516974 {
69526975 try sema.requireRuntimeBlock(block, inst_src);
6953 return block.addUnOp(inst_src, dest_type, .intcast, inst);
6976 return block.addTyOp(.intcast, dest_type, inst);
69546977 }
69556978 }
69566979 },
......@@ -6963,7 +6986,7 @@ fn coerce(
69636986 const dst_bits = dest_type.floatBits(target);
69646987 if (dst_bits >= src_bits) {
69656988 try sema.requireRuntimeBlock(block, inst_src);
6966 return block.addUnOp(inst_src, dest_type, .floatcast, inst);
6989 return block.addTyOp(.floatcast, dest_type, inst);
69676990 }
69686991 }
69696992 },
......@@ -7062,7 +7085,7 @@ fn coerceVarArgParam(
70627085 inst: Air.Inst.Ref,
70637086 inst_src: LazySrcLoc,
70647087) !Air.Inst.Ref {
7065 const inst_ty = sema.getTypeOfAirRef(inst);
7088 const inst_ty = sema.getTypeOf(inst);
70667089 switch (inst_ty.zigTypeTag()) {
70677090 .ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}),
70687091 else => {},
......@@ -7121,7 +7144,7 @@ fn storePtr(
71217144 // TODO handle if the element type requires comptime
71227145
71237146 try sema.requireRuntimeBlock(block, src);
7124 _ = try block.addBinOp(src, Type.initTag(.void), .store, ptr, value);
7147 _ = try block.addBinOp(.store, ptr, value);
71257148}
71267149
71277150fn bitcast(
......@@ -7221,7 +7244,7 @@ fn analyzeRef(
72217244 }
72227245
72237246 try sema.requireRuntimeBlock(block, src);
7224 return block.addUnOp(src, ptr_type, .ref, operand);
7247 return block.addTyOp(.ref, ptr_type, operand);
72257248}
72267249
72277250fn analyzeLoad(
......@@ -7231,7 +7254,7 @@ fn analyzeLoad(
72317254 ptr: Air.Inst.Ref,
72327255 ptr_src: LazySrcLoc,
72337256) InnerError!Air.Inst.Ref {
7234 const ptr_ty = sema.getTypeOfAirRef(ptr);
7257 const ptr_ty = sema.getTypeOf(ptr);
72357258 const elem_ty = switch (ptr_ty.zigTypeTag()) {
72367259 .Pointer => ptr_ty.elemType(),
72377260 else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}),
......@@ -7257,15 +7280,19 @@ fn analyzeIsNull(
72577280 const result_ty = Type.initTag(.bool);
72587281 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |opt_val| {
72597282 if (opt_val.isUndef()) {
7260 return sema.mod.constUndef(sema.arena, src, result_ty);
7283 return sema.addConstUndef(result_ty);
72617284 }
72627285 const is_null = opt_val.isNull();
72637286 const bool_value = if (invert_logic) !is_null else is_null;
7264 return sema.mod.constBool(sema.arena, src, bool_value);
7287 if (bool_value) {
7288 return Air.Inst.Ref.bool_true;
7289 } else {
7290 return Air.Inst.Ref.bool_false;
7291 }
72657292 }
72667293 try sema.requireRuntimeBlock(block, src);
7267 const inst_tag: Inst.Tag = if (invert_logic) .is_non_null else .is_null;
7268 return block.addUnOp(src, result_ty, inst_tag, operand);
7294 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
7295 return block.addUnOp(air_tag, operand);
72697296}
72707297
72717298fn analyzeIsNonErr(
......@@ -7275,18 +7302,22 @@ fn analyzeIsNonErr(
72757302 operand: Air.Inst.Ref,
72767303) InnerError!Air.Inst.Ref {
72777304 const ot = operand.ty.zigTypeTag();
7278 if (ot != .ErrorSet and ot != .ErrorUnion) return sema.mod.constBool(sema.arena, src, true);
7279 if (ot == .ErrorSet) return sema.mod.constBool(sema.arena, src, false);
7305 if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true;
7306 if (ot == .ErrorSet) return Air.Inst.Ref.bool_false;
72807307 assert(ot == .ErrorUnion);
72817308 const result_ty = Type.initTag(.bool);
72827309 if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |err_union| {
72837310 if (err_union.isUndef()) {
7284 return sema.mod.constUndef(sema.arena, src, result_ty);
7311 return sema.addConstUndef(result_ty);
7312 }
7313 if (err_union.getError() == null) {
7314 return Air.Inst.Ref.bool_true;
7315 } else {
7316 return Air.Inst.Ref.bool_false;
72857317 }
7286 return sema.mod.constBool(sema.arena, src, err_union.getError() == null);
72877318 }
72887319 try sema.requireRuntimeBlock(block, src);
7289 return block.addUnOp(src, result_ty, .is_non_err, operand);
7320 return block.addUnOp(.is_non_err, operand);
72907321}
72917322
72927323fn analyzeSlice(
......@@ -7372,31 +7403,43 @@ fn cmpNumeric(
73727403 lhs: Air.Inst.Ref,
73737404 rhs: Air.Inst.Ref,
73747405 op: std.math.CompareOperator,
7406 lhs_src: LazySrcLoc,
7407 rhs_src: LazySrcLoc,
73757408) InnerError!Air.Inst.Ref {
7376 assert(lhs.ty.isNumeric());
7377 assert(rhs.ty.isNumeric());
7409 const lhs_ty = sema.getTypeOf(lhs);
7410 const rhs_ty = sema.getTypeOf(rhs);
7411
7412 assert(lhs_ty.isNumeric());
7413 assert(rhs_ty.isNumeric());
73787414
7379 const lhs_ty_tag = lhs.ty.zigTypeTag();
7380 const rhs_ty_tag = rhs.ty.zigTypeTag();
7415 const lhs_ty_tag = lhs_ty.zigTypeTag();
7416 const rhs_ty_tag = rhs_ty.zigTypeTag();
73817417
73827418 if (lhs_ty_tag == .Vector and rhs_ty_tag == .Vector) {
7383 if (lhs.ty.arrayLen() != rhs.ty.arrayLen()) {
7419 if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
73847420 return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
7385 lhs.ty.arrayLen(),
7386 rhs.ty.arrayLen(),
7421 lhs_ty.arrayLen(),
7422 rhs_ty.arrayLen(),
73877423 });
73887424 }
73897425 return sema.mod.fail(&block.base, src, "TODO implement support for vectors in cmpNumeric", .{});
73907426 } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) {
73917427 return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{
7392 lhs.ty,
7393 rhs.ty,
7428 lhs_ty,
7429 rhs_ty,
73947430 });
73957431 }
73967432
7397 if (lhs.value()) |lhs_val| {
7398 if (rhs.value()) |rhs_val| {
7399 return sema.mod.constBool(sema.arena, src, Value.compare(lhs_val, op, rhs_val));
7433 if (try sema.resolvePossiblyUndefinedValue(block, lhs_src, lhs)) |lhs_val| {
7434 if (try sema.resolvePossiblyUndefinedValue(block, rhs_src, rhs)) |rhs_val| {
7435 if (lhs_val.isUndef() or rhs_val.isUndef()) {
7436 return sema.addConstUndef(Type.initTag(.bool));
7437 }
7438 if (Value.compare(lhs_val, op, rhs_val)) {
7439 return Air.Inst.Ref.bool_true;
7440 } else {
7441 return Air.Inst.Ref.bool_false;
7442 }
74007443 }
74017444 }
74027445
......@@ -7422,19 +7465,19 @@ fn cmpNumeric(
74227465 // Implicit cast the smaller one to the larger one.
74237466 const dest_type = x: {
74247467 if (lhs_ty_tag == .ComptimeFloat) {
7425 break :x rhs.ty;
7468 break :x rhs_ty;
74267469 } else if (rhs_ty_tag == .ComptimeFloat) {
7427 break :x lhs.ty;
7470 break :x lhs_ty;
74287471 }
7429 if (lhs.ty.floatBits(target) >= rhs.ty.floatBits(target)) {
7430 break :x lhs.ty;
7472 if (lhs_ty.floatBits(target) >= rhs_ty.floatBits(target)) {
7473 break :x lhs_ty;
74317474 } else {
7432 break :x rhs.ty;
7475 break :x rhs_ty;
74337476 }
74347477 };
7435 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
7436 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
7437 return block.addBinOp(src, dest_type, Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
7478 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs_src);
7479 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs_src);
7480 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
74387481 }
74397482 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer.
74407483 // For mixed signed and unsigned integers, implicit cast both operands to a signed
......@@ -7445,11 +7488,11 @@ fn cmpNumeric(
74457488 const lhs_is_signed = if (lhs.value()) |lhs_val|
74467489 lhs_val.compareWithZero(.lt)
74477490 else
7448 (lhs.ty.isFloat() or lhs.ty.isSignedInt());
7491 (lhs_ty.isFloat() or lhs_ty.isSignedInt());
74497492 const rhs_is_signed = if (rhs.value()) |rhs_val|
74507493 rhs_val.compareWithZero(.lt)
74517494 else
7452 (rhs.ty.isFloat() or rhs.ty.isSignedInt());
7495 (rhs_ty.isFloat() or rhs_ty.isSignedInt());
74537496 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
74547497
74557498 var dest_float_type: ?Type = null;
......@@ -7457,7 +7500,7 @@ fn cmpNumeric(
74577500 var lhs_bits: usize = undefined;
74587501 if (lhs.value()) |lhs_val| {
74597502 if (lhs_val.isUndef())
7460 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
7503 return sema.addConstUndef(Type.initTag(.bool));
74617504 const is_unsigned = if (lhs_is_float) x: {
74627505 var bigint_space: Value.BigIntSpace = undefined;
74637506 var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
......@@ -7465,8 +7508,8 @@ fn cmpNumeric(
74657508 const zcmp = lhs_val.orderAgainstZero();
74667509 if (lhs_val.floatHasFraction()) {
74677510 switch (op) {
7468 .eq => return sema.mod.constBool(sema.arena, src, false),
7469 .neq => return sema.mod.constBool(sema.arena, src, true),
7511 .eq => return Air.Inst.Ref.bool_false,
7512 .neq => return Air.Inst.Ref.bool_true,
74707513 else => {},
74717514 }
74727515 if (zcmp == .lt) {
......@@ -7483,16 +7526,16 @@ fn cmpNumeric(
74837526 };
74847527 lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);
74857528 } else if (lhs_is_float) {
7486 dest_float_type = lhs.ty;
7529 dest_float_type = lhs_ty;
74877530 } else {
7488 const int_info = lhs.ty.intInfo(target);
7531 const int_info = lhs_ty.intInfo(target);
74897532 lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
74907533 }
74917534
74927535 var rhs_bits: usize = undefined;
74937536 if (rhs.value()) |rhs_val| {
74947537 if (rhs_val.isUndef())
7495 return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool));
7538 return sema.addConstUndef(Type.initTag(.bool));
74967539 const is_unsigned = if (rhs_is_float) x: {
74977540 var bigint_space: Value.BigIntSpace = undefined;
74987541 var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa);
......@@ -7500,8 +7543,8 @@ fn cmpNumeric(
75007543 const zcmp = rhs_val.orderAgainstZero();
75017544 if (rhs_val.floatHasFraction()) {
75027545 switch (op) {
7503 .eq => return sema.mod.constBool(sema.arena, src, false),
7504 .neq => return sema.mod.constBool(sema.arena, src, true),
7546 .eq => return Air.Inst.Ref.bool_false,
7547 .neq => return Air.Inst.Ref.bool_true,
75057548 else => {},
75067549 }
75077550 if (zcmp == .lt) {
......@@ -7518,9 +7561,9 @@ fn cmpNumeric(
75187561 };
75197562 rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed);
75207563 } else if (rhs_is_float) {
7521 dest_float_type = rhs.ty;
7564 dest_float_type = rhs_ty;
75227565 } else {
7523 const int_info = rhs.ty.intInfo(target);
7566 const int_info = rhs_ty.intInfo(target);
75247567 rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed);
75257568 }
75267569
......@@ -7532,10 +7575,10 @@ fn cmpNumeric(
75327575 const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
75337576 break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
75347577 };
7535 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
7536 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);
7578 const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs_src);
7579 const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs_src);
75377580
7538 return block.addBinOp(src, Type.initTag(.bool), Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
7581 return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs);
75397582}
75407583
75417584fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {
......@@ -7544,7 +7587,7 @@ fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Ins
75447587 }
75457588
75467589 try sema.requireRuntimeBlock(block, inst.src);
7547 return block.addUnOp(inst.src, dest_type, .wrap_optional, inst);
7590 return block.addTyOp(.wrap_optional, dest_type, inst);
75487591}
75497592
75507593fn wrapErrorUnion(
......@@ -7617,19 +7660,24 @@ fn wrapErrorUnion(
76177660 // we are coercing from E to E!T
76187661 if (inst.ty.zigTypeTag() == .ErrorSet) {
76197662 var coerced = try sema.coerce(block, err_union.data.error_set, inst, inst.src);
7620 return block.addUnOp(inst.src, dest_type, .wrap_errunion_err, coerced);
7663 return block.addTyOp(.wrap_errunion_err, dest_type, coerced);
76217664 } else {
76227665 var coerced = try sema.coerce(block, err_union.data.payload, inst, inst.src);
7623 return block.addUnOp(inst.src, dest_type, .wrap_errunion_payload, coerced);
7666 return block.addTyOp(.wrap_errunion_payload, dest_type, coerced);
76247667 }
76257668}
76267669
7627fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, instructions: []Air.Inst.Index) !Type {
7670fn resolvePeerTypes(
7671 sema: *Sema,
7672 block: *Scope.Block,
7673 src: LazySrcLoc,
7674 instructions: []Air.Inst.Ref,
7675) !Type {
76287676 if (instructions.len == 0)
76297677 return Type.initTag(.noreturn);
76307678
76317679 if (instructions.len == 1)
7632 return instructions[0].ty;
7680 return sema.getTypeOf(instructions[0]);
76337681
76347682 const target = sema.mod.getTarget();
76357683
......@@ -7989,7 +8037,7 @@ fn enumFieldSrcLoc(
79898037}
79908038
79918039/// Returns the type of the AIR instruction.
7992fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type {
8040fn getTypeOf(sema: *Sema, air_ref: Air.Inst.Ref) Type {
79938041 switch (air_ref) {
79948042 .none => unreachable,
79958043 .u8_type => return Type.initTag(.u8),
......@@ -8045,21 +8093,13 @@ fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type {
80458093 .fn_ccc_void_no_args_type => return Type.initTag(.fn_ccc_void_no_args),
80468094 .single_const_pointer_to_comptime_int_type => return Type.initTag(.single_const_pointer_to_comptime_int),
80478095 .const_slice_u8_type => return Type.initTag(.const_slice_u8),
8048 else => return sema.getAirType(air_ref),
8049 }
8050}
8051
8052/// Asserts the AIR instruction is a `const_ty` and returns the type.
8053fn getAirType(sema: *Sema, air_ref: Air.Inst.Ref) Type {
8054 var i: usize = @enumToInt(air_ref);
8055 if (i < Air.Inst.Ref.typed_value_map.len) {
8056 return Air.Inst.Ref.typed_value_map[i].val.toType(undefined) catch unreachable;
8096 else => {},
80578097 }
8058 i -= Air.Inst.Ref.typed_value_map.len;
8098 const air_index = @as(usize, @enumToInt(air_ref)) - Air.Inst.Ref.typed_value_map.len;
80598099 const air_tags = sema.air_instructions.items(.tag);
80608100 const air_datas = sema.air_instructions.items(.data);
8061 assert(air_tags[i] == .const_ty);
8062 return air_datas[i].ty;
8101 assert(air_tags[air_index] == .const_ty);
8102 return air_datas[air_index].ty;
80638103}
80648104
80658105pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
......@@ -8126,7 +8166,15 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
81268166 return indexToRef(@intCast(u32, sema.air_instructions.len - 1));
81278167}
81288168
8129pub fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref {
8169fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) InnerError!Air.Inst.Ref {
8170 return sema.addConstant(ty, try Value.Tag.int_u64.create(sema.arena, int));
8171}
8172
8173fn addConstUndef(sema: *Sema, ty: Type) InnerError!Air.Inst.Ref {
8174 return sema.addConstant(ty, Value.initTag(.undef));
8175}
8176
8177fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref {
81308178 const gpa = sema.gpa;
81318179 const ty_inst = try sema.addType(ty);
81328180 try sema.air_values.append(gpa, val);