| ... | ... | @@ -534,7 +534,7 @@ pub fn analyzeBody( |
| 534 | 534 | //}, |
| 535 | 535 | else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"), |
| 536 | 536 | }; |
| 537 | | if (sema.getAirType(air_inst).isNoReturn()) |
| 537 | if (sema.getTypeOf(air_inst).isNoReturn()) |
| 538 | 538 | return always_noreturn; |
| 539 | 539 | try map.put(sema.gpa, inst, air_inst); |
| 540 | 540 | i += 1; |
| ... | ... | @@ -664,7 +664,7 @@ fn resolvePossiblyUndefinedValue( |
| 664 | 664 | src: LazySrcLoc, |
| 665 | 665 | air_ref: Air.Inst.Ref, |
| 666 | 666 | ) !?Value { |
| 667 | | const ty = sema.getTypeOfAirRef(air_ref); |
| 667 | const ty = sema.getTypeOf(air_ref); |
| 668 | 668 | if (try sema.typeHasOnePossibleValue(block, src, ty)) |opv| { |
| 669 | 669 | return opv; |
| 670 | 670 | } |
| ... | ... | @@ -737,7 +737,7 @@ pub fn resolveInstConst( |
| 737 | 737 | const air_ref = sema.resolveInst(zir_ref); |
| 738 | 738 | const val = try sema.resolveConstValue(block, src, air_ref); |
| 739 | 739 | return TypedValue{ |
| 740 | | .ty = sema.getTypeOfAirRef(air_ref), |
| 740 | .ty = sema.getTypeOf(air_ref), |
| 741 | 741 | .val = val, |
| 742 | 742 | }; |
| 743 | 743 | } |
| ... | ... | @@ -1208,7 +1208,7 @@ fn zirRetType( |
| 1208 | 1208 | try sema.requireFunctionBlock(block, src); |
| 1209 | 1209 | const fn_ty = sema.func.?.owner_decl.ty; |
| 1210 | 1210 | const ret_type = fn_ty.fnReturnType(); |
| 1211 | | return sema.mod.constType(sema.arena, src, ret_type); |
| 1211 | return sema.addType(ret_type); |
| 1212 | 1212 | } |
| 1213 | 1213 | |
| 1214 | 1214 | fn 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 |
| 1571 | 1571 | // if expressions should force it when the condition is compile-time known. |
| 1572 | 1572 | const src: LazySrcLoc = .unneeded; |
| 1573 | 1573 | 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); |
| 1575 | 1575 | return sema.storePtr(block, src, bitcasted_ptr, value); |
| 1576 | 1576 | } |
| 1577 | 1577 | |
| ... | ... | @@ -1590,7 +1590,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) |
| 1590 | 1590 | // Create a runtime bitcast instruction with exactly the type the pointer wants. |
| 1591 | 1591 | const ptr_ty = try Module.simplePtrType(sema.arena, value.ty, true, .One); |
| 1592 | 1592 | 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); |
| 1594 | 1594 | return sema.storePtr(block, src, bitcasted_ptr, value); |
| 1595 | 1595 | } |
| 1596 | 1596 | |
| ... | ... | @@ -1646,7 +1646,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr |
| 1646 | 1646 | const param_count = fn_ty.fnParamLen(); |
| 1647 | 1647 | if (param_index >= param_count) { |
| 1648 | 1648 | 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)); |
| 1650 | 1650 | } |
| 1651 | 1651 | return sema.mod.fail(&block.base, src, "arg index {d} out of bounds; '{}' has {d} argument(s)", .{ |
| 1652 | 1652 | param_index, |
| ... | ... | @@ -1657,7 +1657,7 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr |
| 1657 | 1657 | |
| 1658 | 1658 | // TODO support generic functions |
| 1659 | 1659 | const param_type = fn_ty.fnParamType(param_index); |
| 1660 | | return sema.mod.constType(sema.arena, src, param_type); |
| 1660 | return sema.addType(param_type); |
| 1661 | 1661 | } |
| 1662 | 1662 | |
| 1663 | 1663 | fn 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 |
| 1694 | 1694 | defer tracy.end(); |
| 1695 | 1695 | |
| 1696 | 1696 | 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); |
| 1698 | 1698 | } |
| 1699 | 1699 | |
| 1700 | 1700 | fn 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 |
| 2418 | 2418 | defer tracy.end(); |
| 2419 | 2419 | |
| 2420 | 2420 | const int_type = sema.code.instructions.items(.data)[inst].int_type; |
| 2421 | | const src = int_type.src(); |
| 2422 | 2421 | const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count); |
| 2423 | 2422 | |
| 2424 | | return sema.mod.constType(sema.arena, src, ty); |
| 2423 | return sema.addType(ty); |
| 2425 | 2424 | } |
| 2426 | 2425 | |
| 2427 | 2426 | fn 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 |
| 2433 | 2432 | const child_type = try sema.resolveType(block, src, inst_data.operand); |
| 2434 | 2433 | const opt_type = try sema.mod.optionalType(sema.arena, child_type); |
| 2435 | 2434 | |
| 2436 | | return sema.mod.constType(sema.arena, src, opt_type); |
| 2435 | return sema.addType(opt_type); |
| 2437 | 2436 | } |
| 2438 | 2437 | |
| 2439 | 2438 | fn 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 |
| 2441 | 2440 | const src = inst_data.src(); |
| 2442 | 2441 | const array_type = try sema.resolveType(block, src, inst_data.operand); |
| 2443 | 2442 | const elem_type = array_type.elemType(); |
| 2444 | | return sema.mod.constType(sema.arena, src, elem_type); |
| 2443 | return sema.addType(elem_type); |
| 2445 | 2444 | } |
| 2446 | 2445 | |
| 2447 | 2446 | fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| 2448 | 2447 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2449 | | const src = inst_data.src(); |
| 2450 | 2448 | const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 2451 | 2449 | const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 2452 | 2450 | 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 |
| 2456 | 2454 | .len = len, |
| 2457 | 2455 | .elem_type = elem_type, |
| 2458 | 2456 | }); |
| 2459 | | return sema.mod.constType(sema.arena, src, vector_type); |
| 2457 | return sema.addType(vector_type); |
| 2460 | 2458 | } |
| 2461 | 2459 | |
| 2462 | 2460 | fn 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 |
| 2469 | 2467 | const elem_type = try sema.resolveType(block, .unneeded, bin_inst.rhs); |
| 2470 | 2468 | const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), null, elem_type); |
| 2471 | 2469 | |
| 2472 | | return sema.mod.constType(sema.arena, .unneeded, array_ty); |
| 2470 | return sema.addType(array_ty); |
| 2473 | 2471 | } |
| 2474 | 2472 | |
| 2475 | 2473 | fn 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) |
| 2484 | 2482 | const elem_type = try sema.resolveType(block, .unneeded, extra.elem_type); |
| 2485 | 2483 | const array_ty = try sema.mod.arrayType(sema.arena, len.val.toUnsignedInt(), sentinel.val, elem_type); |
| 2486 | 2484 | |
| 2487 | | return sema.mod.constType(sema.arena, .unneeded, array_ty); |
| 2485 | return sema.addType(array_ty); |
| 2488 | 2486 | } |
| 2489 | 2487 | |
| 2490 | 2488 | fn 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 |
| 2492 | 2490 | defer tracy.end(); |
| 2493 | 2491 | |
| 2494 | 2492 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2495 | | const src = inst_data.src(); |
| 2496 | 2493 | const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node }; |
| 2497 | 2494 | const return_type = try sema.resolveType(block, operand_src, inst_data.operand); |
| 2498 | 2495 | const anyframe_type = try Type.Tag.anyframe_T.create(sema.arena, return_type); |
| 2499 | 2496 | |
| 2500 | | return sema.mod.constType(sema.arena, src, anyframe_type); |
| 2497 | return sema.addType(anyframe_type); |
| 2501 | 2498 | } |
| 2502 | 2499 | |
| 2503 | 2500 | fn 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 |
| 2506 | 2503 | |
| 2507 | 2504 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2508 | 2505 | 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 }; |
| 2510 | 2506 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 2511 | 2507 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 2512 | 2508 | 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 |
| 2518 | 2514 | }); |
| 2519 | 2515 | } |
| 2520 | 2516 | 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); |
| 2522 | 2518 | } |
| 2523 | 2519 | |
| 2524 | 2520 | fn 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 |
| 2553 | 2549 | |
| 2554 | 2550 | if (try sema.resolvePossiblyUndefinedValue(block, src, op_coerced)) |val| { |
| 2555 | 2551 | if (val.isUndef()) { |
| 2556 | | return sema.mod.constUndef(sema.arena, src, result_ty); |
| 2552 | return sema.addConstUndef(result_ty); |
| 2557 | 2553 | } |
| 2558 | 2554 | const payload = try sema.arena.create(Value.Payload.U64); |
| 2559 | 2555 | payload.* = .{ |
| ... | ... | @@ -2567,7 +2563,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr |
| 2567 | 2563 | } |
| 2568 | 2564 | |
| 2569 | 2565 | try sema.requireRuntimeBlock(block, src); |
| 2570 | | return block.addUnOp(src, result_ty, .bitcast, op_coerced); |
| 2566 | return block.addTyOp(.bitcast, result_ty, op_coerced); |
| 2571 | 2567 | } |
| 2572 | 2568 | |
| 2573 | 2569 | fn 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 |
| 2600 | 2596 | // const is_gt_max = @panic("TODO get max errors in compilation"); |
| 2601 | 2597 | // try sema.addSafetyCheck(block, is_gt_max, .invalid_error_code); |
| 2602 | 2598 | } |
| 2603 | | return block.addUnOp(src, Type.initTag(.anyerror), .bitcast, op); |
| 2599 | return block.addTyOp(.bitcast, Type.initTag(.anyerror), op); |
| 2604 | 2600 | } |
| 2605 | 2601 | |
| 2606 | 2602 | fn 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 |
| 2614 | 2610 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 2615 | 2611 | const lhs = sema.resolveInst(extra.lhs); |
| 2616 | 2612 | 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) { |
| 2618 | 2616 | const msg = msg: { |
| 2619 | 2617 | const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{}); |
| 2620 | 2618 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -2623,8 +2621,6 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inn |
| 2623 | 2621 | }; |
| 2624 | 2622 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| 2625 | 2623 | } |
| 2626 | | const rhs_ty = try sema.resolveAirAsType(block, rhs_src, rhs); |
| 2627 | | const lhs_ty = try sema.resolveAirAsType(block, lhs_src, lhs); |
| 2628 | 2624 | if (rhs_ty.zigTypeTag() != .ErrorSet) |
| 2629 | 2625 | return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty}); |
| 2630 | 2626 | if (lhs_ty.zigTypeTag() != .ErrorSet) |
| ... | ... | @@ -2786,7 +2782,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErr |
| 2786 | 2782 | } |
| 2787 | 2783 | |
| 2788 | 2784 | 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); |
| 2790 | 2786 | } |
| 2791 | 2787 | |
| 2792 | 2788 | fn 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 |
| 2841 | 2837 | } |
| 2842 | 2838 | |
| 2843 | 2839 | try sema.requireRuntimeBlock(block, src); |
| 2844 | | return block.addUnOp(src, dest_ty, .bitcast, operand); |
| 2840 | return block.addTyOp(.bitcast, dest_ty, operand); |
| 2845 | 2841 | } |
| 2846 | 2842 | |
| 2847 | 2843 | /// Pointer in, pointer out. |
| ... | ... | @@ -2881,10 +2877,10 @@ fn zirOptionalPayloadPtr( |
| 2881 | 2877 | |
| 2882 | 2878 | try sema.requireRuntimeBlock(block, src); |
| 2883 | 2879 | 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); |
| 2885 | 2881 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| 2886 | 2882 | } |
| 2887 | | return block.addUnOp(src, child_pointer, .optional_payload_ptr, optional_ptr); |
| 2883 | return block.addTyOp(.optional_payload_ptr, child_pointer, optional_ptr); |
| 2888 | 2884 | } |
| 2889 | 2885 | |
| 2890 | 2886 | /// Value in, value out. |
| ... | ... | @@ -2919,10 +2915,10 @@ fn zirOptionalPayload( |
| 2919 | 2915 | |
| 2920 | 2916 | try sema.requireRuntimeBlock(block, src); |
| 2921 | 2917 | 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); |
| 2923 | 2919 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| 2924 | 2920 | } |
| 2925 | | return block.addUnOp(src, child_type, .optional_payload, operand); |
| 2921 | return block.addTyOp(.optional_payload, child_type, operand); |
| 2926 | 2922 | } |
| 2927 | 2923 | |
| 2928 | 2924 | /// Value in, value out |
| ... | ... | @@ -2953,10 +2949,11 @@ fn zirErrUnionPayload( |
| 2953 | 2949 | } |
| 2954 | 2950 | try sema.requireRuntimeBlock(block, src); |
| 2955 | 2951 | 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); |
| 2957 | 2953 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 2958 | 2954 | } |
| 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); |
| 2960 | 2957 | } |
| 2961 | 2958 | |
| 2962 | 2959 | /// Pointer in, pointer out. |
| ... | ... | @@ -2997,10 +2994,10 @@ fn zirErrUnionPayloadPtr( |
| 2997 | 2994 | |
| 2998 | 2995 | try sema.requireRuntimeBlock(block, src); |
| 2999 | 2996 | 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); |
| 3001 | 2998 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 3002 | 2999 | } |
| 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); |
| 3004 | 3001 | } |
| 3005 | 3002 | |
| 3006 | 3003 | /// Value in, value out |
| ... | ... | @@ -3026,7 +3023,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner |
| 3026 | 3023 | } |
| 3027 | 3024 | |
| 3028 | 3025 | 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); |
| 3030 | 3027 | } |
| 3031 | 3028 | |
| 3032 | 3029 | /// Pointer in, value out |
| ... | ... | @@ -3055,7 +3052,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In |
| 3055 | 3052 | } |
| 3056 | 3053 | |
| 3057 | 3054 | 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); |
| 3059 | 3056 | } |
| 3060 | 3057 | |
| 3061 | 3058 | fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void { |
| ... | ... | @@ -3241,7 +3238,7 @@ fn funcCommon( |
| 3241 | 3238 | } |
| 3242 | 3239 | |
| 3243 | 3240 | if (body_inst == 0) { |
| 3244 | | return mod.constType(sema.arena, src, fn_ty); |
| 3241 | return sema.addType(fn_ty); |
| 3245 | 3242 | } |
| 3246 | 3243 | |
| 3247 | 3244 | const is_inline = fn_ty.fnCallingConvention() == .Inline; |
| ... | ... | @@ -3312,8 +3309,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 3312 | 3309 | // TODO handle known-pointer-address |
| 3313 | 3310 | const src = inst_data.src(); |
| 3314 | 3311 | 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); |
| 3317 | 3313 | } |
| 3318 | 3314 | |
| 3319 | 3315 | fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -4244,15 +4240,14 @@ fn analyzeSwitch( |
| 4244 | 4240 | case_block.instructions.shrinkRetainingCapacity(0); |
| 4245 | 4241 | |
| 4246 | 4242 | var any_ok: ?Air.Inst.Index = null; |
| 4247 | | const bool_ty = comptime Type.initTag(.bool); |
| 4248 | 4243 | |
| 4249 | 4244 | for (items) |item_ref| { |
| 4250 | 4245 | const item = sema.resolveInst(item_ref); |
| 4251 | 4246 | _ = try sema.resolveConstValue(&child_block, item.src, item); |
| 4252 | 4247 | |
| 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); |
| 4254 | 4249 | 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); |
| 4256 | 4251 | } else { |
| 4257 | 4252 | any_ok = cmp_ok; |
| 4258 | 4253 | } |
| ... | ... | @@ -4271,32 +4266,24 @@ fn analyzeSwitch( |
| 4271 | 4266 | _ = try sema.resolveConstValue(&child_block, item_first.src, item_first); |
| 4272 | 4267 | _ = try sema.resolveConstValue(&child_block, item_last.src, item_last); |
| 4273 | 4268 | |
| 4274 | | const range_src = item_first.src; |
| 4275 | | |
| 4276 | 4269 | // operand >= first and operand <= last |
| 4277 | 4270 | const range_first_ok = try case_block.addBinOp( |
| 4278 | | item_first.src, |
| 4279 | | bool_ty, |
| 4280 | 4271 | .cmp_gte, |
| 4281 | 4272 | operand, |
| 4282 | 4273 | item_first, |
| 4283 | 4274 | ); |
| 4284 | 4275 | const range_last_ok = try case_block.addBinOp( |
| 4285 | | item_last.src, |
| 4286 | | bool_ty, |
| 4287 | 4276 | .cmp_lte, |
| 4288 | 4277 | operand, |
| 4289 | 4278 | item_last, |
| 4290 | 4279 | ); |
| 4291 | 4280 | const range_ok = try case_block.addBinOp( |
| 4292 | | range_src, |
| 4293 | | bool_ty, |
| 4294 | 4281 | .bool_and, |
| 4295 | 4282 | range_first_ok, |
| 4296 | 4283 | range_last_ok, |
| 4297 | 4284 | ); |
| 4298 | 4285 | 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); |
| 4300 | 4287 | } else { |
| 4301 | 4288 | any_ok = range_ok; |
| 4302 | 4289 | } |
| ... | ... | @@ -4555,13 +4542,11 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 4555 | 4542 | fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| 4556 | 4543 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 4557 | 4544 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 4558 | | const src = inst_data.src(); |
| 4559 | 4545 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 4560 | 4546 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 4561 | 4547 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); |
| 4562 | 4548 | const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs); |
| 4563 | 4549 | const mod = sema.mod; |
| 4564 | | const arena = sema.arena; |
| 4565 | 4550 | |
| 4566 | 4551 | const namespace = container_type.getNamespace() orelse return mod.fail( |
| 4567 | 4552 | &block.base, |
| ... | ... | @@ -4571,10 +4556,10 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError |
| 4571 | 4556 | ); |
| 4572 | 4557 | if (try sema.lookupInNamespace(namespace, decl_name)) |decl| { |
| 4573 | 4558 | 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; |
| 4575 | 4560 | } |
| 4576 | 4561 | } |
| 4577 | | return mod.constBool(arena, src, false); |
| 4562 | return Air.Inst.Ref.bool_false; |
| 4578 | 4563 | } |
| 4579 | 4564 | |
| 4580 | 4565 | fn 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! |
| 4599 | 4584 | try mod.semaFile(result.file); |
| 4600 | 4585 | const file_root_decl = result.file.root_decl.?; |
| 4601 | 4586 | 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); |
| 4603 | 4588 | } |
| 4604 | 4589 | |
| 4605 | 4590 | fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -4641,6 +4626,8 @@ fn zirBitwise( |
| 4641 | 4626 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 4642 | 4627 | const lhs = sema.resolveInst(extra.lhs); |
| 4643 | 4628 | const rhs = sema.resolveInst(extra.rhs); |
| 4629 | const lhs_ty = sema.getTypeOf(lhs); |
| 4630 | const rhs_ty = sema.getTypeOf(rhs); |
| 4644 | 4631 | |
| 4645 | 4632 | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; |
| 4646 | 4633 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| ... | ... | @@ -4654,38 +4641,38 @@ fn zirBitwise( |
| 4654 | 4641 | |
| 4655 | 4642 | const scalar_tag = scalar_type.zigTypeTag(); |
| 4656 | 4643 | |
| 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()) { |
| 4659 | 4646 | 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(), |
| 4662 | 4649 | }); |
| 4663 | 4650 | } |
| 4664 | 4651 | 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) { |
| 4666 | 4653 | 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, |
| 4669 | 4656 | }); |
| 4670 | 4657 | } |
| 4671 | 4658 | |
| 4672 | 4659 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 4673 | 4660 | |
| 4674 | 4661 | 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()) }); |
| 4676 | 4663 | } |
| 4677 | 4664 | |
| 4678 | 4665 | if (casted_lhs.value()) |lhs_val| { |
| 4679 | 4666 | if (casted_rhs.value()) |rhs_val| { |
| 4680 | 4667 | if (lhs_val.isUndef() or rhs_val.isUndef()) { |
| 4681 | | return sema.mod.constUndef(sema.arena, src, resolved_type); |
| 4668 | return sema.addConstUndef(resolved_type); |
| 4682 | 4669 | } |
| 4683 | 4670 | return sema.mod.fail(&block.base, src, "TODO implement comptime bitwise operations", .{}); |
| 4684 | 4671 | } |
| 4685 | 4672 | } |
| 4686 | 4673 | |
| 4687 | 4674 | 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); |
| 4689 | 4676 | } |
| 4690 | 4677 | |
| 4691 | 4678 | fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -4783,18 +4770,18 @@ fn analyzeArithmetic( |
| 4783 | 4770 | |
| 4784 | 4771 | const scalar_tag = scalar_type.zigTypeTag(); |
| 4785 | 4772 | |
| 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()) { |
| 4788 | 4775 | 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(), |
| 4791 | 4778 | }); |
| 4792 | 4779 | } |
| 4793 | 4780 | 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) { |
| 4795 | 4782 | 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, |
| 4798 | 4785 | }); |
| 4799 | 4786 | } |
| 4800 | 4787 | |
| ... | ... | @@ -4802,13 +4789,13 @@ fn analyzeArithmetic( |
| 4802 | 4789 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; |
| 4803 | 4790 | |
| 4804 | 4791 | 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()) }); |
| 4806 | 4793 | } |
| 4807 | 4794 | |
| 4808 | 4795 | if (casted_lhs.value()) |lhs_val| { |
| 4809 | 4796 | if (casted_rhs.value()) |rhs_val| { |
| 4810 | 4797 | if (lhs_val.isUndef() or rhs_val.isUndef()) { |
| 4811 | | return sema.mod.constUndef(sema.arena, src, resolved_type); |
| 4798 | return sema.addConstUndef(resolved_type); |
| 4812 | 4799 | } |
| 4813 | 4800 | // incase rhs is 0, simply return lhs without doing any calculations |
| 4814 | 4801 | // TODO Once division is implemented we should throw an error when dividing by 0. |
| ... | ... | @@ -4866,7 +4853,7 @@ fn analyzeArithmetic( |
| 4866 | 4853 | } |
| 4867 | 4854 | |
| 4868 | 4855 | try sema.requireRuntimeBlock(block, src); |
| 4869 | | const ir_tag: Inst.Tag = switch (zir_tag) { |
| 4856 | const air_tag: Air.Inst.Tag = switch (zir_tag) { |
| 4870 | 4857 | .add => .add, |
| 4871 | 4858 | .addwrap => .addwrap, |
| 4872 | 4859 | .sub => .sub, |
| ... | ... | @@ -4877,7 +4864,7 @@ fn analyzeArithmetic( |
| 4877 | 4864 | else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tag)}), |
| 4878 | 4865 | }; |
| 4879 | 4866 | |
| 4880 | | return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs); |
| 4867 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 4881 | 4868 | } |
| 4882 | 4869 | |
| 4883 | 4870 | fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -4997,11 +4984,17 @@ fn zirCmp( |
| 4997 | 4984 | .eq, .neq => true, |
| 4998 | 4985 | else => false, |
| 4999 | 4986 | }; |
| 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(); |
| 5002 | 4991 | if (is_equality_cmp and lhs_ty_tag == .Null and rhs_ty_tag == .Null) { |
| 5003 | 4992 | // 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 | } |
| 5005 | 4998 | } else if (is_equality_cmp and |
| 5006 | 4999 | ((lhs_ty_tag == .Null and rhs_ty_tag == .Optional) or |
| 5007 | 5000 | rhs_ty_tag == .Null and lhs_ty_tag == .Optional)) |
| ... | ... | @@ -5010,11 +5003,11 @@ fn zirCmp( |
| 5010 | 5003 | const opt_operand = if (lhs_ty_tag == .Optional) lhs else rhs; |
| 5011 | 5004 | return sema.analyzeIsNull(block, src, opt_operand, op == .neq); |
| 5012 | 5005 | } 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()))) |
| 5014 | 5007 | { |
| 5015 | 5008 | return mod.fail(&block.base, src, "TODO implement C pointer cmp", .{}); |
| 5016 | 5009 | } 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; |
| 5018 | 5011 | return mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type}); |
| 5019 | 5012 | } else if (is_equality_cmp and |
| 5020 | 5013 | ((lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) or |
| ... | ... | @@ -5025,27 +5018,45 @@ fn zirCmp( |
| 5025 | 5018 | if (!is_equality_cmp) { |
| 5026 | 5019 | return mod.fail(&block.base, src, "{s} operator not allowed for errors", .{@tagName(op)}); |
| 5027 | 5020 | } |
| 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 | } |
| 5032 | 5036 | } |
| 5033 | 5037 | } |
| 5034 | 5038 | 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()) { |
| 5037 | 5042 | // This operation allows any combination of integer and float types, regardless of the |
| 5038 | 5043 | // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for |
| 5039 | 5044 | // numeric types. |
| 5040 | | return sema.cmpNumeric(block, src, lhs, rhs, op); |
| 5045 | return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| 5041 | 5046 | } else if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) { |
| 5042 | 5047 | if (!is_equality_cmp) { |
| 5043 | 5048 | return mod.fail(&block.base, src, "{s} operator not allowed for types", .{@tagName(op)}); |
| 5044 | 5049 | } |
| 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 | } |
| 5046 | 5057 | } |
| 5047 | 5058 | |
| 5048 | | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; |
| 5059 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 5049 | 5060 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 5050 | 5061 | if (!resolved_type.isSelfComparable(is_equality_cmp)) { |
| 5051 | 5062 | return mod.fail(&block.base, src, "operator not allowed for type '{}'", .{resolved_type}); |
| ... | ... | @@ -5057,15 +5068,18 @@ fn zirCmp( |
| 5057 | 5068 | if (casted_lhs.value()) |lhs_val| { |
| 5058 | 5069 | if (casted_rhs.value()) |rhs_val| { |
| 5059 | 5070 | 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; |
| 5061 | 5077 | } |
| 5062 | | const result = lhs_val.compare(op, rhs_val); |
| 5063 | | return sema.mod.constBool(sema.arena, src, result); |
| 5064 | 5078 | } |
| 5065 | 5079 | } |
| 5066 | 5080 | |
| 5067 | 5081 | try sema.requireRuntimeBlock(block, src); |
| 5068 | | const tag: Inst.Tag = switch (op) { |
| 5082 | const tag: Air.Inst.Tag = switch (op) { |
| 5069 | 5083 | .lt => .cmp_lt, |
| 5070 | 5084 | .lte => .cmp_lte, |
| 5071 | 5085 | .eq => .cmp_eq, |
| ... | ... | @@ -5073,28 +5087,26 @@ fn zirCmp( |
| 5073 | 5087 | .gt => .cmp_gt, |
| 5074 | 5088 | .neq => .cmp_neq, |
| 5075 | 5089 | }; |
| 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); |
| 5078 | 5092 | } |
| 5079 | 5093 | |
| 5080 | 5094 | fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| 5081 | 5095 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5082 | | const src = inst_data.src(); |
| 5083 | 5096 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 5084 | 5097 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 5085 | 5098 | const target = sema.mod.getTarget(); |
| 5086 | 5099 | 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); |
| 5088 | 5101 | } |
| 5089 | 5102 | |
| 5090 | 5103 | fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| 5091 | 5104 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5092 | | const src = inst_data.src(); |
| 5093 | 5105 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 5094 | 5106 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 5095 | 5107 | const target = sema.mod.getTarget(); |
| 5096 | 5108 | 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); |
| 5098 | 5110 | } |
| 5099 | 5111 | |
| 5100 | 5112 | fn zirThis( |
| ... | ... | @@ -5171,18 +5183,16 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! |
| 5171 | 5183 | _ = block; |
| 5172 | 5184 | const zir_datas = sema.code.instructions.items(.data); |
| 5173 | 5185 | const inst_data = zir_datas[inst].un_node; |
| 5174 | | const src = inst_data.src(); |
| 5175 | 5186 | const operand = sema.resolveInst(inst_data.operand); |
| 5176 | | return sema.mod.constType(sema.arena, src, operand.ty); |
| 5187 | return sema.addType(operand.ty); |
| 5177 | 5188 | } |
| 5178 | 5189 | |
| 5179 | 5190 | fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| 5180 | 5191 | _ = block; |
| 5181 | 5192 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5182 | | const src = inst_data.src(); |
| 5183 | 5193 | const operand_ptr = sema.resolveInst(inst_data.operand); |
| 5184 | 5194 | const elem_ty = operand_ptr.ty.elemType(); |
| 5185 | | return sema.mod.constType(sema.arena, src, elem_ty); |
| 5195 | return sema.addType(elem_ty); |
| 5186 | 5196 | } |
| 5187 | 5197 | |
| 5188 | 5198 | fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -5217,7 +5227,7 @@ fn zirTypeofPeer( |
| 5217 | 5227 | } |
| 5218 | 5228 | |
| 5219 | 5229 | 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); |
| 5221 | 5231 | } |
| 5222 | 5232 | |
| 5223 | 5233 | fn 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 |
| 5231 | 5241 | const bool_type = Type.initTag(.bool); |
| 5232 | 5242 | const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src); |
| 5233 | 5243 | 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 | } |
| 5235 | 5249 | } |
| 5236 | 5250 | try sema.requireRuntimeBlock(block, src); |
| 5237 | | return block.addUnOp(src, bool_type, .not, operand); |
| 5251 | return block.addTyOp(.not, bool_type, operand); |
| 5238 | 5252 | } |
| 5239 | 5253 | |
| 5240 | 5254 | fn zirBoolOp( |
| 5241 | 5255 | sema: *Sema, |
| 5242 | 5256 | block: *Scope.Block, |
| 5243 | 5257 | inst: Zir.Inst.Index, |
| 5244 | | comptime is_bool_or: bool, |
| 5258 | is_bool_or: bool, |
| 5245 | 5259 | ) InnerError!Air.Inst.Ref { |
| 5246 | 5260 | const tracy = trace(@src()); |
| 5247 | 5261 | defer tracy.end(); |
| ... | ... | @@ -5257,15 +5271,23 @@ fn zirBoolOp( |
| 5257 | 5271 | if (lhs.value()) |lhs_val| { |
| 5258 | 5272 | if (rhs.value()) |rhs_val| { |
| 5259 | 5273 | 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 | } |
| 5261 | 5279 | } 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 | } |
| 5263 | 5285 | } |
| 5264 | 5286 | } |
| 5265 | 5287 | } |
| 5266 | 5288 | try sema.requireRuntimeBlock(block, src); |
| 5267 | 5289 | 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); |
| 5269 | 5291 | } |
| 5270 | 5292 | |
| 5271 | 5293 | fn zirBoolBr( |
| ... | ... | @@ -5286,7 +5308,11 @@ fn zirBoolBr( |
| 5286 | 5308 | |
| 5287 | 5309 | if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| { |
| 5288 | 5310 | 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 | } |
| 5290 | 5316 | } |
| 5291 | 5317 | // comptime-known left-hand side. No need for a block here; the result |
| 5292 | 5318 | // is simply the rhs expression. Here we rely on there only being 1 |
| ... | ... | @@ -5522,14 +5548,11 @@ fn analyzeRet( |
| 5522 | 5548 | const fn_ty = func.owner_decl.ty; |
| 5523 | 5549 | const fn_ret_ty = fn_ty.fnReturnType(); |
| 5524 | 5550 | 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); |
| 5529 | 5552 | return always_noreturn; |
| 5530 | 5553 | } |
| 5531 | 5554 | } |
| 5532 | | _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, operand); |
| 5555 | _ = try block.addUnOp(.ret, operand); |
| 5533 | 5556 | return always_noreturn; |
| 5534 | 5557 | } |
| 5535 | 5558 | |
| ... | ... | @@ -5559,7 +5582,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inne |
| 5559 | 5582 | inst_data.is_volatile, |
| 5560 | 5583 | inst_data.size, |
| 5561 | 5584 | ); |
| 5562 | | return sema.mod.constType(sema.arena, .unneeded, ty); |
| 5585 | return sema.addType(ty); |
| 5563 | 5586 | } |
| 5564 | 5587 | |
| 5565 | 5588 | fn 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 |
| 5613 | 5636 | inst_data.flags.is_volatile, |
| 5614 | 5637 | inst_data.size, |
| 5615 | 5638 | ); |
| 5616 | | return sema.mod.constType(sema.arena, src, ty); |
| 5639 | return sema.addType(ty); |
| 5617 | 5640 | } |
| 5618 | 5641 | |
| 5619 | 5642 | fn 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 |
| 5794 | 5817 | const struct_obj = struct_ty.castTag(.@"struct").?.data; |
| 5795 | 5818 | const field = struct_obj.fields.get(field_name) orelse |
| 5796 | 5819 | 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); |
| 5798 | 5821 | } |
| 5799 | 5822 | |
| 5800 | 5823 | fn zirErrorReturnTrace( |
| ... | ... | @@ -5937,7 +5960,7 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 5937 | 5960 | .val = Value.initTag(.zero), |
| 5938 | 5961 | }); |
| 5939 | 5962 | 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); |
| 5941 | 5964 | try sema.addSafetyCheck(block, is_non_zero, .cast_to_null); |
| 5942 | 5965 | } |
| 5943 | 5966 | |
| ... | ... | @@ -5951,12 +5974,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 5951 | 5974 | .ty = Type.initTag(.u64), |
| 5952 | 5975 | .val = Value.initPayload(&val_payload.base), |
| 5953 | 5976 | }); |
| 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); |
| 5956 | 5979 | try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); |
| 5957 | 5980 | } |
| 5958 | 5981 | } |
| 5959 | | return block.addUnOp(src, type_res, .bitcast, operand_coerced); |
| 5982 | return block.addTyOp(.bitcast, type_res, operand_coerced); |
| 5960 | 5983 | } |
| 5961 | 5984 | |
| 5962 | 5985 | fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air.Inst.Ref { |
| ... | ... | @@ -6841,7 +6864,7 @@ fn coerce( |
| 6841 | 6864 | return sema.coerceVarArgParam(block, inst, inst_src); |
| 6842 | 6865 | } |
| 6843 | 6866 | |
| 6844 | | const inst_ty = sema.getTypeOfAirRef(inst); |
| 6867 | const inst_ty = sema.getTypeOf(inst); |
| 6845 | 6868 | // If the types are the same, we can return the operand. |
| 6846 | 6869 | if (dest_type.eql(inst_ty)) |
| 6847 | 6870 | return inst; |
| ... | ... | @@ -6950,7 +6973,7 @@ fn coerce( |
| 6950 | 6973 | (src_info.signedness == .signed and dst_info.signedness == .unsigned and dst_info.bits > src_info.bits)) |
| 6951 | 6974 | { |
| 6952 | 6975 | try sema.requireRuntimeBlock(block, inst_src); |
| 6953 | | return block.addUnOp(inst_src, dest_type, .intcast, inst); |
| 6976 | return block.addTyOp(.intcast, dest_type, inst); |
| 6954 | 6977 | } |
| 6955 | 6978 | } |
| 6956 | 6979 | }, |
| ... | ... | @@ -6963,7 +6986,7 @@ fn coerce( |
| 6963 | 6986 | const dst_bits = dest_type.floatBits(target); |
| 6964 | 6987 | if (dst_bits >= src_bits) { |
| 6965 | 6988 | try sema.requireRuntimeBlock(block, inst_src); |
| 6966 | | return block.addUnOp(inst_src, dest_type, .floatcast, inst); |
| 6989 | return block.addTyOp(.floatcast, dest_type, inst); |
| 6967 | 6990 | } |
| 6968 | 6991 | } |
| 6969 | 6992 | }, |
| ... | ... | @@ -7062,7 +7085,7 @@ fn coerceVarArgParam( |
| 7062 | 7085 | inst: Air.Inst.Ref, |
| 7063 | 7086 | inst_src: LazySrcLoc, |
| 7064 | 7087 | ) !Air.Inst.Ref { |
| 7065 | | const inst_ty = sema.getTypeOfAirRef(inst); |
| 7088 | const inst_ty = sema.getTypeOf(inst); |
| 7066 | 7089 | switch (inst_ty.zigTypeTag()) { |
| 7067 | 7090 | .ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}), |
| 7068 | 7091 | else => {}, |
| ... | ... | @@ -7121,7 +7144,7 @@ fn storePtr( |
| 7121 | 7144 | // TODO handle if the element type requires comptime |
| 7122 | 7145 | |
| 7123 | 7146 | try sema.requireRuntimeBlock(block, src); |
| 7124 | | _ = try block.addBinOp(src, Type.initTag(.void), .store, ptr, value); |
| 7147 | _ = try block.addBinOp(.store, ptr, value); |
| 7125 | 7148 | } |
| 7126 | 7149 | |
| 7127 | 7150 | fn bitcast( |
| ... | ... | @@ -7221,7 +7244,7 @@ fn analyzeRef( |
| 7221 | 7244 | } |
| 7222 | 7245 | |
| 7223 | 7246 | try sema.requireRuntimeBlock(block, src); |
| 7224 | | return block.addUnOp(src, ptr_type, .ref, operand); |
| 7247 | return block.addTyOp(.ref, ptr_type, operand); |
| 7225 | 7248 | } |
| 7226 | 7249 | |
| 7227 | 7250 | fn analyzeLoad( |
| ... | ... | @@ -7231,7 +7254,7 @@ fn analyzeLoad( |
| 7231 | 7254 | ptr: Air.Inst.Ref, |
| 7232 | 7255 | ptr_src: LazySrcLoc, |
| 7233 | 7256 | ) InnerError!Air.Inst.Ref { |
| 7234 | | const ptr_ty = sema.getTypeOfAirRef(ptr); |
| 7257 | const ptr_ty = sema.getTypeOf(ptr); |
| 7235 | 7258 | const elem_ty = switch (ptr_ty.zigTypeTag()) { |
| 7236 | 7259 | .Pointer => ptr_ty.elemType(), |
| 7237 | 7260 | else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}), |
| ... | ... | @@ -7257,15 +7280,19 @@ fn analyzeIsNull( |
| 7257 | 7280 | const result_ty = Type.initTag(.bool); |
| 7258 | 7281 | if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |opt_val| { |
| 7259 | 7282 | if (opt_val.isUndef()) { |
| 7260 | | return sema.mod.constUndef(sema.arena, src, result_ty); |
| 7283 | return sema.addConstUndef(result_ty); |
| 7261 | 7284 | } |
| 7262 | 7285 | const is_null = opt_val.isNull(); |
| 7263 | 7286 | 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 | } |
| 7265 | 7292 | } |
| 7266 | 7293 | 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); |
| 7269 | 7296 | } |
| 7270 | 7297 | |
| 7271 | 7298 | fn analyzeIsNonErr( |
| ... | ... | @@ -7275,18 +7302,22 @@ fn analyzeIsNonErr( |
| 7275 | 7302 | operand: Air.Inst.Ref, |
| 7276 | 7303 | ) InnerError!Air.Inst.Ref { |
| 7277 | 7304 | 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; |
| 7280 | 7307 | assert(ot == .ErrorUnion); |
| 7281 | 7308 | const result_ty = Type.initTag(.bool); |
| 7282 | 7309 | if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |err_union| { |
| 7283 | 7310 | 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; |
| 7285 | 7317 | } |
| 7286 | | return sema.mod.constBool(sema.arena, src, err_union.getError() == null); |
| 7287 | 7318 | } |
| 7288 | 7319 | try sema.requireRuntimeBlock(block, src); |
| 7289 | | return block.addUnOp(src, result_ty, .is_non_err, operand); |
| 7320 | return block.addUnOp(.is_non_err, operand); |
| 7290 | 7321 | } |
| 7291 | 7322 | |
| 7292 | 7323 | fn analyzeSlice( |
| ... | ... | @@ -7372,31 +7403,43 @@ fn cmpNumeric( |
| 7372 | 7403 | lhs: Air.Inst.Ref, |
| 7373 | 7404 | rhs: Air.Inst.Ref, |
| 7374 | 7405 | op: std.math.CompareOperator, |
| 7406 | lhs_src: LazySrcLoc, |
| 7407 | rhs_src: LazySrcLoc, |
| 7375 | 7408 | ) 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()); |
| 7378 | 7414 | |
| 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(); |
| 7381 | 7417 | |
| 7382 | 7418 | 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()) { |
| 7384 | 7420 | 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(), |
| 7387 | 7423 | }); |
| 7388 | 7424 | } |
| 7389 | 7425 | return sema.mod.fail(&block.base, src, "TODO implement support for vectors in cmpNumeric", .{}); |
| 7390 | 7426 | } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) { |
| 7391 | 7427 | 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, |
| 7394 | 7430 | }); |
| 7395 | 7431 | } |
| 7396 | 7432 | |
| 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 | } |
| 7400 | 7443 | } |
| 7401 | 7444 | } |
| 7402 | 7445 | |
| ... | ... | @@ -7422,19 +7465,19 @@ fn cmpNumeric( |
| 7422 | 7465 | // Implicit cast the smaller one to the larger one. |
| 7423 | 7466 | const dest_type = x: { |
| 7424 | 7467 | if (lhs_ty_tag == .ComptimeFloat) { |
| 7425 | | break :x rhs.ty; |
| 7468 | break :x rhs_ty; |
| 7426 | 7469 | } else if (rhs_ty_tag == .ComptimeFloat) { |
| 7427 | | break :x lhs.ty; |
| 7470 | break :x lhs_ty; |
| 7428 | 7471 | } |
| 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; |
| 7431 | 7474 | } else { |
| 7432 | | break :x rhs.ty; |
| 7475 | break :x rhs_ty; |
| 7433 | 7476 | } |
| 7434 | 7477 | }; |
| 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); |
| 7438 | 7481 | } |
| 7439 | 7482 | // For mixed unsigned integer sizes, implicit cast both operands to the larger integer. |
| 7440 | 7483 | // For mixed signed and unsigned integers, implicit cast both operands to a signed |
| ... | ... | @@ -7445,11 +7488,11 @@ fn cmpNumeric( |
| 7445 | 7488 | const lhs_is_signed = if (lhs.value()) |lhs_val| |
| 7446 | 7489 | lhs_val.compareWithZero(.lt) |
| 7447 | 7490 | else |
| 7448 | | (lhs.ty.isFloat() or lhs.ty.isSignedInt()); |
| 7491 | (lhs_ty.isFloat() or lhs_ty.isSignedInt()); |
| 7449 | 7492 | const rhs_is_signed = if (rhs.value()) |rhs_val| |
| 7450 | 7493 | rhs_val.compareWithZero(.lt) |
| 7451 | 7494 | else |
| 7452 | | (rhs.ty.isFloat() or rhs.ty.isSignedInt()); |
| 7495 | (rhs_ty.isFloat() or rhs_ty.isSignedInt()); |
| 7453 | 7496 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; |
| 7454 | 7497 | |
| 7455 | 7498 | var dest_float_type: ?Type = null; |
| ... | ... | @@ -7457,7 +7500,7 @@ fn cmpNumeric( |
| 7457 | 7500 | var lhs_bits: usize = undefined; |
| 7458 | 7501 | if (lhs.value()) |lhs_val| { |
| 7459 | 7502 | if (lhs_val.isUndef()) |
| 7460 | | return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool)); |
| 7503 | return sema.addConstUndef(Type.initTag(.bool)); |
| 7461 | 7504 | const is_unsigned = if (lhs_is_float) x: { |
| 7462 | 7505 | var bigint_space: Value.BigIntSpace = undefined; |
| 7463 | 7506 | var bigint = try lhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); |
| ... | ... | @@ -7465,8 +7508,8 @@ fn cmpNumeric( |
| 7465 | 7508 | const zcmp = lhs_val.orderAgainstZero(); |
| 7466 | 7509 | if (lhs_val.floatHasFraction()) { |
| 7467 | 7510 | 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, |
| 7470 | 7513 | else => {}, |
| 7471 | 7514 | } |
| 7472 | 7515 | if (zcmp == .lt) { |
| ... | ... | @@ -7483,16 +7526,16 @@ fn cmpNumeric( |
| 7483 | 7526 | }; |
| 7484 | 7527 | lhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); |
| 7485 | 7528 | } else if (lhs_is_float) { |
| 7486 | | dest_float_type = lhs.ty; |
| 7529 | dest_float_type = lhs_ty; |
| 7487 | 7530 | } else { |
| 7488 | | const int_info = lhs.ty.intInfo(target); |
| 7531 | const int_info = lhs_ty.intInfo(target); |
| 7489 | 7532 | lhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed); |
| 7490 | 7533 | } |
| 7491 | 7534 | |
| 7492 | 7535 | var rhs_bits: usize = undefined; |
| 7493 | 7536 | if (rhs.value()) |rhs_val| { |
| 7494 | 7537 | if (rhs_val.isUndef()) |
| 7495 | | return sema.mod.constUndef(sema.arena, src, Type.initTag(.bool)); |
| 7538 | return sema.addConstUndef(Type.initTag(.bool)); |
| 7496 | 7539 | const is_unsigned = if (rhs_is_float) x: { |
| 7497 | 7540 | var bigint_space: Value.BigIntSpace = undefined; |
| 7498 | 7541 | var bigint = try rhs_val.toBigInt(&bigint_space).toManaged(sema.gpa); |
| ... | ... | @@ -7500,8 +7543,8 @@ fn cmpNumeric( |
| 7500 | 7543 | const zcmp = rhs_val.orderAgainstZero(); |
| 7501 | 7544 | if (rhs_val.floatHasFraction()) { |
| 7502 | 7545 | 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, |
| 7505 | 7548 | else => {}, |
| 7506 | 7549 | } |
| 7507 | 7550 | if (zcmp == .lt) { |
| ... | ... | @@ -7518,9 +7561,9 @@ fn cmpNumeric( |
| 7518 | 7561 | }; |
| 7519 | 7562 | rhs_bits += @boolToInt(is_unsigned and dest_int_is_signed); |
| 7520 | 7563 | } else if (rhs_is_float) { |
| 7521 | | dest_float_type = rhs.ty; |
| 7564 | dest_float_type = rhs_ty; |
| 7522 | 7565 | } else { |
| 7523 | | const int_info = rhs.ty.intInfo(target); |
| 7566 | const int_info = rhs_ty.intInfo(target); |
| 7524 | 7567 | rhs_bits = int_info.bits + @boolToInt(int_info.signedness == .unsigned and dest_int_is_signed); |
| 7525 | 7568 | } |
| 7526 | 7569 | |
| ... | ... | @@ -7532,10 +7575,10 @@ fn cmpNumeric( |
| 7532 | 7575 | const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned; |
| 7533 | 7576 | break :blk try Module.makeIntType(sema.arena, signedness, casted_bits); |
| 7534 | 7577 | }; |
| 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); |
| 7537 | 7580 | |
| 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); |
| 7539 | 7582 | } |
| 7540 | 7583 | |
| 7541 | 7584 | fn 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 |
| 7544 | 7587 | } |
| 7545 | 7588 | |
| 7546 | 7589 | 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); |
| 7548 | 7591 | } |
| 7549 | 7592 | |
| 7550 | 7593 | fn wrapErrorUnion( |
| ... | ... | @@ -7617,19 +7660,24 @@ fn wrapErrorUnion( |
| 7617 | 7660 | // we are coercing from E to E!T |
| 7618 | 7661 | if (inst.ty.zigTypeTag() == .ErrorSet) { |
| 7619 | 7662 | 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); |
| 7621 | 7664 | } else { |
| 7622 | 7665 | 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); |
| 7624 | 7667 | } |
| 7625 | 7668 | } |
| 7626 | 7669 | |
| 7627 | | fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, instructions: []Air.Inst.Index) !Type { |
| 7670 | fn resolvePeerTypes( |
| 7671 | sema: *Sema, |
| 7672 | block: *Scope.Block, |
| 7673 | src: LazySrcLoc, |
| 7674 | instructions: []Air.Inst.Ref, |
| 7675 | ) !Type { |
| 7628 | 7676 | if (instructions.len == 0) |
| 7629 | 7677 | return Type.initTag(.noreturn); |
| 7630 | 7678 | |
| 7631 | 7679 | if (instructions.len == 1) |
| 7632 | | return instructions[0].ty; |
| 7680 | return sema.getTypeOf(instructions[0]); |
| 7633 | 7681 | |
| 7634 | 7682 | const target = sema.mod.getTarget(); |
| 7635 | 7683 | |
| ... | ... | @@ -7989,7 +8037,7 @@ fn enumFieldSrcLoc( |
| 7989 | 8037 | } |
| 7990 | 8038 | |
| 7991 | 8039 | /// Returns the type of the AIR instruction. |
| 7992 | | fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type { |
| 8040 | fn getTypeOf(sema: *Sema, air_ref: Air.Inst.Ref) Type { |
| 7993 | 8041 | switch (air_ref) { |
| 7994 | 8042 | .none => unreachable, |
| 7995 | 8043 | .u8_type => return Type.initTag(.u8), |
| ... | ... | @@ -8045,21 +8093,13 @@ fn getTypeOfAirRef(sema: *Sema, air_ref: Air.Inst.Ref) Type { |
| 8045 | 8093 | .fn_ccc_void_no_args_type => return Type.initTag(.fn_ccc_void_no_args), |
| 8046 | 8094 | .single_const_pointer_to_comptime_int_type => return Type.initTag(.single_const_pointer_to_comptime_int), |
| 8047 | 8095 | .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. |
| 8053 | | fn 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 => {}, |
| 8057 | 8097 | } |
| 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; |
| 8059 | 8099 | const air_tags = sema.air_instructions.items(.tag); |
| 8060 | 8100 | 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; |
| 8063 | 8103 | } |
| 8064 | 8104 | |
| 8065 | 8105 | pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref { |
| ... | ... | @@ -8126,7 +8166,15 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref { |
| 8126 | 8166 | return indexToRef(@intCast(u32, sema.air_instructions.len - 1)); |
| 8127 | 8167 | } |
| 8128 | 8168 | |
| 8129 | | pub fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref { |
| 8169 | fn 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 | |
| 8173 | fn addConstUndef(sema: *Sema, ty: Type) InnerError!Air.Inst.Ref { |
| 8174 | return sema.addConstant(ty, Value.initTag(.undef)); |
| 8175 | } |
| 8176 | |
| 8177 | fn addConstant(sema: *Sema, ty: Type, val: Value) InnerError!Air.Inst.Ref { |
| 8130 | 8178 | const gpa = sema.gpa; |
| 8131 | 8179 | const ty_inst = try sema.addType(ty); |
| 8132 | 8180 | try sema.air_values.append(gpa, val); |