| ... | @@ -1609,7 +1609,7 @@ fn analyzeBodyInner( | ... | @@ -1609,7 +1609,7 @@ fn analyzeBodyInner( |
| 1609 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); | 1609 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| 1610 | return err; | 1610 | return err; |
| 1611 | }; | 1611 | }; |
| 1612 | const inline_body = if (cond.val.toBool(mod)) then_body else else_body; | 1612 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1613 | | 1613 | |
| 1614 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1614 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1615 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1615 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| ... | @@ -1630,7 +1630,7 @@ fn analyzeBodyInner( | ... | @@ -1630,7 +1630,7 @@ fn analyzeBodyInner( |
| 1630 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); | 1630 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| 1631 | return err; | 1631 | return err; |
| 1632 | }; | 1632 | }; |
| 1633 | const inline_body = if (cond.val.toBool(mod)) then_body else else_body; | 1633 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1634 | | 1634 | |
| 1635 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1635 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1636 | const old_runtime_index = block.runtime_index; | 1636 | const old_runtime_index = block.runtime_index; |
| ... | @@ -1663,7 +1663,7 @@ fn analyzeBodyInner( | ... | @@ -1663,7 +1663,7 @@ fn analyzeBodyInner( |
| 1663 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); | 1663 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| 1664 | return err; | 1664 | return err; |
| 1665 | }; | 1665 | }; |
| 1666 | if (is_non_err_val.toBool(mod)) { | 1666 | if (is_non_err_val.toBool()) { |
| 1667 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); | 1667 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); |
| 1668 | } | 1668 | } |
| 1669 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1669 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| ... | @@ -1689,7 +1689,7 @@ fn analyzeBodyInner( | ... | @@ -1689,7 +1689,7 @@ fn analyzeBodyInner( |
| 1689 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); | 1689 | if (err == error.AnalysisFail and block.comptime_reason != null) try block.comptime_reason.?.explain(sema, sema.err); |
| 1690 | return err; | 1690 | return err; |
| 1691 | }; | 1691 | }; |
| 1692 | if (is_non_err_val.toBool(mod)) { | 1692 | if (is_non_err_val.toBool()) { |
| 1693 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); | 1693 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1694 | } | 1694 | } |
| 1695 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1695 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| ... | @@ -1778,12 +1778,11 @@ fn resolveConstBool( | ... | @@ -1778,12 +1778,11 @@ fn resolveConstBool( |
| 1778 | zir_ref: Zir.Inst.Ref, | 1778 | zir_ref: Zir.Inst.Ref, |
| 1779 | reason: []const u8, | 1779 | reason: []const u8, |
| 1780 | ) !bool { | 1780 | ) !bool { |
| 1781 | const mod = sema.mod; | | |
| 1782 | const air_inst = try sema.resolveInst(zir_ref); | 1781 | const air_inst = try sema.resolveInst(zir_ref); |
| 1783 | const wanted_type = Type.bool; | 1782 | const wanted_type = Type.bool; |
| 1784 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 1783 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1785 | const val = try sema.resolveConstValue(block, src, coerced_inst, reason); | 1784 | const val = try sema.resolveConstValue(block, src, coerced_inst, reason); |
| 1786 | return val.toBool(mod); | 1785 | return val.toBool(); |
| 1787 | } | 1786 | } |
| 1788 | | 1787 | |
| 1789 | pub fn resolveConstString( | 1788 | pub fn resolveConstString( |
| ... | @@ -2488,7 +2487,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2488,7 +2487,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2488 | defer anon_decl.deinit(); | 2487 | defer anon_decl.deinit(); |
| 2489 | const decl_index = try anon_decl.finish( | 2488 | const decl_index = try anon_decl.finish( |
| 2490 | pointee_ty, | 2489 | pointee_ty, |
| 2491 | Value.undef, | 2490 | (try mod.intern(.{ .undef = pointee_ty.toIntern() })).toValue(), |
| 2492 | alignment.toByteUnits(0), | 2491 | alignment.toByteUnits(0), |
| 2493 | ); | 2492 | ); |
| 2494 | sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index; | 2493 | sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index; |
| ... | @@ -2611,7 +2610,7 @@ fn coerceResultPtr( | ... | @@ -2611,7 +2610,7 @@ fn coerceResultPtr( |
| 2611 | .@"addrspace" = addr_space, | 2610 | .@"addrspace" = addr_space, |
| 2612 | }); | 2611 | }); |
| 2613 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { | 2612 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| 2614 | new_ptr = try sema.addConstant(ptr_operand_ty, ptr_val); | 2613 | new_ptr = try sema.addConstant(ptr_operand_ty, try mod.getCoerced(ptr_val, ptr_operand_ty)); |
| 2615 | } else { | 2614 | } else { |
| 2616 | new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src, null); | 2615 | new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src, null); |
| 2617 | } | 2616 | } |
| ... | @@ -3613,7 +3612,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai | ... | @@ -3613,7 +3612,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai |
| 3613 | | 3612 | |
| 3614 | // Detect if a comptime value simply needs to have its type changed. | 3613 | // Detect if a comptime value simply needs to have its type changed. |
| 3615 | if (try sema.resolveMaybeUndefVal(alloc)) |val| { | 3614 | if (try sema.resolveMaybeUndefVal(alloc)) |val| { |
| 3616 | return sema.addConstant(const_ptr_ty, val); | 3615 | return sema.addConstant(const_ptr_ty, try mod.getCoerced(val, const_ptr_ty)); |
| 3617 | } | 3616 | } |
| 3618 | | 3617 | |
| 3619 | return block.addBitCast(const_ptr_ty, alloc); | 3618 | return block.addBitCast(const_ptr_ty, alloc); |
| ... | @@ -3735,6 +3734,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3735,6 +3734,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3735 | try mod.declareDeclDependency(sema.owner_decl_index, decl_index); | 3734 | try mod.declareDeclDependency(sema.owner_decl_index, decl_index); |
| 3736 | | 3735 | |
| 3737 | const decl = mod.declPtr(decl_index); | 3736 | const decl = mod.declPtr(decl_index); |
| | 3737 | if (iac.is_const) try decl.intern(mod); |
| 3738 | const final_elem_ty = decl.ty; | 3738 | const final_elem_ty = decl.ty; |
| 3739 | const final_ptr_ty = try mod.ptrType(.{ | 3739 | const final_ptr_ty = try mod.ptrType(.{ |
| 3740 | .elem_type = final_elem_ty.toIntern(), | 3740 | .elem_type = final_elem_ty.toIntern(), |
| ... | @@ -3774,7 +3774,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3774,7 +3774,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3774 | // Detect if the value is comptime-known. In such case, the | 3774 | // Detect if the value is comptime-known. In such case, the |
| 3775 | // last 3 AIR instructions of the block will look like this: | 3775 | // last 3 AIR instructions of the block will look like this: |
| 3776 | // | 3776 | // |
| 3777 | // %a = interned | 3777 | // %a = inferred_alloc |
| 3778 | // %b = bitcast(%a) | 3778 | // %b = bitcast(%a) |
| 3779 | // %c = store(%b, %d) | 3779 | // %c = store(%b, %d) |
| 3780 | // | 3780 | // |
| ... | @@ -3814,22 +3814,22 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3814,22 +3814,22 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3814 | } | 3814 | } |
| 3815 | }; | 3815 | }; |
| 3816 | | 3816 | |
| 3817 | const const_inst = while (true) { | 3817 | while (true) { |
| 3818 | if (search_index == 0) break :ct; | 3818 | if (search_index == 0) break :ct; |
| 3819 | search_index -= 1; | 3819 | search_index -= 1; |
| 3820 | | 3820 | |
| 3821 | const candidate = block.instructions.items[search_index]; | 3821 | const candidate = block.instructions.items[search_index]; |
| | 3822 | if (candidate == ptr_inst) break; |
| 3822 | switch (air_tags[candidate]) { | 3823 | switch (air_tags[candidate]) { |
| 3823 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, | 3824 | .dbg_stmt, .dbg_block_begin, .dbg_block_end => continue, |
| 3824 | .interned => break candidate, | | |
| 3825 | else => break :ct, | 3825 | else => break :ct, |
| 3826 | } | 3826 | } |
| 3827 | }; | 3827 | } |
| 3828 | | 3828 | |
| 3829 | const store_op = air_datas[store_inst].bin_op; | 3829 | const store_op = air_datas[store_inst].bin_op; |
| 3830 | const store_val = (try sema.resolveMaybeUndefVal(store_op.rhs)) orelse break :ct; | 3830 | const store_val = (try sema.resolveMaybeUndefVal(store_op.rhs)) orelse break :ct; |
| 3831 | if (store_op.lhs != Air.indexToRef(bitcast_inst)) break :ct; | 3831 | if (store_op.lhs != Air.indexToRef(bitcast_inst)) break :ct; |
| 3832 | if (air_datas[bitcast_inst].ty_op.operand != Air.indexToRef(const_inst)) break :ct; | 3832 | if (air_datas[bitcast_inst].ty_op.operand != ptr) break :ct; |
| 3833 | | 3833 | |
| 3834 | const new_decl_index = d: { | 3834 | const new_decl_index = d: { |
| 3835 | var anon_decl = try block.startAnonDecl(); | 3835 | var anon_decl = try block.startAnonDecl(); |
| ... | @@ -3850,7 +3850,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3850,7 +3850,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3850 | sema.air_instructions.set(ptr_inst, .{ | 3850 | sema.air_instructions.set(ptr_inst, .{ |
| 3851 | .tag = .interned, | 3851 | .tag = .interned, |
| 3852 | .data = .{ .interned = try mod.intern(.{ .ptr = .{ | 3852 | .data = .{ .interned = try mod.intern(.{ .ptr = .{ |
| 3853 | .ty = final_elem_ty.toIntern(), | 3853 | .ty = final_ptr_ty.toIntern(), |
| 3854 | .addr = .{ .decl = new_decl_index }, | 3854 | .addr = .{ .decl = new_decl_index }, |
| 3855 | } }) }, | 3855 | } }) }, |
| 3856 | }); | 3856 | }); |
| ... | @@ -4707,15 +4707,23 @@ fn zirValidateArrayInit( | ... | @@ -4707,15 +4707,23 @@ fn zirValidateArrayInit( |
| 4707 | return; | 4707 | return; |
| 4708 | } | 4708 | } |
| 4709 | | 4709 | |
| | 4710 | // If the array has one possible value, the value is always comptime-known. |
| | 4711 | if (try sema.typeHasOnePossibleValue(array_ty)) |array_opv| { |
| | 4712 | const array_init = try sema.addConstant(array_ty, array_opv); |
| | 4713 | try sema.storePtr2(block, init_src, array_ptr, init_src, array_init, init_src, .store); |
| | 4714 | return; |
| | 4715 | } |
| | 4716 | |
| 4710 | var array_is_comptime = true; | 4717 | var array_is_comptime = true; |
| 4711 | var first_block_index = block.instructions.items.len; | 4718 | var first_block_index = block.instructions.items.len; |
| 4712 | var make_runtime = false; | 4719 | var make_runtime = false; |
| 4713 | | 4720 | |
| 4714 | // Collect the comptime element values in case the array literal ends up | 4721 | // Collect the comptime element values in case the array literal ends up |
| 4715 | // being comptime-known. | 4722 | // being comptime-known. |
| 4716 | const array_len_s = try sema.usizeCast(block, init_src, array_ty.arrayLenIncludingSentinel(mod)); | 4723 | const element_vals = try sema.arena.alloc( |
| 4717 | const element_vals = try sema.arena.alloc(InternPool.Index, array_len_s); | 4724 | InternPool.Index, |
| 4718 | const opt_opv = try sema.typeHasOnePossibleValue(array_ty); | 4725 | try sema.usizeCast(block, init_src, array_len), |
| | 4726 | ); |
| 4719 | const air_tags = sema.air_instructions.items(.tag); | 4727 | const air_tags = sema.air_instructions.items(.tag); |
| 4720 | const air_datas = sema.air_instructions.items(.data); | 4728 | const air_datas = sema.air_instructions.items(.data); |
| 4721 | | 4729 | |
| ... | @@ -4727,12 +4735,6 @@ fn zirValidateArrayInit( | ... | @@ -4727,12 +4735,6 @@ fn zirValidateArrayInit( |
| 4727 | element_vals[i] = opv.toIntern(); | 4735 | element_vals[i] = opv.toIntern(); |
| 4728 | continue; | 4736 | continue; |
| 4729 | } | 4737 | } |
| 4730 | } else { | | |
| 4731 | // Array has one possible value, so value is always comptime-known | | |
| 4732 | if (opt_opv) |opv| { | | |
| 4733 | element_vals[i] = opv.toIntern(); | | |
| 4734 | continue; | | |
| 4735 | } | | |
| 4736 | } | 4738 | } |
| 4737 | | 4739 | |
| 4738 | const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?; | 4740 | const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?; |
| ... | @@ -4814,11 +4816,6 @@ fn zirValidateArrayInit( | ... | @@ -4814,11 +4816,6 @@ fn zirValidateArrayInit( |
| 4814 | | 4816 | |
| 4815 | // Our task is to delete all the `elem_ptr` and `store` instructions, and insert | 4817 | // Our task is to delete all the `elem_ptr` and `store` instructions, and insert |
| 4816 | // instead a single `store` to the array_ptr with a comptime struct value. | 4818 | // instead a single `store` to the array_ptr with a comptime struct value. |
| 4817 | // Also to populate the sentinel value, if any. | | |
| 4818 | if (array_ty.sentinel(mod)) |sentinel_val| { | | |
| 4819 | element_vals[instrs.len] = sentinel_val.toIntern(); | | |
| 4820 | } | | |
| 4821 | | | |
| 4822 | block.instructions.shrinkRetainingCapacity(first_block_index); | 4819 | block.instructions.shrinkRetainingCapacity(first_block_index); |
| 4823 | | 4820 | |
| 4824 | var array_val = try mod.intern(.{ .aggregate = .{ | 4821 | var array_val = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -6259,7 +6256,7 @@ fn popErrorReturnTrace( | ... | @@ -6259,7 +6256,7 @@ fn popErrorReturnTrace( |
| 6259 | if (operand != .none) { | 6256 | if (operand != .none) { |
| 6260 | is_non_error_inst = try sema.analyzeIsNonErr(block, src, operand); | 6257 | is_non_error_inst = try sema.analyzeIsNonErr(block, src, operand); |
| 6261 | if (try sema.resolveDefinedValue(block, src, is_non_error_inst)) |cond_val| | 6258 | if (try sema.resolveDefinedValue(block, src, is_non_error_inst)) |cond_val| |
| 6262 | is_non_error = cond_val.toBool(mod); | 6259 | is_non_error = cond_val.toBool(); |
| 6263 | } else is_non_error = true; // no operand means pop unconditionally | 6260 | } else is_non_error = true; // no operand means pop unconditionally |
| 6264 | | 6261 | |
| 6265 | if (is_non_error == true) { | 6262 | if (is_non_error == true) { |
| ... | @@ -6873,14 +6870,15 @@ fn analyzeCall( | ... | @@ -6873,14 +6870,15 @@ fn analyzeCall( |
| 6873 | | 6870 | |
| 6874 | // If it's a comptime function call, we need to memoize it as long as no external | 6871 | // If it's a comptime function call, we need to memoize it as long as no external |
| 6875 | // comptime memory is mutated. | 6872 | // comptime memory is mutated. |
| 6876 | var memoized_call_key: Module.MemoizedCall.Key = undefined; | 6873 | var memoized_call_key = Module.MemoizedCall.Key{ |
| | 6874 | .func = module_fn_index, |
| | 6875 | .args_index = @intCast(u32, mod.memoized_call_args.items.len), |
| | 6876 | .args_count = @intCast(u32, func_ty_info.param_types.len), |
| | 6877 | }; |
| 6877 | var delete_memoized_call_key = false; | 6878 | var delete_memoized_call_key = false; |
| 6878 | defer if (delete_memoized_call_key) gpa.free(memoized_call_key.args); | 6879 | defer if (delete_memoized_call_key) mod.memoized_call_args.shrinkRetainingCapacity(memoized_call_key.args_index); |
| 6879 | if (is_comptime_call) { | 6880 | if (is_comptime_call) { |
| 6880 | memoized_call_key = .{ | 6881 | try mod.memoized_call_args.ensureUnusedCapacity(gpa, memoized_call_key.args_count); |
| 6881 | .func = module_fn_index, | | |
| 6882 | .args = try gpa.alloc(TypedValue, func_ty_info.param_types.len), | | |
| 6883 | }; | | |
| 6884 | delete_memoized_call_key = true; | 6882 | delete_memoized_call_key = true; |
| 6885 | } | 6883 | } |
| 6886 | | 6884 | |
| ... | @@ -6916,8 +6914,7 @@ fn analyzeCall( | ... | @@ -6916,8 +6914,7 @@ fn analyzeCall( |
| 6916 | uncasted_args, | 6914 | uncasted_args, |
| 6917 | is_comptime_call, | 6915 | is_comptime_call, |
| 6918 | &should_memoize, | 6916 | &should_memoize, |
| 6919 | memoized_call_key, | 6917 | mod.typeToFunc(func_ty).?.param_types, |
| 6920 | func_ty_info.param_types, | | |
| 6921 | func, | 6918 | func, |
| 6922 | &has_comptime_args, | 6919 | &has_comptime_args, |
| 6923 | ) catch |err| switch (err) { | 6920 | ) catch |err| switch (err) { |
| ... | @@ -6934,8 +6931,7 @@ fn analyzeCall( | ... | @@ -6934,8 +6931,7 @@ fn analyzeCall( |
| 6934 | uncasted_args, | 6931 | uncasted_args, |
| 6935 | is_comptime_call, | 6932 | is_comptime_call, |
| 6936 | &should_memoize, | 6933 | &should_memoize, |
| 6937 | memoized_call_key, | 6934 | mod.typeToFunc(func_ty).?.param_types, |
| 6938 | func_ty_info.param_types, | | |
| 6939 | func, | 6935 | func, |
| 6940 | &has_comptime_args, | 6936 | &has_comptime_args, |
| 6941 | ); | 6937 | ); |
| ... | @@ -6988,9 +6984,19 @@ fn analyzeCall( | ... | @@ -6988,9 +6984,19 @@ fn analyzeCall( |
| 6988 | // bug generating invalid LLVM IR. | 6984 | // bug generating invalid LLVM IR. |
| 6989 | const res2: Air.Inst.Ref = res2: { | 6985 | const res2: Air.Inst.Ref = res2: { |
| 6990 | if (should_memoize and is_comptime_call) { | 6986 | if (should_memoize and is_comptime_call) { |
| 6991 | if (mod.memoized_calls.getContext(memoized_call_key, .{ .module = mod })) |result| { | 6987 | const gop = try mod.memoized_calls.getOrPutContext( |
| 6992 | break :res2 try sema.addConstant(fn_ret_ty, result.val); | 6988 | gpa, |
| | 6989 | memoized_call_key, |
| | 6990 | .{ .args = &mod.memoized_call_args }, |
| | 6991 | ); |
| | 6992 | if (gop.found_existing) { |
| | 6993 | // We need to use the original memoized error set instead of fn_ret_ty. |
| | 6994 | const result = gop.value_ptr.*; |
| | 6995 | assert(result != .none); // recursive memoization? |
| | 6996 | break :res2 try sema.addConstant(mod.intern_pool.typeOf(result).toType(), result.toValue()); |
| 6993 | } | 6997 | } |
| | 6998 | gop.value_ptr.* = .none; |
| | 6999 | delete_memoized_call_key = false; |
| 6994 | } | 7000 | } |
| 6995 | | 7001 | |
| 6996 | const new_func_resolved_ty = try mod.funcType(new_fn_info); | 7002 | const new_func_resolved_ty = try mod.funcType(new_fn_info); |
| ... | @@ -7049,26 +7055,10 @@ fn analyzeCall( | ... | @@ -7049,26 +7055,10 @@ fn analyzeCall( |
| 7049 | | 7055 | |
| 7050 | if (should_memoize and is_comptime_call) { | 7056 | if (should_memoize and is_comptime_call) { |
| 7051 | const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, ""); | 7057 | const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, ""); |
| 7052 | | 7058 | mod.memoized_calls.getPtrContext( |
| 7053 | // TODO: check whether any external comptime memory was mutated by the | 7059 | memoized_call_key, |
| 7054 | // comptime function call. If so, then do not memoize the call here. | 7060 | .{ .args = &mod.memoized_call_args }, |
| 7055 | // TODO: re-evaluate whether memoized_calls needs its own arena. I think | 7061 | ).?.* = try result_val.intern(fn_ret_ty, mod); |
| 7056 | // it should be fine to use the Decl arena for the function. | | |
| 7057 | { | | |
| 7058 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); | | |
| 7059 | errdefer arena_allocator.deinit(); | | |
| 7060 | const arena = arena_allocator.allocator(); | | |
| 7061 | | | |
| 7062 | for (memoized_call_key.args) |*arg| { | | |
| 7063 | arg.* = try arg.*.copy(arena); | | |
| 7064 | } | | |
| 7065 | | | |
| 7066 | try mod.memoized_calls.putContext(gpa, memoized_call_key, .{ | | |
| 7067 | .val = try result_val.copy(arena), | | |
| 7068 | .arena = arena_allocator.state, | | |
| 7069 | }, .{ .module = mod }); | | |
| 7070 | delete_memoized_call_key = false; | | |
| 7071 | } | | |
| 7072 | } | 7062 | } |
| 7073 | | 7063 | |
| 7074 | break :res2 result; | 7064 | break :res2 result; |
| ... | @@ -7214,11 +7204,11 @@ fn analyzeInlineCallArg( | ... | @@ -7214,11 +7204,11 @@ fn analyzeInlineCallArg( |
| 7214 | uncasted_args: []const Air.Inst.Ref, | 7204 | uncasted_args: []const Air.Inst.Ref, |
| 7215 | is_comptime_call: bool, | 7205 | is_comptime_call: bool, |
| 7216 | should_memoize: *bool, | 7206 | should_memoize: *bool, |
| 7217 | memoized_call_key: Module.MemoizedCall.Key, | | |
| 7218 | raw_param_types: []const InternPool.Index, | 7207 | raw_param_types: []const InternPool.Index, |
| 7219 | func_inst: Air.Inst.Ref, | 7208 | func_inst: Air.Inst.Ref, |
| 7220 | has_comptime_args: *bool, | 7209 | has_comptime_args: *bool, |
| 7221 | ) !void { | 7210 | ) !void { |
| | 7211 | const mod = sema.mod; |
| 7222 | const zir_tags = sema.code.instructions.items(.tag); | 7212 | const zir_tags = sema.code.instructions.items(.tag); |
| 7223 | switch (zir_tags[inst]) { | 7213 | switch (zir_tags[inst]) { |
| 7224 | .param_comptime, .param_anytype_comptime => has_comptime_args.* = true, | 7214 | .param_comptime, .param_anytype_comptime => has_comptime_args.* = true, |
| ... | @@ -7276,11 +7266,8 @@ fn analyzeInlineCallArg( | ... | @@ -7276,11 +7266,8 @@ fn analyzeInlineCallArg( |
| 7276 | try sema.resolveLazyValue(arg_val); | 7266 | try sema.resolveLazyValue(arg_val); |
| 7277 | }, | 7267 | }, |
| 7278 | } | 7268 | } |
| 7279 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(sema.mod); | 7269 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(mod); |
| 7280 | memoized_call_key.args[arg_i.*] = .{ | 7270 | mod.memoized_call_args.appendAssumeCapacity(try arg_val.intern(param_ty.toType(), mod)); |
| 7281 | .ty = param_ty.toType(), | | |
| 7282 | .val = arg_val, | | |
| 7283 | }; | | |
| 7284 | } else { | 7271 | } else { |
| 7285 | sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg); | 7272 | sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| 7286 | } | 7273 | } |
| ... | @@ -7315,11 +7302,8 @@ fn analyzeInlineCallArg( | ... | @@ -7315,11 +7302,8 @@ fn analyzeInlineCallArg( |
| 7315 | try sema.resolveLazyValue(arg_val); | 7302 | try sema.resolveLazyValue(arg_val); |
| 7316 | }, | 7303 | }, |
| 7317 | } | 7304 | } |
| 7318 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(sema.mod); | 7305 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(mod); |
| 7319 | memoized_call_key.args[arg_i.*] = .{ | 7306 | mod.memoized_call_args.appendAssumeCapacity(try arg_val.intern(sema.typeOf(uncasted_arg), mod)); |
| 7320 | .ty = sema.typeOf(uncasted_arg), | | |
| 7321 | .val = arg_val, | | |
| 7322 | }; | | |
| 7323 | } else { | 7307 | } else { |
| 7324 | if (zir_tags[inst] == .param_anytype_comptime) { | 7308 | if (zir_tags[inst] == .param_anytype_comptime) { |
| 7325 | _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime"); | 7309 | _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime"); |
| ... | @@ -8279,7 +8263,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -8279,7 +8263,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 8279 | const int_tag_ty = try enum_tag_ty.intTagType(mod); | 8263 | const int_tag_ty = try enum_tag_ty.intTagType(mod); |
| 8280 | | 8264 | |
| 8281 | if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| { | 8265 | if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| { |
| 8282 | return sema.addConstant(int_tag_ty, opv); | 8266 | return sema.addConstant(int_tag_ty, try mod.getCoerced(opv, int_tag_ty)); |
| 8283 | } | 8267 | } |
| 8284 | | 8268 | |
| 8285 | if (try sema.resolveMaybeUndefVal(enum_tag)) |enum_tag_val| { | 8269 | if (try sema.resolveMaybeUndefVal(enum_tag)) |enum_tag_val| { |
| ... | @@ -8310,7 +8294,10 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -8310,7 +8294,10 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 8310 | if (dest_ty.isNonexhaustiveEnum(mod)) { | 8294 | if (dest_ty.isNonexhaustiveEnum(mod)) { |
| 8311 | const int_tag_ty = try dest_ty.intTagType(mod); | 8295 | const int_tag_ty = try dest_ty.intTagType(mod); |
| 8312 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { | 8296 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { |
| 8313 | return sema.addConstant(dest_ty, int_val); | 8297 | return sema.addConstant(dest_ty, (try mod.intern(.{ .enum_tag = .{ |
| | 8298 | .ty = dest_ty.toIntern(), |
| | 8299 | .int = int_val.toIntern(), |
| | 8300 | } })).toValue()); |
| 8314 | } | 8301 | } |
| 8315 | const msg = msg: { | 8302 | const msg = msg: { |
| 8316 | const msg = try sema.errMsg( | 8303 | const msg = try sema.errMsg( |
| ... | @@ -8657,8 +8644,10 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air | ... | @@ -8657,8 +8644,10 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air |
| 8657 | const result_ty = operand_ty.errorUnionSet(mod); | 8644 | const result_ty = operand_ty.errorUnionSet(mod); |
| 8658 | | 8645 | |
| 8659 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 8646 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 8660 | assert(val.getError(mod) != null); | 8647 | return sema.addConstant(result_ty, (try mod.intern(.{ .err = .{ |
| 8661 | return sema.addConstant(result_ty, val); | 8648 | .ty = result_ty.toIntern(), |
| | 8649 | .name = mod.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, |
| | 8650 | } })).toValue()); |
| 8662 | } | 8651 | } |
| 8663 | | 8652 | |
| 8664 | try sema.requireRuntimeBlock(block, src, null); | 8653 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -10737,7 +10726,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10737,7 +10726,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10737 | block, | 10726 | block, |
| 10738 | &range_set, | 10727 | &range_set, |
| 10739 | item_ref, | 10728 | item_ref, |
| 10740 | operand_ty, | | |
| 10741 | src_node_offset, | 10729 | src_node_offset, |
| 10742 | .{ .scalar = scalar_i }, | 10730 | .{ .scalar = scalar_i }, |
| 10743 | ); | 10731 | ); |
| ... | @@ -10760,7 +10748,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10760,7 +10748,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10760 | block, | 10748 | block, |
| 10761 | &range_set, | 10749 | &range_set, |
| 10762 | item_ref, | 10750 | item_ref, |
| 10763 | operand_ty, | | |
| 10764 | src_node_offset, | 10751 | src_node_offset, |
| 10765 | .{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }, | 10752 | .{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }, |
| 10766 | ); | 10753 | ); |
| ... | @@ -10778,7 +10765,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10778,7 +10765,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10778 | &range_set, | 10765 | &range_set, |
| 10779 | item_first, | 10766 | item_first, |
| 10780 | item_last, | 10767 | item_last, |
| 10781 | operand_ty, | | |
| 10782 | src_node_offset, | 10768 | src_node_offset, |
| 10783 | .{ .range = .{ .prong = multi_i, .item = range_i } }, | 10769 | .{ .range = .{ .prong = multi_i, .item = range_i } }, |
| 10784 | ); | 10770 | ); |
| ... | @@ -10792,7 +10778,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10792,7 +10778,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10792 | if (operand_ty.zigTypeTag(mod) == .Int) { | 10778 | if (operand_ty.zigTypeTag(mod) == .Int) { |
| 10793 | const min_int = try operand_ty.minInt(mod, operand_ty); | 10779 | const min_int = try operand_ty.minInt(mod, operand_ty); |
| 10794 | const max_int = try operand_ty.maxInt(mod, operand_ty); | 10780 | const max_int = try operand_ty.maxInt(mod, operand_ty); |
| 10795 | if (try range_set.spans(min_int, max_int, operand_ty)) { | 10781 | if (try range_set.spans(min_int.toIntern(), max_int.toIntern())) { |
| 10796 | if (special_prong == .@"else") { | 10782 | if (special_prong == .@"else") { |
| 10797 | return sema.fail( | 10783 | return sema.fail( |
| 10798 | block, | 10784 | block, |
| ... | @@ -10894,11 +10880,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10894,11 +10880,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10894 | ); | 10880 | ); |
| 10895 | } | 10881 | } |
| 10896 | | 10882 | |
| 10897 | var seen_values = ValueSrcMap.initContext(gpa, .{ | 10883 | var seen_values = ValueSrcMap{}; |
| 10898 | .ty = operand_ty, | 10884 | defer seen_values.deinit(gpa); |
| 10899 | .mod = mod, | | |
| 10900 | }); | | |
| 10901 | defer seen_values.deinit(); | | |
| 10902 | | 10885 | |
| 10903 | var extra_index: usize = special.end; | 10886 | var extra_index: usize = special.end; |
| 10904 | { | 10887 | { |
| ... | @@ -11664,10 +11647,10 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -11664,10 +11647,10 @@ const RangeSetUnhandledIterator = struct { |
| 11664 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); | 11647 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); |
| 11665 | } | 11648 | } |
| 11666 | it.first = false; | 11649 | it.first = false; |
| 11667 | if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) { | 11650 | if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first.toValue(), it.ty, it.sema.mod)) { |
| 11668 | return it.cur; | 11651 | return it.cur; |
| 11669 | } | 11652 | } |
| 11670 | it.cur = it.ranges[it.range_i].last; | 11653 | it.cur = it.ranges[it.range_i].last.toValue(); |
| 11671 | } | 11654 | } |
| 11672 | if (!it.first) { | 11655 | if (!it.first) { |
| 11673 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); | 11656 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); |
| ... | @@ -11687,16 +11670,15 @@ fn resolveSwitchItemVal( | ... | @@ -11687,16 +11670,15 @@ fn resolveSwitchItemVal( |
| 11687 | switch_node_offset: i32, | 11670 | switch_node_offset: i32, |
| 11688 | switch_prong_src: Module.SwitchProngSrc, | 11671 | switch_prong_src: Module.SwitchProngSrc, |
| 11689 | range_expand: Module.SwitchProngSrc.RangeExpand, | 11672 | range_expand: Module.SwitchProngSrc.RangeExpand, |
| 11690 | ) CompileError!TypedValue { | 11673 | ) CompileError!InternPool.Index { |
| 11691 | const mod = sema.mod; | 11674 | const mod = sema.mod; |
| 11692 | const item = try sema.resolveInst(item_ref); | 11675 | const item = try sema.resolveInst(item_ref); |
| 11693 | const item_ty = sema.typeOf(item); | | |
| 11694 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. | 11676 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. |
| 11695 | // Only if we know for sure we need to report a compile error do we resolve the | 11677 | // Only if we know for sure we need to report a compile error do we resolve the |
| 11696 | // full source locations. | 11678 | // full source locations. |
| 11697 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { | 11679 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { |
| 11698 | try sema.resolveLazyValue(val); | 11680 | try sema.resolveLazyValue(val); |
| 11699 | return TypedValue{ .ty = item_ty, .val = val }; | 11681 | return val.toIntern(); |
| 11700 | } else |err| switch (err) { | 11682 | } else |err| switch (err) { |
| 11701 | error.NeededSourceLocation => { | 11683 | error.NeededSourceLocation => { |
| 11702 | const src = switch_prong_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); | 11684 | const src = switch_prong_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); |
| ... | @@ -11713,18 +11695,17 @@ fn validateSwitchRange( | ... | @@ -11713,18 +11695,17 @@ fn validateSwitchRange( |
| 11713 | range_set: *RangeSet, | 11695 | range_set: *RangeSet, |
| 11714 | first_ref: Zir.Inst.Ref, | 11696 | first_ref: Zir.Inst.Ref, |
| 11715 | last_ref: Zir.Inst.Ref, | 11697 | last_ref: Zir.Inst.Ref, |
| 11716 | operand_ty: Type, | | |
| 11717 | src_node_offset: i32, | 11698 | src_node_offset: i32, |
| 11718 | switch_prong_src: Module.SwitchProngSrc, | 11699 | switch_prong_src: Module.SwitchProngSrc, |
| 11719 | ) CompileError!void { | 11700 | ) CompileError!void { |
| 11720 | const mod = sema.mod; | 11701 | const mod = sema.mod; |
| 11721 | const first_val = (try sema.resolveSwitchItemVal(block, first_ref, src_node_offset, switch_prong_src, .first)).val; | 11702 | const first = try sema.resolveSwitchItemVal(block, first_ref, src_node_offset, switch_prong_src, .first); |
| 11722 | const last_val = (try sema.resolveSwitchItemVal(block, last_ref, src_node_offset, switch_prong_src, .last)).val; | 11703 | const last = try sema.resolveSwitchItemVal(block, last_ref, src_node_offset, switch_prong_src, .last); |
| 11723 | if (first_val.compareScalar(.gt, last_val, operand_ty, mod)) { | 11704 | if (first.toValue().compareScalar(.gt, last.toValue(), mod.intern_pool.typeOf(first).toType(), mod)) { |
| 11724 | const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), src_node_offset, .first); | 11705 | const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), src_node_offset, .first); |
| 11725 | return sema.fail(block, src, "range start value is greater than the end value", .{}); | 11706 | return sema.fail(block, src, "range start value is greater than the end value", .{}); |
| 11726 | } | 11707 | } |
| 11727 | const maybe_prev_src = try range_set.add(first_val, last_val, operand_ty, switch_prong_src); | 11708 | const maybe_prev_src = try range_set.add(first, last, switch_prong_src); |
| 11728 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); | 11709 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); |
| 11729 | } | 11710 | } |
| 11730 | | 11711 | |
| ... | @@ -11733,12 +11714,11 @@ fn validateSwitchItem( | ... | @@ -11733,12 +11714,11 @@ fn validateSwitchItem( |
| 11733 | block: *Block, | 11714 | block: *Block, |
| 11734 | range_set: *RangeSet, | 11715 | range_set: *RangeSet, |
| 11735 | item_ref: Zir.Inst.Ref, | 11716 | item_ref: Zir.Inst.Ref, |
| 11736 | operand_ty: Type, | | |
| 11737 | src_node_offset: i32, | 11717 | src_node_offset: i32, |
| 11738 | switch_prong_src: Module.SwitchProngSrc, | 11718 | switch_prong_src: Module.SwitchProngSrc, |
| 11739 | ) CompileError!void { | 11719 | ) CompileError!void { |
| 11740 | const item_val = (try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none)).val; | 11720 | const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 11741 | const maybe_prev_src = try range_set.add(item_val, item_val, operand_ty, switch_prong_src); | 11721 | const maybe_prev_src = try range_set.add(item, item, switch_prong_src); |
| 11742 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); | 11722 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); |
| 11743 | } | 11723 | } |
| 11744 | | 11724 | |
| ... | @@ -11751,9 +11731,11 @@ fn validateSwitchItemEnum( | ... | @@ -11751,9 +11731,11 @@ fn validateSwitchItemEnum( |
| 11751 | src_node_offset: i32, | 11731 | src_node_offset: i32, |
| 11752 | switch_prong_src: Module.SwitchProngSrc, | 11732 | switch_prong_src: Module.SwitchProngSrc, |
| 11753 | ) CompileError!void { | 11733 | ) CompileError!void { |
| 11754 | const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); | 11734 | const ip = &sema.mod.intern_pool; |
| 11755 | const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse { | 11735 | const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 11756 | const maybe_prev_src = try range_set.add(item_tv.val, item_tv.val, item_tv.ty, switch_prong_src); | 11736 | const int = ip.indexToKey(item).enum_tag.int; |
| | 11737 | const field_index = ip.indexToKey(ip.typeOf(item)).enum_type.tagValueIndex(ip, int) orelse { |
| | 11738 | const maybe_prev_src = try range_set.add(int, int, switch_prong_src); |
| 11757 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); | 11739 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); |
| 11758 | }; | 11740 | }; |
| 11759 | const maybe_prev_src = seen_fields[field_index]; | 11741 | const maybe_prev_src = seen_fields[field_index]; |
| ... | @@ -11770,9 +11752,9 @@ fn validateSwitchItemError( | ... | @@ -11770,9 +11752,9 @@ fn validateSwitchItemError( |
| 11770 | switch_prong_src: Module.SwitchProngSrc, | 11752 | switch_prong_src: Module.SwitchProngSrc, |
| 11771 | ) CompileError!void { | 11753 | ) CompileError!void { |
| 11772 | const ip = &sema.mod.intern_pool; | 11754 | const ip = &sema.mod.intern_pool; |
| 11773 | const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); | 11755 | const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 11774 | // TODO: Do i need to typecheck here? | 11756 | // TODO: Do i need to typecheck here? |
| 11775 | const error_name = ip.stringToSlice(ip.indexToKey(item_tv.val.toIntern()).err.name); | 11757 | const error_name = ip.stringToSlice(ip.indexToKey(item).err.name); |
| 11776 | const maybe_prev_src = if (try seen_errors.fetchPut(error_name, switch_prong_src)) |prev| | 11758 | const maybe_prev_src = if (try seen_errors.fetchPut(error_name, switch_prong_src)) |prev| |
| 11777 | prev.value | 11759 | prev.value |
| 11778 | else | 11760 | else |
| ... | @@ -11822,8 +11804,8 @@ fn validateSwitchItemBool( | ... | @@ -11822,8 +11804,8 @@ fn validateSwitchItemBool( |
| 11822 | switch_prong_src: Module.SwitchProngSrc, | 11804 | switch_prong_src: Module.SwitchProngSrc, |
| 11823 | ) CompileError!void { | 11805 | ) CompileError!void { |
| 11824 | const mod = sema.mod; | 11806 | const mod = sema.mod; |
| 11825 | const item_val = (try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none)).val; | 11807 | const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 11826 | if (item_val.toBool(mod)) { | 11808 | if (item.toValue().toBool()) { |
| 11827 | true_count.* += 1; | 11809 | true_count.* += 1; |
| 11828 | } else { | 11810 | } else { |
| 11829 | false_count.* += 1; | 11811 | false_count.* += 1; |
| ... | @@ -11835,7 +11817,7 @@ fn validateSwitchItemBool( | ... | @@ -11835,7 +11817,7 @@ fn validateSwitchItemBool( |
| 11835 | } | 11817 | } |
| 11836 | } | 11818 | } |
| 11837 | | 11819 | |
| 11838 | const ValueSrcMap = std.HashMap(Value, Module.SwitchProngSrc, Value.HashContext, std.hash_map.default_max_load_percentage); | 11820 | const ValueSrcMap = std.AutoHashMapUnmanaged(InternPool.Index, Module.SwitchProngSrc); |
| 11839 | | 11821 | |
| 11840 | fn validateSwitchItemSparse( | 11822 | fn validateSwitchItemSparse( |
| 11841 | sema: *Sema, | 11823 | sema: *Sema, |
| ... | @@ -11845,8 +11827,8 @@ fn validateSwitchItemSparse( | ... | @@ -11845,8 +11827,8 @@ fn validateSwitchItemSparse( |
| 11845 | src_node_offset: i32, | 11827 | src_node_offset: i32, |
| 11846 | switch_prong_src: Module.SwitchProngSrc, | 11828 | switch_prong_src: Module.SwitchProngSrc, |
| 11847 | ) CompileError!void { | 11829 | ) CompileError!void { |
| 11848 | const item_val = (try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none)).val; | 11830 | const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 11849 | const kv = (try seen_values.fetchPut(item_val, switch_prong_src)) orelse return; | 11831 | const kv = (try seen_values.fetchPut(sema.gpa, item, switch_prong_src)) orelse return; |
| 11850 | return sema.validateSwitchDupe(block, kv.value, switch_prong_src, src_node_offset); | 11832 | return sema.validateSwitchDupe(block, kv.value, switch_prong_src, src_node_offset); |
| 11851 | } | 11833 | } |
| 11852 | | 11834 | |
| ... | @@ -13047,8 +13029,6 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13047,8 +13029,6 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13047 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); | 13029 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); |
| 13048 | | 13030 | |
| 13049 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { | 13031 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { |
| 13050 | const final_len_including_sent = result_len + @boolToInt(lhs_info.sentinel != null); | | |
| 13051 | | | |
| 13052 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) | 13032 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) |
| 13053 | (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? | 13033 | (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? |
| 13054 | else | 13034 | else |
| ... | @@ -13065,7 +13045,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13065,7 +13045,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13065 | } }); | 13045 | } }); |
| 13066 | } | 13046 | } |
| 13067 | | 13047 | |
| 13068 | const element_vals = try sema.arena.alloc(InternPool.Index, final_len_including_sent); | 13048 | const element_vals = try sema.arena.alloc(InternPool.Index, result_len); |
| 13069 | var elem_i: usize = 0; | 13049 | var elem_i: usize = 0; |
| 13070 | while (elem_i < result_len) { | 13050 | while (elem_i < result_len) { |
| 13071 | var lhs_i: usize = 0; | 13051 | var lhs_i: usize = 0; |
| ... | @@ -13075,9 +13055,6 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13075,9 +13055,6 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13075 | elem_i += 1; | 13055 | elem_i += 1; |
| 13076 | } | 13056 | } |
| 13077 | } | 13057 | } |
| 13078 | if (lhs_info.sentinel) |sent_val| { | | |
| 13079 | element_vals[result_len] = sent_val.toIntern(); | | |
| 13080 | } | | |
| 13081 | break :v try mod.intern(.{ .aggregate = .{ | 13058 | break :v try mod.intern(.{ .aggregate = .{ |
| 13082 | .ty = result_ty.toIntern(), | 13059 | .ty = result_ty.toIntern(), |
| 13083 | .storage = .{ .elems = element_vals }, | 13060 | .storage = .{ .elems = element_vals }, |
| ... | @@ -14896,13 +14873,18 @@ fn analyzeArithmetic( | ... | @@ -14896,13 +14873,18 @@ fn analyzeArithmetic( |
| 14896 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), | 14873 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| 14897 | else => unreachable, | 14874 | else => unreachable, |
| 14898 | }; | 14875 | }; |
| | 14876 | const scalar_one = switch (scalar_tag) { |
| | 14877 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0), |
| | 14878 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 1), |
| | 14879 | else => unreachable, |
| | 14880 | }; |
| 14899 | if (maybe_lhs_val) |lhs_val| { | 14881 | if (maybe_lhs_val) |lhs_val| { |
| 14900 | if (!lhs_val.isUndef(mod)) { | 14882 | if (!lhs_val.isUndef(mod)) { |
| 14901 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14883 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14902 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 14884 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14903 | return sema.addConstant(resolved_type, zero_val); | 14885 | return sema.addConstant(resolved_type, zero_val); |
| 14904 | } | 14886 | } |
| 14905 | if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { | 14887 | if (try sema.compareAll(lhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) { |
| 14906 | return casted_rhs; | 14888 | return casted_rhs; |
| 14907 | } | 14889 | } |
| 14908 | } | 14890 | } |
| ... | @@ -14916,7 +14898,7 @@ fn analyzeArithmetic( | ... | @@ -14916,7 +14898,7 @@ fn analyzeArithmetic( |
| 14916 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 14898 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14917 | return sema.addConstant(resolved_type, zero_val); | 14899 | return sema.addConstant(resolved_type, zero_val); |
| 14918 | } | 14900 | } |
| 14919 | if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { | 14901 | if (try sema.compareAll(rhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) { |
| 14920 | return casted_lhs; | 14902 | return casted_lhs; |
| 14921 | } | 14903 | } |
| 14922 | if (maybe_lhs_val) |lhs_val| { | 14904 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -15524,7 +15506,7 @@ fn cmpSelf( | ... | @@ -15524,7 +15506,7 @@ fn cmpSelf( |
| 15524 | } else { | 15506 | } else { |
| 15525 | if (resolved_type.zigTypeTag(mod) == .Bool) { | 15507 | if (resolved_type.zigTypeTag(mod) == .Bool) { |
| 15526 | // We can lower bool eq/neq more efficiently. | 15508 | // We can lower bool eq/neq more efficiently. |
| 15527 | return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(mod), rhs_src); | 15509 | return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src); |
| 15528 | } | 15510 | } |
| 15529 | break :src rhs_src; | 15511 | break :src rhs_src; |
| 15530 | } | 15512 | } |
| ... | @@ -15534,7 +15516,7 @@ fn cmpSelf( | ... | @@ -15534,7 +15516,7 @@ fn cmpSelf( |
| 15534 | if (resolved_type.zigTypeTag(mod) == .Bool) { | 15516 | if (resolved_type.zigTypeTag(mod) == .Bool) { |
| 15535 | if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| { | 15517 | if (try sema.resolveMaybeUndefVal(casted_rhs)) |rhs_val| { |
| 15536 | if (rhs_val.isUndef(mod)) return sema.addConstUndef(Type.bool); | 15518 | if (rhs_val.isUndef(mod)) return sema.addConstUndef(Type.bool); |
| 15537 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(mod), lhs_src); | 15519 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src); |
| 15538 | } | 15520 | } |
| 15539 | } | 15521 | } |
| 15540 | break :src lhs_src; | 15522 | break :src lhs_src; |
| ... | @@ -15840,6 +15822,7 @@ fn zirBuiltinSrc( | ... | @@ -15840,6 +15822,7 @@ fn zirBuiltinSrc( |
| 15840 | break :blk try mod.intern(.{ .ptr = .{ | 15822 | break :blk try mod.intern(.{ .ptr = .{ |
| 15841 | .ty = .slice_const_u8_sentinel_0_type, | 15823 | .ty = .slice_const_u8_sentinel_0_type, |
| 15842 | .addr = .{ .decl = new_decl }, | 15824 | .addr = .{ .decl = new_decl }, |
| | 15825 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 15843 | } }); | 15826 | } }); |
| 15844 | }; | 15827 | }; |
| 15845 | | 15828 | |
| ... | @@ -15864,6 +15847,7 @@ fn zirBuiltinSrc( | ... | @@ -15864,6 +15847,7 @@ fn zirBuiltinSrc( |
| 15864 | break :blk try mod.intern(.{ .ptr = .{ | 15847 | break :blk try mod.intern(.{ .ptr = .{ |
| 15865 | .ty = .slice_const_u8_sentinel_0_type, | 15848 | .ty = .slice_const_u8_sentinel_0_type, |
| 15866 | .addr = .{ .decl = new_decl }, | 15849 | .addr = .{ .decl = new_decl }, |
| | 15850 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 15867 | } }); | 15851 | } }); |
| 15868 | }; | 15852 | }; |
| 15869 | | 15853 | |
| ... | @@ -16314,6 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16314,6 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16314 | break :v try mod.intern(.{ .ptr = .{ | 16298 | break :v try mod.intern(.{ .ptr = .{ |
| 16315 | .ty = slice_errors_ty.toIntern(), | 16299 | .ty = slice_errors_ty.toIntern(), |
| 16316 | .addr = .{ .decl = new_decl }, | 16300 | .addr = .{ .decl = new_decl }, |
| | 16301 | .len = (try mod.intValue(Type.usize, vals.len)).toIntern(), |
| 16317 | } }); | 16302 | } }); |
| 16318 | } else .none; | 16303 | } else .none; |
| 16319 | const errors_val = try mod.intern(.{ .opt = .{ | 16304 | const errors_val = try mod.intern(.{ .opt = .{ |
| ... | @@ -16438,6 +16423,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16438,6 +16423,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16438 | .is_const = true, | 16423 | .is_const = true, |
| 16439 | })).toIntern(), | 16424 | })).toIntern(), |
| 16440 | .addr = .{ .decl = new_decl }, | 16425 | .addr = .{ .decl = new_decl }, |
| | 16426 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), |
| 16441 | } }); | 16427 | } }); |
| 16442 | }; | 16428 | }; |
| 16443 | | 16429 | |
| ... | @@ -17141,7 +17127,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17141,7 +17127,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17141 | if (try sema.resolveMaybeUndefVal(operand)) |val| { | 17127 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 17142 | return if (val.isUndef(mod)) | 17128 | return if (val.isUndef(mod)) |
| 17143 | sema.addConstUndef(Type.bool) | 17129 | sema.addConstUndef(Type.bool) |
| 17144 | else if (val.toBool(mod)) | 17130 | else if (val.toBool()) |
| 17145 | Air.Inst.Ref.bool_false | 17131 | Air.Inst.Ref.bool_false |
| 17146 | else | 17132 | else |
| 17147 | Air.Inst.Ref.bool_true; | 17133 | Air.Inst.Ref.bool_true; |
| ... | @@ -17169,9 +17155,9 @@ fn zirBoolBr( | ... | @@ -17169,9 +17155,9 @@ fn zirBoolBr( |
| 17169 | const gpa = sema.gpa; | 17155 | const gpa = sema.gpa; |
| 17170 | | 17156 | |
| 17171 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { | 17157 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { |
| 17172 | if (is_bool_or and lhs_val.toBool(mod)) { | 17158 | if (is_bool_or and lhs_val.toBool()) { |
| 17173 | return Air.Inst.Ref.bool_true; | 17159 | return Air.Inst.Ref.bool_true; |
| 17174 | } else if (!is_bool_or and !lhs_val.toBool(mod)) { | 17160 | } else if (!is_bool_or and !lhs_val.toBool()) { |
| 17175 | return Air.Inst.Ref.bool_false; | 17161 | return Air.Inst.Ref.bool_false; |
| 17176 | } | 17162 | } |
| 17177 | // comptime-known left-hand side. No need for a block here; the result | 17163 | // comptime-known left-hand side. No need for a block here; the result |
| ... | @@ -17215,9 +17201,9 @@ fn zirBoolBr( | ... | @@ -17215,9 +17201,9 @@ fn zirBoolBr( |
| 17215 | const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst); | 17201 | const result = sema.finishCondBr(parent_block, &child_block, &then_block, &else_block, lhs, block_inst); |
| 17216 | if (!sema.typeOf(rhs_result).isNoReturn(mod)) { | 17202 | if (!sema.typeOf(rhs_result).isNoReturn(mod)) { |
| 17217 | if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| { | 17203 | if (try sema.resolveDefinedValue(rhs_block, sema.src, rhs_result)) |rhs_val| { |
| 17218 | if (is_bool_or and rhs_val.toBool(mod)) { | 17204 | if (is_bool_or and rhs_val.toBool()) { |
| 17219 | return Air.Inst.Ref.bool_true; | 17205 | return Air.Inst.Ref.bool_true; |
| 17220 | } else if (!is_bool_or and !rhs_val.toBool(mod)) { | 17206 | } else if (!is_bool_or and !rhs_val.toBool()) { |
| 17221 | return Air.Inst.Ref.bool_false; | 17207 | return Air.Inst.Ref.bool_false; |
| 17222 | } | 17208 | } |
| 17223 | } | 17209 | } |
| ... | @@ -17371,7 +17357,7 @@ fn zirCondbr( | ... | @@ -17371,7 +17357,7 @@ fn zirCondbr( |
| 17371 | const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src); | 17357 | const cond = try sema.coerce(parent_block, Type.bool, uncasted_cond, cond_src); |
| 17372 | | 17358 | |
| 17373 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { | 17359 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { |
| 17374 | const body = if (cond_val.toBool(mod)) then_body else else_body; | 17360 | const body = if (cond_val.toBool()) then_body else else_body; |
| 17375 | | 17361 | |
| 17376 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); | 17362 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); |
| 17377 | // We use `analyzeBodyInner` since we want to propagate any possible | 17363 | // We use `analyzeBodyInner` since we want to propagate any possible |
| ... | @@ -17444,7 +17430,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -17444,7 +17430,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 17444 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); | 17430 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| 17445 | if (is_non_err != .none) { | 17431 | if (is_non_err != .none) { |
| 17446 | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; | 17432 | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; |
| 17447 | if (is_non_err_val.toBool(mod)) { | 17433 | if (is_non_err_val.toBool()) { |
| 17448 | return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false); | 17434 | return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false); |
| 17449 | } | 17435 | } |
| 17450 | // We can analyze the body directly in the parent block because we know there are | 17436 | // We can analyze the body directly in the parent block because we know there are |
| ... | @@ -17491,7 +17477,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -17491,7 +17477,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 17491 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); | 17477 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| 17492 | if (is_non_err != .none) { | 17478 | if (is_non_err != .none) { |
| 17493 | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; | 17479 | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; |
| 17494 | if (is_non_err_val.toBool(mod)) { | 17480 | if (is_non_err_val.toBool()) { |
| 17495 | return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false); | 17481 | return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false); |
| 17496 | } | 17482 | } |
| 17497 | // We can analyze the body directly in the parent block because we know there are | 17483 | // We can analyze the body directly in the parent block because we know there are |
| ... | @@ -18858,7 +18844,7 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -18858,7 +18844,7 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 18858 | const operand = try sema.resolveInst(inst_data.operand); | 18844 | const operand = try sema.resolveInst(inst_data.operand); |
| 18859 | if (try sema.resolveMaybeUndefVal(operand)) |val| { | 18845 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 18860 | if (val.isUndef(mod)) return sema.addConstUndef(Type.u1); | 18846 | if (val.isUndef(mod)) return sema.addConstUndef(Type.u1); |
| 18861 | if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1)); | 18847 | if (val.toBool()) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1)); |
| 18862 | return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0)); | 18848 | return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0)); |
| 18863 | } | 18849 | } |
| 18864 | return block.addUnOp(.bool_to_int, operand); | 18850 | return block.addUnOp(.bool_to_int, operand); |
| ... | @@ -19171,12 +19157,12 @@ fn zirReify( | ... | @@ -19171,12 +19157,12 @@ fn zirReify( |
| 19171 | | 19157 | |
| 19172 | const ty = try mod.ptrType(.{ | 19158 | const ty = try mod.ptrType(.{ |
| 19173 | .size = ptr_size, | 19159 | .size = ptr_size, |
| 19174 | .is_const = is_const_val.toBool(mod), | 19160 | .is_const = is_const_val.toBool(), |
| 19175 | .is_volatile = is_volatile_val.toBool(mod), | 19161 | .is_volatile = is_volatile_val.toBool(), |
| 19176 | .alignment = abi_align, | 19162 | .alignment = abi_align, |
| 19177 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), | 19163 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), |
| 19178 | .elem_type = elem_ty.toIntern(), | 19164 | .elem_type = elem_ty.toIntern(), |
| 19179 | .is_allowzero = is_allowzero_val.toBool(mod), | 19165 | .is_allowzero = is_allowzero_val.toBool(), |
| 19180 | .sentinel = actual_sentinel, | 19166 | .sentinel = actual_sentinel, |
| 19181 | }); | 19167 | }); |
| 19182 | return sema.addType(ty); | 19168 | return sema.addType(ty); |
| ... | @@ -19267,7 +19253,7 @@ fn zirReify( | ... | @@ -19267,7 +19253,7 @@ fn zirReify( |
| 19267 | return sema.fail(block, src, "non-packed struct does not support backing integer type", .{}); | 19253 | return sema.fail(block, src, "non-packed struct does not support backing integer type", .{}); |
| 19268 | } | 19254 | } |
| 19269 | | 19255 | |
| 19270 | return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool(mod)); | 19256 | return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool()); |
| 19271 | }, | 19257 | }, |
| 19272 | .Enum => { | 19258 | .Enum => { |
| 19273 | const fields = ip.typeOf(union_val.val).toType().structFields(mod); | 19259 | const fields = ip.typeOf(union_val.val).toType().structFields(mod); |
| ... | @@ -19305,7 +19291,7 @@ fn zirReify( | ... | @@ -19305,7 +19291,7 @@ fn zirReify( |
| 19305 | .namespace = .none, | 19291 | .namespace = .none, |
| 19306 | .fields_len = fields_len, | 19292 | .fields_len = fields_len, |
| 19307 | .has_values = true, | 19293 | .has_values = true, |
| 19308 | .tag_mode = if (!is_exhaustive_val.toBool(mod)) | 19294 | .tag_mode = if (!is_exhaustive_val.toBool()) |
| 19309 | .nonexhaustive | 19295 | .nonexhaustive |
| 19310 | else | 19296 | else |
| 19311 | .explicit, | 19297 | .explicit, |
| ... | @@ -19619,12 +19605,12 @@ fn zirReify( | ... | @@ -19619,12 +19605,12 @@ fn zirReify( |
| 19619 | const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?); | 19605 | const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?); |
| 19620 | const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?); | 19606 | const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?); |
| 19621 | | 19607 | |
| 19622 | const is_generic = is_generic_val.toBool(mod); | 19608 | const is_generic = is_generic_val.toBool(); |
| 19623 | if (is_generic) { | 19609 | if (is_generic) { |
| 19624 | return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{}); | 19610 | return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{}); |
| 19625 | } | 19611 | } |
| 19626 | | 19612 | |
| 19627 | const is_var_args = is_var_args_val.toBool(mod); | 19613 | const is_var_args = is_var_args_val.toBool(); |
| 19628 | const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val); | 19614 | const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val); |
| 19629 | if (is_var_args and cc != .C) { | 19615 | if (is_var_args and cc != .C) { |
| 19630 | return sema.fail(block, src, "varargs functions must have C calling convention", .{}); | 19616 | return sema.fail(block, src, "varargs functions must have C calling convention", .{}); |
| ... | @@ -19653,9 +19639,9 @@ fn zirReify( | ... | @@ -19653,9 +19639,9 @@ fn zirReify( |
| 19653 | const arg_val = arg.castTag(.aggregate).?.data; | 19639 | const arg_val = arg.castTag(.aggregate).?.data; |
| 19654 | // TODO use reflection instead of magic numbers here | 19640 | // TODO use reflection instead of magic numbers here |
| 19655 | // is_generic: bool, | 19641 | // is_generic: bool, |
| 19656 | const arg_is_generic = arg_val[0].toBool(mod); | 19642 | const arg_is_generic = arg_val[0].toBool(); |
| 19657 | // is_noalias: bool, | 19643 | // is_noalias: bool, |
| 19658 | const arg_is_noalias = arg_val[1].toBool(mod); | 19644 | const arg_is_noalias = arg_val[1].toBool(); |
| 19659 | // type: ?type, | 19645 | // type: ?type, |
| 19660 | const param_type_opt_val = arg_val[2]; | 19646 | const param_type_opt_val = arg_val[2]; |
| 19661 | | 19647 | |
| ... | @@ -19783,9 +19769,9 @@ fn reifyStruct( | ... | @@ -19783,9 +19769,9 @@ fn reifyStruct( |
| 19783 | | 19769 | |
| 19784 | if (layout == .Packed) { | 19770 | if (layout == .Packed) { |
| 19785 | if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); | 19771 | if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); |
| 19786 | if (is_comptime_val.toBool(mod)) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{}); | 19772 | if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{}); |
| 19787 | } | 19773 | } |
| 19788 | if (layout == .Extern and is_comptime_val.toBool(mod)) { | 19774 | if (layout == .Extern and is_comptime_val.toBool()) { |
| 19789 | return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{}); | 19775 | return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{}); |
| 19790 | } | 19776 | } |
| 19791 | | 19777 | |
| ... | @@ -19827,7 +19813,7 @@ fn reifyStruct( | ... | @@ -19827,7 +19813,7 @@ fn reifyStruct( |
| 19827 | opt_val; | 19813 | opt_val; |
| 19828 | break :blk try payload_val.copy(new_decl_arena_allocator); | 19814 | break :blk try payload_val.copy(new_decl_arena_allocator); |
| 19829 | } else Value.@"unreachable"; | 19815 | } else Value.@"unreachable"; |
| 19830 | if (is_comptime_val.toBool(mod) and default_val.toIntern() == .unreachable_value) { | 19816 | if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) { |
| 19831 | return sema.fail(block, src, "comptime field without default initialization value", .{}); | 19817 | return sema.fail(block, src, "comptime field without default initialization value", .{}); |
| 19832 | } | 19818 | } |
| 19833 | | 19819 | |
| ... | @@ -19836,7 +19822,7 @@ fn reifyStruct( | ... | @@ -19836,7 +19822,7 @@ fn reifyStruct( |
| 19836 | .ty = field_ty, | 19822 | .ty = field_ty, |
| 19837 | .abi_align = abi_align, | 19823 | .abi_align = abi_align, |
| 19838 | .default_val = default_val, | 19824 | .default_val = default_val, |
| 19839 | .is_comptime = is_comptime_val.toBool(mod), | 19825 | .is_comptime = is_comptime_val.toBool(), |
| 19840 | .offset = undefined, | 19826 | .offset = undefined, |
| 19841 | }; | 19827 | }; |
| 19842 | | 19828 | |
| ... | @@ -20400,13 +20386,17 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -20400,13 +20386,17 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20400 | if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) { | 20386 | if (!dest_ty.ptrAllowsZero(mod) and operand_val.isNull(mod)) { |
| 20401 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)}); | 20387 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)}); |
| 20402 | } | 20388 | } |
| 20403 | if (dest_ty.zigTypeTag(mod) == .Optional and sema.typeOf(ptr).zigTypeTag(mod) != .Optional) { | 20389 | return sema.addConstant(aligned_dest_ty, try mod.getCoerced(switch (mod.intern_pool.indexToKey(operand_val.toIntern())) { |
| 20404 | return sema.addConstant(dest_ty, (try mod.intern(.{ .opt = .{ | 20390 | .undef, .ptr => operand_val, |
| 20405 | .ty = dest_ty.toIntern(), | 20391 | .opt => |opt| switch (opt.val) { |
| 20406 | .val = operand_val.toIntern(), | 20392 | .none => if (dest_ty.ptrAllowsZero(mod)) |
| 20407 | } })).toValue()); | 20393 | Value.zero_usize |
| 20408 | } | 20394 | else |
| 20409 | return sema.addConstant(aligned_dest_ty, try mod.getCoerced(operand_val, aligned_dest_ty)); | 20395 | return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)}), |
| | 20396 | else => opt.val.toValue(), |
| | 20397 | }, |
| | 20398 | else => unreachable, |
| | 20399 | }, aligned_dest_ty)); |
| 20410 | } | 20400 | } |
| 20411 | | 20401 | |
| 20412 | try sema.requireRuntimeBlock(block, src, null); | 20402 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -20534,10 +20524,10 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -20534,10 +20524,10 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 20534 | if (try sema.resolveMaybeUndefValIntable(operand)) |val| { | 20524 | if (try sema.resolveMaybeUndefValIntable(operand)) |val| { |
| 20535 | if (val.isUndef(mod)) return sema.addConstUndef(dest_ty); | 20525 | if (val.isUndef(mod)) return sema.addConstUndef(dest_ty); |
| 20536 | if (!is_vector) { | 20526 | if (!is_vector) { |
| 20537 | return sema.addConstant( | 20527 | return sema.addConstant(dest_ty, try mod.getCoerced( |
| 20538 | dest_ty, | | |
| 20539 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, mod), | 20528 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits, mod), |
| 20540 | ); | 20529 | dest_ty, |
| | 20530 | )); |
| 20541 | } | 20531 | } |
| 20542 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); | 20532 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); |
| 20543 | for (elems, 0..) |*elem, i| { | 20533 | for (elems, 0..) |*elem, i| { |
| ... | @@ -21410,7 +21400,10 @@ fn zirCmpxchg( | ... | @@ -21410,7 +21400,10 @@ fn zirCmpxchg( |
| 21410 | | 21400 | |
| 21411 | // special case zero bit types | 21401 | // special case zero bit types |
| 21412 | if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { | 21402 | if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { |
| 21413 | return sema.addConstant(result_ty, Value.null); | 21403 | return sema.addConstant(result_ty, (try mod.intern(.{ .opt = .{ |
| | 21404 | .ty = result_ty.toIntern(), |
| | 21405 | .val = .none, |
| | 21406 | } })).toValue()); |
| 21414 | } | 21407 | } |
| 21415 | | 21408 | |
| 21416 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { | 21409 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { |
| ... | @@ -21633,8 +21626,7 @@ fn analyzeShuffle( | ... | @@ -21633,8 +21626,7 @@ fn analyzeShuffle( |
| 21633 | .{ b_len, b_src, b_ty }, | 21626 | .{ b_len, b_src, b_ty }, |
| 21634 | }; | 21627 | }; |
| 21635 | | 21628 | |
| 21636 | var i: usize = 0; | 21629 | for (0..@intCast(usize, mask_len)) |i| { |
| 21637 | while (i < mask_len) : (i += 1) { | | |
| 21638 | const elem = try mask.elemValue(sema.mod, i); | 21630 | const elem = try mask.elemValue(sema.mod, i); |
| 21639 | if (elem.isUndef(mod)) continue; | 21631 | if (elem.isUndef(mod)) continue; |
| 21640 | const int = elem.toSignedInt(mod); | 21632 | const int = elem.toSignedInt(mod); |
| ... | @@ -21670,7 +21662,7 @@ fn analyzeShuffle( | ... | @@ -21670,7 +21662,7 @@ fn analyzeShuffle( |
| 21670 | if (try sema.resolveMaybeUndefVal(a)) |a_val| { | 21662 | if (try sema.resolveMaybeUndefVal(a)) |a_val| { |
| 21671 | if (try sema.resolveMaybeUndefVal(b)) |b_val| { | 21663 | if (try sema.resolveMaybeUndefVal(b)) |b_val| { |
| 21672 | const values = try sema.arena.alloc(InternPool.Index, mask_len); | 21664 | const values = try sema.arena.alloc(InternPool.Index, mask_len); |
| 21673 | for (values) |*value| { | 21665 | for (values, 0..) |*value, i| { |
| 21674 | const mask_elem_val = try mask.elemValue(sema.mod, i); | 21666 | const mask_elem_val = try mask.elemValue(sema.mod, i); |
| 21675 | if (mask_elem_val.isUndef(mod)) { | 21667 | if (mask_elem_val.isUndef(mod)) { |
| 21676 | value.* = try mod.intern(.{ .undef = elem_ty.toIntern() }); | 21668 | value.* = try mod.intern(.{ .undef = elem_ty.toIntern() }); |
| ... | @@ -21698,11 +21690,10 @@ fn analyzeShuffle( | ... | @@ -21698,11 +21690,10 @@ fn analyzeShuffle( |
| 21698 | const max_len = try sema.usizeCast(block, max_src, std.math.max(a_len, b_len)); | 21690 | const max_len = try sema.usizeCast(block, max_src, std.math.max(a_len, b_len)); |
| 21699 | | 21691 | |
| 21700 | const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len); | 21692 | const expand_mask_values = try sema.arena.alloc(InternPool.Index, max_len); |
| 21701 | i = 0; | 21693 | for (@intCast(usize, 0)..@intCast(usize, min_len)) |i| { |
| 21702 | while (i < min_len) : (i += 1) { | | |
| 21703 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, i)).toIntern(); | 21694 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, i)).toIntern(); |
| 21704 | } | 21695 | } |
| 21705 | while (i < max_len) : (i += 1) { | 21696 | for (@intCast(usize, min_len)..@intCast(usize, max_len)) |i| { |
| 21706 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, -1)).toIntern(); | 21697 | expand_mask_values[i] = (try mod.intValue(Type.comptime_int, -1)).toIntern(); |
| 21707 | } | 21698 | } |
| 21708 | const expand_mask = try mod.intern(.{ .aggregate = .{ | 21699 | const expand_mask = try mod.intern(.{ .aggregate = .{ |
| ... | @@ -21783,7 +21774,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -21783,7 +21774,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 21783 | const elems = try sema.gpa.alloc(InternPool.Index, vec_len); | 21774 | const elems = try sema.gpa.alloc(InternPool.Index, vec_len); |
| 21784 | for (elems, 0..) |*elem, i| { | 21775 | for (elems, 0..) |*elem, i| { |
| 21785 | const pred_elem_val = try pred_val.elemValue(mod, i); | 21776 | const pred_elem_val = try pred_val.elemValue(mod, i); |
| 21786 | const should_choose_a = pred_elem_val.toBool(mod); | 21777 | const should_choose_a = pred_elem_val.toBool(); |
| 21787 | elem.* = try (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).intern(elem_ty, mod); | 21778 | elem.* = try (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).intern(elem_ty, mod); |
| 21788 | } | 21779 | } |
| 21789 | | 21780 | |
| ... | @@ -22853,15 +22844,15 @@ fn zirVarExtended( | ... | @@ -22853,15 +22844,15 @@ fn zirVarExtended( |
| 22853 | else | 22844 | else |
| 22854 | uncasted_init; | 22845 | uncasted_init; |
| 22855 | | 22846 | |
| 22856 | break :blk (try sema.resolveMaybeUndefVal(init)) orelse | 22847 | break :blk ((try sema.resolveMaybeUndefVal(init)) orelse |
| 22857 | return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime-known"); | 22848 | return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime-known")).toIntern(); |
| 22858 | } else Value.@"unreachable"; | 22849 | } else .none; |
| 22859 | | 22850 | |
| 22860 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); | 22851 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); |
| 22861 | | 22852 | |
| 22862 | return sema.addConstant(var_ty, (try mod.intern(.{ .variable = .{ | 22853 | return sema.addConstant(var_ty, (try mod.intern(.{ .variable = .{ |
| 22863 | .ty = var_ty.toIntern(), | 22854 | .ty = var_ty.toIntern(), |
| 22864 | .init = init_val.toIntern(), | 22855 | .init = init_val, |
| 22865 | .decl = sema.owner_decl_index, | 22856 | .decl = sema.owner_decl_index, |
| 22866 | .lib_name = if (lib_name) |lname| (try mod.intern_pool.getOrPutString( | 22857 | .lib_name = if (lib_name) |lname| (try mod.intern_pool.getOrPutString( |
| 22867 | sema.gpa, | 22858 | sema.gpa, |
| ... | @@ -23284,7 +23275,7 @@ fn resolveExternOptions( | ... | @@ -23284,7 +23275,7 @@ fn resolveExternOptions( |
| 23284 | .name = name, | 23275 | .name = name, |
| 23285 | .library_name = library_name, | 23276 | .library_name = library_name, |
| 23286 | .linkage = linkage, | 23277 | .linkage = linkage, |
| 23287 | .is_thread_local = is_thread_local_val.toBool(mod), | 23278 | .is_thread_local = is_thread_local_val.toBool(), |
| 23288 | }; | 23279 | }; |
| 23289 | } | 23280 | } |
| 23290 | | 23281 | |
| ... | @@ -26190,7 +26181,7 @@ fn coerceExtra( | ... | @@ -26190,7 +26181,7 @@ fn coerceExtra( |
| 26190 | .addr = .{ .int = (if (dest_info.@"align" != 0) | 26181 | .addr = .{ .int = (if (dest_info.@"align" != 0) |
| 26191 | try mod.intValue(Type.usize, dest_info.@"align") | 26182 | try mod.intValue(Type.usize, dest_info.@"align") |
| 26192 | else | 26183 | else |
| 26193 | try dest_info.pointee_type.lazyAbiAlignment(mod)).toIntern() }, | 26184 | try mod.getCoerced(try dest_info.pointee_type.lazyAbiAlignment(mod), Type.usize)).toIntern() }, |
| 26194 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), | 26185 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), |
| 26195 | } })).toValue()); | 26186 | } })).toValue()); |
| 26196 | } | 26187 | } |
| ... | @@ -27785,7 +27776,7 @@ fn beginComptimePtrMutation( | ... | @@ -27785,7 +27776,7 @@ fn beginComptimePtrMutation( |
| 27785 | const payload = try arena.create(Value.Payload.SubValue); | 27776 | const payload = try arena.create(Value.Payload.SubValue); |
| 27786 | payload.* = .{ | 27777 | payload.* = .{ |
| 27787 | .base = .{ .tag = .eu_payload }, | 27778 | .base = .{ .tag = .eu_payload }, |
| 27788 | .data = Value.undef, | 27779 | .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(), |
| 27789 | }; | 27780 | }; |
| 27790 | | 27781 | |
| 27791 | val_ptr.* = Value.initPayload(&payload.base); | 27782 | val_ptr.* = Value.initPayload(&payload.base); |
| ... | @@ -27824,7 +27815,7 @@ fn beginComptimePtrMutation( | ... | @@ -27824,7 +27815,7 @@ fn beginComptimePtrMutation( |
| 27824 | const payload = try arena.create(Value.Payload.SubValue); | 27815 | const payload = try arena.create(Value.Payload.SubValue); |
| 27825 | payload.* = .{ | 27816 | payload.* = .{ |
| 27826 | .base = .{ .tag = .opt_payload }, | 27817 | .base = .{ .tag = .opt_payload }, |
| 27827 | .data = Value.undef, | 27818 | .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(), |
| 27828 | }; | 27819 | }; |
| 27829 | | 27820 | |
| 27830 | val_ptr.* = Value.initPayload(&payload.base); | 27821 | val_ptr.* = Value.initPayload(&payload.base); |
| ... | @@ -27898,30 +27889,6 @@ fn beginComptimePtrMutation( | ... | @@ -27898,30 +27889,6 @@ fn beginComptimePtrMutation( |
| 27898 | } | 27889 | } |
| 27899 | | 27890 | |
| 27900 | switch (val_ptr.ip_index) { | 27891 | switch (val_ptr.ip_index) { |
| 27901 | .undef => { | | |
| 27902 | // An array has been initialized to undefined at comptime and now we | | |
| 27903 | // are for the first time setting an element. We must change the representation | | |
| 27904 | // of the array from `undef` to `array`. | | |
| 27905 | const arena = parent.beginArena(sema.mod); | | |
| 27906 | defer parent.finishArena(sema.mod); | | |
| 27907 | | | |
| 27908 | const array_len_including_sentinel = | | |
| 27909 | try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); | | |
| 27910 | const elems = try arena.alloc(Value, array_len_including_sentinel); | | |
| 27911 | @memset(elems, Value.undef); | | |
| 27912 | | | |
| 27913 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); | | |
| 27914 | | | |
| 27915 | return beginComptimePtrMutationInner( | | |
| 27916 | sema, | | |
| 27917 | block, | | |
| 27918 | src, | | |
| 27919 | elem_ty, | | |
| 27920 | &elems[elem_ptr.index], | | |
| 27921 | ptr_elem_ty, | | |
| 27922 | parent.mut_decl, | | |
| 27923 | ); | | |
| 27924 | }, | | |
| 27925 | .none => switch (val_ptr.tag()) { | 27892 | .none => switch (val_ptr.tag()) { |
| 27926 | .bytes => { | 27893 | .bytes => { |
| 27927 | // An array is memory-optimized to store a slice of bytes, but we are about | 27894 | // An array is memory-optimized to store a slice of bytes, but we are about |
| ... | @@ -27999,7 +27966,33 @@ fn beginComptimePtrMutation( | ... | @@ -27999,7 +27966,33 @@ fn beginComptimePtrMutation( |
| 27999 | | 27966 | |
| 28000 | else => unreachable, | 27967 | else => unreachable, |
| 28001 | }, | 27968 | }, |
| 28002 | else => unreachable, | 27969 | else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) { |
| | 27970 | .undef => { |
| | 27971 | // An array has been initialized to undefined at comptime and now we |
| | 27972 | // are for the first time setting an element. We must change the representation |
| | 27973 | // of the array from `undef` to `array`. |
| | 27974 | const arena = parent.beginArena(sema.mod); |
| | 27975 | defer parent.finishArena(sema.mod); |
| | 27976 | |
| | 27977 | const array_len_including_sentinel = |
| | 27978 | try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); |
| | 27979 | const elems = try arena.alloc(Value, array_len_including_sentinel); |
| | 27980 | @memset(elems, (try mod.intern(.{ .undef = elem_ty.toIntern() })).toValue()); |
| | 27981 | |
| | 27982 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); |
| | 27983 | |
| | 27984 | return beginComptimePtrMutationInner( |
| | 27985 | sema, |
| | 27986 | block, |
| | 27987 | src, |
| | 27988 | elem_ty, |
| | 27989 | &elems[elem_ptr.index], |
| | 27990 | ptr_elem_ty, |
| | 27991 | parent.mut_decl, |
| | 27992 | ); |
| | 27993 | }, |
| | 27994 | else => unreachable, |
| | 27995 | }, |
| 28003 | } | 27996 | } |
| 28004 | }, | 27997 | }, |
| 28005 | else => { | 27998 | else => { |
| ... | @@ -28052,83 +28045,6 @@ fn beginComptimePtrMutation( | ... | @@ -28052,83 +28045,6 @@ fn beginComptimePtrMutation( |
| 28052 | var parent = try sema.beginComptimePtrMutation(block, src, field_ptr.base.toValue(), base_child_ty); | 28045 | var parent = try sema.beginComptimePtrMutation(block, src, field_ptr.base.toValue(), base_child_ty); |
| 28053 | switch (parent.pointee) { | 28046 | switch (parent.pointee) { |
| 28054 | .direct => |val_ptr| switch (val_ptr.ip_index) { | 28047 | .direct => |val_ptr| switch (val_ptr.ip_index) { |
| 28055 | .undef => { | | |
| 28056 | // A struct or union has been initialized to undefined at comptime and now we | | |
| 28057 | // are for the first time setting a field. We must change the representation | | |
| 28058 | // of the struct/union from `undef` to `struct`/`union`. | | |
| 28059 | const arena = parent.beginArena(sema.mod); | | |
| 28060 | defer parent.finishArena(sema.mod); | | |
| 28061 | | | |
| 28062 | switch (parent.ty.zigTypeTag(mod)) { | | |
| 28063 | .Struct => { | | |
| 28064 | const fields = try arena.alloc(Value, parent.ty.structFieldCount(mod)); | | |
| 28065 | @memset(fields, Value.undef); | | |
| 28066 | | | |
| 28067 | val_ptr.* = try Value.Tag.aggregate.create(arena, fields); | | |
| 28068 | | | |
| 28069 | return beginComptimePtrMutationInner( | | |
| 28070 | sema, | | |
| 28071 | block, | | |
| 28072 | src, | | |
| 28073 | parent.ty.structFieldType(field_index, mod), | | |
| 28074 | &fields[field_index], | | |
| 28075 | ptr_elem_ty, | | |
| 28076 | parent.mut_decl, | | |
| 28077 | ); | | |
| 28078 | }, | | |
| 28079 | .Union => { | | |
| 28080 | const payload = try arena.create(Value.Payload.Union); | | |
| 28081 | const tag_ty = parent.ty.unionTagTypeHypothetical(mod); | | |
| 28082 | payload.* = .{ .data = .{ | | |
| 28083 | .tag = try mod.enumValueFieldIndex(tag_ty, field_index), | | |
| 28084 | .val = Value.undef, | | |
| 28085 | } }; | | |
| 28086 | | | |
| 28087 | val_ptr.* = Value.initPayload(&payload.base); | | |
| 28088 | | | |
| 28089 | return beginComptimePtrMutationInner( | | |
| 28090 | sema, | | |
| 28091 | block, | | |
| 28092 | src, | | |
| 28093 | parent.ty.structFieldType(field_index, mod), | | |
| 28094 | &payload.data.val, | | |
| 28095 | ptr_elem_ty, | | |
| 28096 | parent.mut_decl, | | |
| 28097 | ); | | |
| 28098 | }, | | |
| 28099 | .Pointer => { | | |
| 28100 | assert(parent.ty.isSlice(mod)); | | |
| 28101 | val_ptr.* = try Value.Tag.slice.create(arena, .{ | | |
| 28102 | .ptr = Value.undef, | | |
| 28103 | .len = Value.undef, | | |
| 28104 | }); | | |
| 28105 | | | |
| 28106 | switch (field_index) { | | |
| 28107 | Value.slice_ptr_index => return beginComptimePtrMutationInner( | | |
| 28108 | sema, | | |
| 28109 | block, | | |
| 28110 | src, | | |
| 28111 | parent.ty.slicePtrFieldType(mod), | | |
| 28112 | &val_ptr.castTag(.slice).?.data.ptr, | | |
| 28113 | ptr_elem_ty, | | |
| 28114 | parent.mut_decl, | | |
| 28115 | ), | | |
| 28116 | Value.slice_len_index => return beginComptimePtrMutationInner( | | |
| 28117 | sema, | | |
| 28118 | block, | | |
| 28119 | src, | | |
| 28120 | Type.usize, | | |
| 28121 | &val_ptr.castTag(.slice).?.data.len, | | |
| 28122 | ptr_elem_ty, | | |
| 28123 | parent.mut_decl, | | |
| 28124 | ), | | |
| 28125 | | | |
| 28126 | else => unreachable, | | |
| 28127 | } | | |
| 28128 | }, | | |
| 28129 | else => unreachable, | | |
| 28130 | } | | |
| 28131 | }, | | |
| 28132 | .empty_struct => { | 28048 | .empty_struct => { |
| 28133 | const duped = try sema.arena.create(Value); | 28049 | const duped = try sema.arena.create(Value); |
| 28134 | duped.* = val_ptr.*; | 28050 | duped.* = val_ptr.*; |
| ... | @@ -28210,10 +28126,92 @@ fn beginComptimePtrMutation( | ... | @@ -28210,10 +28126,92 @@ fn beginComptimePtrMutation( |
| 28210 | | 28126 | |
| 28211 | else => unreachable, | 28127 | else => unreachable, |
| 28212 | }, | 28128 | }, |
| | 28129 | else => unreachable, |
| | 28130 | }, |
| | 28131 | else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) { |
| | 28132 | .undef => { |
| | 28133 | // A struct or union has been initialized to undefined at comptime and now we |
| | 28134 | // are for the first time setting a field. We must change the representation |
| | 28135 | // of the struct/union from `undef` to `struct`/`union`. |
| | 28136 | const arena = parent.beginArena(sema.mod); |
| | 28137 | defer parent.finishArena(sema.mod); |
| | 28138 | |
| | 28139 | switch (parent.ty.zigTypeTag(mod)) { |
| | 28140 | .Struct => { |
| | 28141 | const fields = try arena.alloc(Value, parent.ty.structFieldCount(mod)); |
| | 28142 | for (fields, 0..) |*field, i| field.* = (try mod.intern(.{ |
| | 28143 | .undef = parent.ty.structFieldType(i, mod).toIntern(), |
| | 28144 | })).toValue(); |
| | 28145 | |
| | 28146 | val_ptr.* = try Value.Tag.aggregate.create(arena, fields); |
| | 28147 | |
| | 28148 | return beginComptimePtrMutationInner( |
| | 28149 | sema, |
| | 28150 | block, |
| | 28151 | src, |
| | 28152 | parent.ty.structFieldType(field_index, mod), |
| | 28153 | &fields[field_index], |
| | 28154 | ptr_elem_ty, |
| | 28155 | parent.mut_decl, |
| | 28156 | ); |
| | 28157 | }, |
| | 28158 | .Union => { |
| | 28159 | const payload = try arena.create(Value.Payload.Union); |
| | 28160 | const tag_ty = parent.ty.unionTagTypeHypothetical(mod); |
| | 28161 | const payload_ty = parent.ty.structFieldType(field_index, mod); |
| | 28162 | payload.* = .{ .data = .{ |
| | 28163 | .tag = try mod.enumValueFieldIndex(tag_ty, field_index), |
| | 28164 | .val = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(), |
| | 28165 | } }; |
| 28213 | | 28166 | |
| | 28167 | val_ptr.* = Value.initPayload(&payload.base); |
| | 28168 | |
| | 28169 | return beginComptimePtrMutationInner( |
| | 28170 | sema, |
| | 28171 | block, |
| | 28172 | src, |
| | 28173 | payload_ty, |
| | 28174 | &payload.data.val, |
| | 28175 | ptr_elem_ty, |
| | 28176 | parent.mut_decl, |
| | 28177 | ); |
| | 28178 | }, |
| | 28179 | .Pointer => { |
| | 28180 | assert(parent.ty.isSlice(mod)); |
| | 28181 | const ptr_ty = parent.ty.slicePtrFieldType(mod); |
| | 28182 | val_ptr.* = try Value.Tag.slice.create(arena, .{ |
| | 28183 | .ptr = (try mod.intern(.{ .undef = ptr_ty.toIntern() })).toValue(), |
| | 28184 | .len = (try mod.intern(.{ .undef = .usize_type })).toValue(), |
| | 28185 | }); |
| | 28186 | |
| | 28187 | switch (field_index) { |
| | 28188 | Value.slice_ptr_index => return beginComptimePtrMutationInner( |
| | 28189 | sema, |
| | 28190 | block, |
| | 28191 | src, |
| | 28192 | ptr_ty, |
| | 28193 | &val_ptr.castTag(.slice).?.data.ptr, |
| | 28194 | ptr_elem_ty, |
| | 28195 | parent.mut_decl, |
| | 28196 | ), |
| | 28197 | Value.slice_len_index => return beginComptimePtrMutationInner( |
| | 28198 | sema, |
| | 28199 | block, |
| | 28200 | src, |
| | 28201 | Type.usize, |
| | 28202 | &val_ptr.castTag(.slice).?.data.len, |
| | 28203 | ptr_elem_ty, |
| | 28204 | parent.mut_decl, |
| | 28205 | ), |
| | 28206 | |
| | 28207 | else => unreachable, |
| | 28208 | } |
| | 28209 | }, |
| | 28210 | else => unreachable, |
| | 28211 | } |
| | 28212 | }, |
| 28214 | else => unreachable, | 28213 | else => unreachable, |
| 28215 | }, | 28214 | }, |
| 28216 | else => unreachable, | | |
| 28217 | }, | 28215 | }, |
| 28218 | .reinterpret => |reinterpret| { | 28216 | .reinterpret => |reinterpret| { |
| 28219 | const field_offset_u64 = base_child_ty.structFieldOffset(field_index, mod); | 28217 | const field_offset_u64 = base_child_ty.structFieldOffset(field_index, mod); |
| ... | @@ -28370,18 +28368,22 @@ fn beginComptimePtrLoad( | ... | @@ -28370,18 +28368,22 @@ fn beginComptimePtrLoad( |
| 28370 | (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or | 28368 | (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or |
| 28371 | (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok; | 28369 | (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok; |
| 28372 | if (coerce_in_mem_ok) { | 28370 | if (coerce_in_mem_ok) { |
| 28373 | const payload_val = switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { | 28371 | const payload_val = switch (tv.val.ip_index) { |
| 28374 | .error_union => |error_union| switch (error_union.val) { | 28372 | .none => tv.val.cast(Value.Payload.SubValue).?.data, |
| 28375 | .err_name => |err_name| return sema.fail(block, src, "attempt to unwrap error: {s}", .{mod.intern_pool.stringToSlice(err_name)}), | 28373 | .null_value => return sema.fail(block, src, "attempt to use null value", .{}), |
| 28376 | .payload => |payload| payload, | 28374 | else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { |
| 28377 | }, | 28375 | .error_union => |error_union| switch (error_union.val) { |
| 28378 | .opt => |opt| switch (opt.val) { | 28376 | .err_name => |err_name| return sema.fail(block, src, "attempt to unwrap error: {s}", .{mod.intern_pool.stringToSlice(err_name)}), |
| 28379 | .none => return sema.fail(block, src, "attempt to use null value", .{}), | 28377 | .payload => |payload| payload, |
| 28380 | else => opt.val, | 28378 | }, |
| 28381 | }, | 28379 | .opt => |opt| switch (opt.val) { |
| 28382 | else => unreachable, | 28380 | .none => return sema.fail(block, src, "attempt to use null value", .{}), |
| | 28381 | else => opt.val, |
| | 28382 | }, |
| | 28383 | else => unreachable, |
| | 28384 | }.toValue(), |
| 28383 | }; | 28385 | }; |
| 28384 | tv.* = TypedValue{ .ty = payload_ty, .val = payload_val.toValue() }; | 28386 | tv.* = TypedValue{ .ty = payload_ty, .val = payload_val }; |
| 28385 | break :blk deref; | 28387 | break :blk deref; |
| 28386 | } | 28388 | } |
| 28387 | } | 28389 | } |
| ... | @@ -28960,7 +28962,7 @@ fn coerceArrayLike( | ... | @@ -28960,7 +28962,7 @@ fn coerceArrayLike( |
| 28960 | if (in_memory_result == .ok) { | 28962 | if (in_memory_result == .ok) { |
| 28961 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { | 28963 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| 28962 | // These types share the same comptime value representation. | 28964 | // These types share the same comptime value representation. |
| 28963 | return sema.addConstant(dest_ty, inst_val); | 28965 | return sema.addConstant(dest_ty, try mod.getCoerced(inst_val, dest_ty)); |
| 28964 | } | 28966 | } |
| 28965 | try sema.requireRuntimeBlock(block, inst_src, null); | 28967 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 28966 | return block.addBitCast(dest_ty, inst); | 28968 | return block.addBitCast(dest_ty, inst); |
| ... | @@ -29024,7 +29026,7 @@ fn coerceTupleToArray( | ... | @@ -29024,7 +29026,7 @@ fn coerceTupleToArray( |
| 29024 | return sema.failWithOwnedErrorMsg(msg); | 29026 | return sema.failWithOwnedErrorMsg(msg); |
| 29025 | } | 29027 | } |
| 29026 | | 29028 | |
| 29027 | const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLenIncludingSentinel(mod)); | 29029 | const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_len); |
| 29028 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_elems); | 29030 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_elems); |
| 29029 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_elems); | 29031 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_elems); |
| 29030 | const dest_elem_ty = dest_ty.childType(mod); | 29032 | const dest_elem_ty = dest_ty.childType(mod); |
| ... | @@ -29430,7 +29432,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo | ... | @@ -29430,7 +29432,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo |
| 29430 | const ptr_ty = try mod.ptrType(.{ | 29432 | const ptr_ty = try mod.ptrType(.{ |
| 29431 | .elem_type = decl_tv.ty.toIntern(), | 29433 | .elem_type = decl_tv.ty.toIntern(), |
| 29432 | .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"), | 29434 | .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"), |
| 29433 | .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else false, | 29435 | .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true, |
| 29434 | .address_space = decl.@"addrspace", | 29436 | .address_space = decl.@"addrspace", |
| 29435 | }); | 29437 | }); |
| 29436 | if (analyze_fn_body) { | 29438 | if (analyze_fn_body) { |
| ... | @@ -29513,7 +29515,7 @@ fn analyzeLoad( | ... | @@ -29513,7 +29515,7 @@ fn analyzeLoad( |
| 29513 | | 29515 | |
| 29514 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { | 29516 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { |
| 29515 | if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| { | 29517 | if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| { |
| 29516 | return sema.addConstant(elem_ty, elem_val); | 29518 | return sema.addConstant(elem_ty, try mod.getCoerced(elem_val, elem_ty)); |
| 29517 | } | 29519 | } |
| 29518 | } | 29520 | } |
| 29519 | | 29521 | |
| ... | @@ -32610,8 +32612,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32610,8 +32612,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32610 | | 32612 | |
| 32611 | var int_tag_ty: Type = undefined; | 32613 | var int_tag_ty: Type = undefined; |
| 32612 | var enum_field_names: []InternPool.NullTerminatedString = &.{}; | 32614 | var enum_field_names: []InternPool.NullTerminatedString = &.{}; |
| 32613 | var enum_field_vals: []InternPool.Index = &.{}; | 32615 | var enum_field_vals: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{}; |
| 32614 | var enum_field_vals_map: std.ArrayHashMapUnmanaged(Value, void, Value.ArrayHashContext, false) = .{}; | | |
| 32615 | var explicit_tags_seen: []bool = &.{}; | 32616 | var explicit_tags_seen: []bool = &.{}; |
| 32616 | var explicit_enum_info: ?InternPool.Key.EnumType = null; | 32617 | var explicit_enum_info: ?InternPool.Key.EnumType = null; |
| 32617 | if (tag_type_ref != .none) { | 32618 | if (tag_type_ref != .none) { |
| ... | @@ -32638,9 +32639,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32638,9 +32639,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32638 | }; | 32639 | }; |
| 32639 | return sema.failWithOwnedErrorMsg(msg); | 32640 | return sema.failWithOwnedErrorMsg(msg); |
| 32640 | } | 32641 | } |
| | 32642 | enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len); |
| | 32643 | try enum_field_vals.ensureTotalCapacity(sema.arena, fields_len); |
| 32641 | } | 32644 | } |
| 32642 | enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len); | | |
| 32643 | enum_field_vals = try sema.arena.alloc(InternPool.Index, fields_len); | | |
| 32644 | } else { | 32645 | } else { |
| 32645 | // The provided type is the enum tag type. | 32646 | // The provided type is the enum tag type. |
| 32646 | union_obj.tag_ty = provided_ty; | 32647 | union_obj.tag_ty = provided_ty; |
| ... | @@ -32712,8 +32713,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32712,8 +32713,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32712 | break :blk try sema.resolveInst(tag_ref); | 32713 | break :blk try sema.resolveInst(tag_ref); |
| 32713 | } else .none; | 32714 | } else .none; |
| 32714 | | 32715 | |
| 32715 | if (enum_field_vals.len != 0) { | 32716 | if (enum_field_vals.capacity() > 0) { |
| 32716 | const copied_val = if (tag_ref != .none) blk: { | 32717 | const enum_tag_val = if (tag_ref != .none) blk: { |
| 32717 | const val = sema.semaUnionFieldVal(&block_scope, .unneeded, int_tag_ty, tag_ref) catch |err| switch (err) { | 32718 | const val = sema.semaUnionFieldVal(&block_scope, .unneeded, int_tag_ty, tag_ref) catch |err| switch (err) { |
| 32718 | error.NeededSourceLocation => { | 32719 | error.NeededSourceLocation => { |
| 32719 | const val_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ | 32720 | const val_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ |
| ... | @@ -32737,16 +32738,12 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32737,16 +32738,12 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32737 | | 32738 | |
| 32738 | break :blk val; | 32739 | break :blk val; |
| 32739 | }; | 32740 | }; |
| 32740 | enum_field_vals[field_i] = copied_val.toIntern(); | 32741 | const gop = enum_field_vals.getOrPutAssumeCapacity(enum_tag_val.toIntern()); |
| 32741 | const gop = enum_field_vals_map.getOrPutAssumeCapacityContext(copied_val, .{ | | |
| 32742 | .ty = int_tag_ty, | | |
| 32743 | .mod = mod, | | |
| 32744 | }); | | |
| 32745 | if (gop.found_existing) { | 32742 | if (gop.found_existing) { |
| 32746 | const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy; | 32743 | const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy; |
| 32747 | const other_field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = gop.index }).lazy; | 32744 | const other_field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = gop.index }).lazy; |
| 32748 | const msg = msg: { | 32745 | const msg = msg: { |
| 32749 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, mod)}); | 32746 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(int_tag_ty, mod)}); |
| 32750 | errdefer msg.destroy(gpa); | 32747 | errdefer msg.destroy(gpa); |
| 32751 | try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); | 32748 | try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); |
| 32752 | break :msg msg; | 32749 | break :msg msg; |
| ... | @@ -32907,8 +32904,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32907,8 +32904,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32907 | }; | 32904 | }; |
| 32908 | return sema.failWithOwnedErrorMsg(msg); | 32905 | return sema.failWithOwnedErrorMsg(msg); |
| 32909 | } | 32906 | } |
| 32910 | } else if (enum_field_vals.len != 0) { | 32907 | } else if (enum_field_vals.count() > 0) { |
| 32911 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals, union_obj); | 32908 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), union_obj); |
| 32912 | } else { | 32909 | } else { |
| 32913 | union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, union_obj); | 32910 | union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, union_obj); |
| 32914 | } | 32911 | } |
| ... | @@ -33180,8 +33177,12 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33180,8 +33177,12 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33180 | .struct_type => |struct_type| { | 33177 | .struct_type => |struct_type| { |
| 33181 | const resolved_ty = try sema.resolveTypeFields(ty); | 33178 | const resolved_ty = try sema.resolveTypeFields(ty); |
| 33182 | if (mod.structPtrUnwrap(struct_type.index)) |s| { | 33179 | if (mod.structPtrUnwrap(struct_type.index)) |s| { |
| 33183 | for (s.fields.values(), 0..) |field, i| { | 33180 | const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count()); |
| 33184 | if (field.is_comptime) continue; | 33181 | for (field_vals, s.fields.values(), 0..) |*field_val, field, i| { |
| | 33182 | if (field.is_comptime) { |
| | 33183 | field_val.* = try field.default_val.intern(field.ty, mod); |
| | 33184 | continue; |
| | 33185 | } |
| 33185 | if (field.ty.eql(resolved_ty, sema.mod)) { | 33186 | if (field.ty.eql(resolved_ty, sema.mod)) { |
| 33186 | const msg = try Module.ErrorMsg.create( | 33187 | const msg = try Module.ErrorMsg.create( |
| 33187 | sema.gpa, | 33188 | sema.gpa, |
| ... | @@ -33192,24 +33193,25 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33192,24 +33193,25 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33192 | try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{}); | 33193 | try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{}); |
| 33193 | return sema.failWithOwnedErrorMsg(msg); | 33194 | return sema.failWithOwnedErrorMsg(msg); |
| 33194 | } | 33195 | } |
| 33195 | if ((try sema.typeHasOnePossibleValue(field.ty)) == null) { | 33196 | if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| { |
| 33196 | return null; | 33197 | field_val.* = try field_opv.intern(field.ty, mod); |
| 33197 | } | 33198 | } else return null; |
| 33198 | } | 33199 | } |
| | 33200 | |
| | 33201 | // In this case the struct has no runtime-known fields and |
| | 33202 | // therefore has one possible value. |
| | 33203 | return (try mod.intern(.{ .aggregate = .{ |
| | 33204 | .ty = ty.toIntern(), |
| | 33205 | .storage = .{ .elems = field_vals }, |
| | 33206 | } })).toValue(); |
| 33199 | } | 33207 | } |
| 33200 | // In this case the struct has no runtime-known fields and | | |
| 33201 | // therefore has one possible value. | | |
| 33202 | | 33208 | |
| 33203 | // TODO: this is incorrect for structs with comptime fields, I think | 33209 | // In this case the struct has no fields at all and |
| 33204 | // we should use a temporary allocator to construct an aggregate that | 33210 | // therefore has one possible value. |
| 33205 | // is populated with the comptime values and then intern that value here. | 33211 | return (try mod.intern(.{ .aggregate = .{ |
| 33206 | // This TODO is repeated in the redundant implementation of | | |
| 33207 | // one-possible-value in type.zig. | | |
| 33208 | const empty = try mod.intern(.{ .aggregate = .{ | | |
| 33209 | .ty = ty.toIntern(), | 33212 | .ty = ty.toIntern(), |
| 33210 | .storage = .{ .elems = &.{} }, | 33213 | .storage = .{ .elems = &.{} }, |
| 33211 | } }); | 33214 | } })).toValue(); |
| 33212 | return empty.toValue(); | | |
| 33213 | }, | 33215 | }, |
| 33214 | | 33216 | |
| 33215 | .anon_struct_type => |tuple| { | 33217 | .anon_struct_type => |tuple| { |
| ... | @@ -33268,20 +33270,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33268,20 +33270,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33268 | }, | 33270 | }, |
| 33269 | .auto, .explicit => switch (enum_type.names.len) { | 33271 | .auto, .explicit => switch (enum_type.names.len) { |
| 33270 | 0 => return Value.@"unreachable", | 33272 | 0 => return Value.@"unreachable", |
| 33271 | 1 => { | 33273 | 1 => return try mod.getCoerced((if (enum_type.values.len == 0) |
| 33272 | if (enum_type.values.len == 0) { | 33274 | try mod.intern(.{ .int = .{ |
| 33273 | const only = try mod.intern(.{ .enum_tag = .{ | 33275 | .ty = enum_type.tag_ty, |
| 33274 | .ty = ty.toIntern(), | 33276 | .storage = .{ .u64 = 0 }, |
| 33275 | .int = try mod.intern(.{ .int = .{ | 33277 | } }) |
| 33276 | .ty = enum_type.tag_ty, | 33278 | else |
| 33277 | .storage = .{ .u64 = 0 }, | 33279 | enum_type.values[0]).toValue(), ty), |
| 33278 | } }), | | |
| 33279 | } }); | | |
| 33280 | return only.toValue(); | | |
| 33281 | } else { | | |
| 33282 | return enum_type.values[0].toValue(); | | |
| 33283 | } | | |
| 33284 | }, | | |
| 33285 | else => return null, | 33280 | else => return null, |
| 33286 | }, | 33281 | }, |
| 33287 | }, | 33282 | }, |
| ... | @@ -33427,7 +33422,7 @@ fn analyzeComptimeAlloc( | ... | @@ -33427,7 +33422,7 @@ fn analyzeComptimeAlloc( |
| 33427 | // There will be stores before the first load, but they may be to sub-elements or | 33422 | // There will be stores before the first load, but they may be to sub-elements or |
| 33428 | // sub-fields. So we need to initialize with undef to allow the mechanism to expand | 33423 | // sub-fields. So we need to initialize with undef to allow the mechanism to expand |
| 33429 | // into fields/elements and have those overridden with stored values. | 33424 | // into fields/elements and have those overridden with stored values. |
| 33430 | Value.undef, | 33425 | (try sema.mod.intern(.{ .undef = var_type.toIntern() })).toValue(), |
| 33431 | alignment, | 33426 | alignment, |
| 33432 | ); | 33427 | ); |
| 33433 | const decl = sema.mod.declPtr(decl_index); | 33428 | const decl = sema.mod.declPtr(decl_index); |
| ... | @@ -34028,16 +34023,16 @@ fn intSubWithOverflow( | ... | @@ -34028,16 +34023,16 @@ fn intSubWithOverflow( |
| 34028 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 34023 | const lhs_elem = try lhs.elemValue(sema.mod, i); |
| 34029 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 34024 | const rhs_elem = try rhs.elemValue(sema.mod, i); |
| 34030 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 34025 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 34031 | of.* = try of_math_result.overflow_bit.intern(Type.bool, mod); | 34026 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); |
| 34032 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 34027 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); |
| 34033 | } | 34028 | } |
| 34034 | return Value.OverflowArithmeticResult{ | 34029 | return Value.OverflowArithmeticResult{ |
| 34035 | .overflow_bit = (try mod.intern(.{ .aggregate = .{ | 34030 | .overflow_bit = (try mod.intern(.{ .aggregate = .{ |
| 34036 | .ty = ty.toIntern(), | 34031 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 34037 | .storage = .{ .elems = overflowed_data }, | 34032 | .storage = .{ .elems = overflowed_data }, |
| 34038 | } })).toValue(), | 34033 | } })).toValue(), |
| 34039 | .wrapped_result = (try mod.intern(.{ .aggregate = .{ | 34034 | .wrapped_result = (try mod.intern(.{ .aggregate = .{ |
| 34040 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 34035 | .ty = ty.toIntern(), |
| 34041 | .storage = .{ .elems = result_data }, | 34036 | .storage = .{ .elems = result_data }, |
| 34042 | } })).toValue(), | 34037 | } })).toValue(), |
| 34043 | }; | 34038 | }; |
| ... | @@ -34066,7 +34061,7 @@ fn intSubWithOverflowScalar( | ... | @@ -34066,7 +34061,7 @@ fn intSubWithOverflowScalar( |
| 34066 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 34061 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 34067 | const wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()); | 34062 | const wrapped_result = try mod.intValue_big(ty, result_bigint.toConst()); |
| 34068 | return Value.OverflowArithmeticResult{ | 34063 | return Value.OverflowArithmeticResult{ |
| 34069 | .overflow_bit = Value.boolToInt(overflowed), | 34064 | .overflow_bit = try mod.intValue(Type.u1, @boolToInt(overflowed)), |
| 34070 | .wrapped_result = wrapped_result, | 34065 | .wrapped_result = wrapped_result, |
| 34071 | }; | 34066 | }; |
| 34072 | } | 34067 | } |
| ... | @@ -34273,16 +34268,16 @@ fn intAddWithOverflow( | ... | @@ -34273,16 +34268,16 @@ fn intAddWithOverflow( |
| 34273 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 34268 | const lhs_elem = try lhs.elemValue(sema.mod, i); |
| 34274 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 34269 | const rhs_elem = try rhs.elemValue(sema.mod, i); |
| 34275 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 34270 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 34276 | of.* = try of_math_result.overflow_bit.intern(Type.bool, mod); | 34271 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); |
| 34277 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 34272 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); |
| 34278 | } | 34273 | } |
| 34279 | return Value.OverflowArithmeticResult{ | 34274 | return Value.OverflowArithmeticResult{ |
| 34280 | .overflow_bit = (try mod.intern(.{ .aggregate = .{ | 34275 | .overflow_bit = (try mod.intern(.{ .aggregate = .{ |
| 34281 | .ty = ty.toIntern(), | 34276 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), |
| 34282 | .storage = .{ .elems = overflowed_data }, | 34277 | .storage = .{ .elems = overflowed_data }, |
| 34283 | } })).toValue(), | 34278 | } })).toValue(), |
| 34284 | .wrapped_result = (try mod.intern(.{ .aggregate = .{ | 34279 | .wrapped_result = (try mod.intern(.{ .aggregate = .{ |
| 34285 | .ty = (try mod.vectorType(.{ .len = vec_len, .child = .u1_type })).toIntern(), | 34280 | .ty = ty.toIntern(), |
| 34286 | .storage = .{ .elems = result_data }, | 34281 | .storage = .{ .elems = result_data }, |
| 34287 | } })).toValue(), | 34282 | } })).toValue(), |
| 34288 | }; | 34283 | }; |
| ... | @@ -34311,7 +34306,7 @@ fn intAddWithOverflowScalar( | ... | @@ -34311,7 +34306,7 @@ fn intAddWithOverflowScalar( |
| 34311 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); | 34306 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| 34312 | const result = try mod.intValue_big(ty, result_bigint.toConst()); | 34307 | const result = try mod.intValue_big(ty, result_bigint.toConst()); |
| 34313 | return Value.OverflowArithmeticResult{ | 34308 | return Value.OverflowArithmeticResult{ |
| 34314 | .overflow_bit = Value.boolToInt(overflowed), | 34309 | .overflow_bit = try mod.intValue(Type.u1, @boolToInt(overflowed)), |
| 34315 | .wrapped_result = result, | 34310 | .wrapped_result = result, |
| 34316 | }; | 34311 | }; |
| 34317 | } | 34312 | } |
| ... | @@ -34384,7 +34379,7 @@ fn compareVector( | ... | @@ -34384,7 +34379,7 @@ fn compareVector( |
| 34384 | scalar.* = try Value.makeBool(res_bool).intern(Type.bool, mod); | 34379 | scalar.* = try Value.makeBool(res_bool).intern(Type.bool, mod); |
| 34385 | } | 34380 | } |
| 34386 | return (try mod.intern(.{ .aggregate = .{ | 34381 | return (try mod.intern(.{ .aggregate = .{ |
| 34387 | .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .u1_type })).toIntern(), | 34382 | .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), |
| 34388 | .storage = .{ .elems = result_data }, | 34383 | .storage = .{ .elems = result_data }, |
| 34389 | } })).toValue(); | 34384 | } })).toValue(); |
| 34390 | } | 34385 | } |