| ... | ... | @@ -89,7 +89,9 @@ is_generic_instantiation: bool = false, |
| 89 | 89 | /// function types will emit generic poison instead of a partial type. |
| 90 | 90 | no_partial_func_ty: bool = false, |
| 91 | 91 | |
| 92 | | unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, void) = .{}, |
| 92 | /// The temporary arena is used for the memory of the `InferredAlloc` values |
| 93 | /// here so the values can be dropped without any cleanup. |
| 94 | unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{}, |
| 93 | 95 | |
| 94 | 96 | const std = @import("std"); |
| 95 | 97 | const math = std.math; |
| ... | ... | @@ -718,7 +720,7 @@ pub const Block = struct { |
| 718 | 720 | } |
| 719 | 721 | |
| 720 | 722 | /// `alignment` value of 0 means to use ABI alignment. |
| 721 | | pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u32) !Decl.Index { |
| 723 | pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u64) !Decl.Index { |
| 722 | 724 | const sema = wad.block.sema; |
| 723 | 725 | // Do this ahead of time because `createAnonymousDecl` depends on calling |
| 724 | 726 | // `type.hasRuntimeBits()`. |
| ... | ... | @@ -728,7 +730,8 @@ pub const Block = struct { |
| 728 | 730 | .val = val, |
| 729 | 731 | }); |
| 730 | 732 | const new_decl = sema.mod.declPtr(new_decl_index); |
| 731 | | new_decl.@"align" = alignment; |
| 733 | // TODO: migrate Decl alignment to use `InternPool.Alignment` |
| 734 | new_decl.@"align" = @intCast(u32, alignment); |
| 732 | 735 | errdefer sema.mod.abortAnonDecl(new_decl_index); |
| 733 | 736 | try new_decl.finalizeNewArena(&wad.new_decl_arena); |
| 734 | 737 | wad.finished = true; |
| ... | ... | @@ -748,6 +751,23 @@ const LabeledBlock = struct { |
| 748 | 751 | } |
| 749 | 752 | }; |
| 750 | 753 | |
| 754 | /// The value stored in the inferred allocation. This will go into |
| 755 | /// peer type resolution. This is stored in a separate list so that |
| 756 | /// the items are contiguous in memory and thus can be passed to |
| 757 | /// `Module.resolvePeerTypes`. |
| 758 | const InferredAlloc = struct { |
| 759 | prongs: std.MultiArrayList(struct { |
| 760 | /// The dummy instruction used as a peer to resolve the type. |
| 761 | /// Although this has a redundant type with placeholder, this is |
| 762 | /// needed in addition because it may be a constant value, which |
| 763 | /// affects peer type resolution. |
| 764 | stored_inst: Air.Inst.Ref, |
| 765 | /// The bitcast instruction used as a placeholder when the |
| 766 | /// new result pointer type is not yet known. |
| 767 | placeholder: Air.Inst.Index, |
| 768 | }) = .{}, |
| 769 | }; |
| 770 | |
| 751 | 771 | pub fn deinit(sema: *Sema) void { |
| 752 | 772 | const gpa = sema.gpa; |
| 753 | 773 | sema.air_instructions.deinit(gpa); |
| ... | ... | @@ -909,10 +929,10 @@ fn analyzeBodyInner( |
| 909 | 929 | const air_inst: Air.Inst.Ref = switch (tags[inst]) { |
| 910 | 930 | // zig fmt: off |
| 911 | 931 | .alloc => try sema.zirAlloc(block, inst), |
| 912 | | .alloc_inferred => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_const_type }), |
| 913 | | .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_mut_type }), |
| 914 | | .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_const_type }), |
| 915 | | .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_mut_type }), |
| 932 | .alloc_inferred => try sema.zirAllocInferred(block, inst, true), |
| 933 | .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, false), |
| 934 | .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, true), |
| 935 | .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, false), |
| 916 | 936 | .alloc_mut => try sema.zirAllocMut(block, inst), |
| 917 | 937 | .alloc_comptime_mut => try sema.zirAllocComptime(block, inst), |
| 918 | 938 | .make_ptr_const => try sema.zirMakePtrConst(block, inst), |
| ... | ... | @@ -1707,7 +1727,7 @@ fn analyzeBodyInner( |
| 1707 | 1727 | break :blk Air.Inst.Ref.void_value; |
| 1708 | 1728 | }, |
| 1709 | 1729 | }; |
| 1710 | | if (sema.typeOf(air_inst).isNoReturn(mod)) |
| 1730 | if (sema.isNoReturn(air_inst)) |
| 1711 | 1731 | break always_noreturn; |
| 1712 | 1732 | map.putAssumeCapacity(inst, air_inst); |
| 1713 | 1733 | i += 1; |
| ... | ... | @@ -1751,8 +1771,6 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { |
| 1751 | 1771 | // The last section of indexes refers to the map of ZIR => AIR. |
| 1752 | 1772 | const inst = sema.inst_map.get(i - InternPool.static_len).?; |
| 1753 | 1773 | if (inst == .generic_poison) return error.GenericPoison; |
| 1754 | | const ty = sema.typeOf(inst); |
| 1755 | | assert(!ty.isGenericPoison()); |
| 1756 | 1774 | return inst; |
| 1757 | 1775 | } |
| 1758 | 1776 | |
| ... | ... | @@ -2431,20 +2449,20 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2431 | 2449 | const tracy = trace(@src()); |
| 2432 | 2450 | defer tracy.end(); |
| 2433 | 2451 | |
| 2452 | const mod = sema.mod; |
| 2434 | 2453 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2435 | 2454 | const src = inst_data.src(); |
| 2436 | 2455 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 2437 | 2456 | const pointee_ty = try sema.resolveType(block, src, extra.lhs); |
| 2438 | 2457 | const ptr = try sema.resolveInst(extra.rhs); |
| 2439 | | const target = sema.mod.getTarget(); |
| 2458 | const target = mod.getTarget(); |
| 2440 | 2459 | const addr_space = target_util.defaultAddressSpace(target, .local); |
| 2441 | 2460 | |
| 2442 | 2461 | if (Air.refToIndex(ptr)) |ptr_inst| { |
| 2443 | 2462 | switch (sema.air_instructions.items(.tag)[ptr_inst]) { |
| 2444 | 2463 | .inferred_alloc => { |
| 2445 | | const air_datas = sema.air_instructions.items(.data); |
| 2446 | | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; |
| 2447 | | const inferred_alloc = &ptr_val.castTag(.inferred_alloc).?.data; |
| 2464 | const ia1 = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc; |
| 2465 | const ia2 = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?; |
| 2448 | 2466 | // Add the stored instruction to the set we will use to resolve peer types |
| 2449 | 2467 | // for the inferred allocation. |
| 2450 | 2468 | // This instruction will not make it to codegen; it is only to participate |
| ... | ... | @@ -2453,14 +2471,14 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2453 | 2471 | defer trash_block.instructions.deinit(sema.gpa); |
| 2454 | 2472 | const operand = try trash_block.addBitCast(pointee_ty, .void_value); |
| 2455 | 2473 | |
| 2456 | | const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 2457 | | .pointee_type = pointee_ty, |
| 2458 | | .@"align" = inferred_alloc.alignment, |
| 2459 | | .@"addrspace" = addr_space, |
| 2474 | const ptr_ty = try mod.ptrType(.{ |
| 2475 | .elem_type = pointee_ty.toIntern(), |
| 2476 | .alignment = ia1.alignment, |
| 2477 | .address_space = addr_space, |
| 2460 | 2478 | }); |
| 2461 | 2479 | const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); |
| 2462 | 2480 | |
| 2463 | | try inferred_alloc.prongs.append(sema.arena, .{ |
| 2481 | try ia2.prongs.append(sema.arena, .{ |
| 2464 | 2482 | .stored_inst = operand, |
| 2465 | 2483 | .placeholder = Air.refToIndex(bitcasted_ptr).?, |
| 2466 | 2484 | }); |
| ... | ... | @@ -2468,31 +2486,30 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2468 | 2486 | return bitcasted_ptr; |
| 2469 | 2487 | }, |
| 2470 | 2488 | .inferred_alloc_comptime => { |
| 2471 | | const air_datas = sema.air_instructions.items(.data); |
| 2472 | | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; |
| 2473 | | const iac = ptr_val.castTag(.inferred_alloc_comptime).?; |
| 2489 | const alignment = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.alignment; |
| 2474 | 2490 | // There will be only one coerce_result_ptr because we are running at comptime. |
| 2475 | 2491 | // The alloc will turn into a Decl. |
| 2476 | 2492 | var anon_decl = try block.startAnonDecl(); |
| 2477 | 2493 | defer anon_decl.deinit(); |
| 2478 | | iac.data.decl_index = try anon_decl.finish( |
| 2494 | const decl_index = try anon_decl.finish( |
| 2479 | 2495 | pointee_ty, |
| 2480 | 2496 | Value.undef, |
| 2481 | | iac.data.alignment, |
| 2497 | alignment.toByteUnits(0), |
| 2482 | 2498 | ); |
| 2483 | | if (iac.data.alignment != 0) { |
| 2499 | sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.decl_index = decl_index; |
| 2500 | if (alignment != .none) { |
| 2484 | 2501 | try sema.resolveTypeLayout(pointee_ty); |
| 2485 | 2502 | } |
| 2486 | | const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 2487 | | .pointee_type = pointee_ty, |
| 2488 | | .@"align" = iac.data.alignment, |
| 2489 | | .@"addrspace" = addr_space, |
| 2503 | const ptr_ty = try mod.ptrType(.{ |
| 2504 | .elem_type = pointee_ty.toIntern(), |
| 2505 | .alignment = alignment, |
| 2506 | .address_space = addr_space, |
| 2490 | 2507 | }); |
| 2491 | | try sema.maybeQueueFuncBodyAnalysis(iac.data.decl_index); |
| 2492 | | return sema.addConstant(ptr_ty, (try sema.mod.intern(.{ .ptr = .{ |
| 2508 | try sema.maybeQueueFuncBodyAnalysis(decl_index); |
| 2509 | return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{ |
| 2493 | 2510 | .ty = ptr_ty.toIntern(), |
| 2494 | 2511 | .addr = .{ .mut_decl = .{ |
| 2495 | | .decl = iac.data.decl_index, |
| 2512 | .decl = decl_index, |
| 2496 | 2513 | .runtime_index = block.runtime_index, |
| 2497 | 2514 | } }, |
| 2498 | 2515 | } })).toValue()); |
| ... | ... | @@ -3479,25 +3496,16 @@ fn zirAllocExtended( |
| 3479 | 3496 | break :blk alignment; |
| 3480 | 3497 | } else 0; |
| 3481 | 3498 | |
| 3482 | | const inferred_alloc_ty = if (small.is_const) |
| 3483 | | Type{ .ip_index = .inferred_alloc_const_type } |
| 3484 | | else |
| 3485 | | Type{ .ip_index = .inferred_alloc_mut_type }; |
| 3486 | | |
| 3487 | 3499 | if (block.is_comptime or small.is_comptime) { |
| 3488 | 3500 | if (small.has_type) { |
| 3489 | 3501 | return sema.analyzeComptimeAlloc(block, var_ty, alignment); |
| 3490 | 3502 | } else { |
| 3491 | | const ty_inst = try sema.addType(inferred_alloc_ty); |
| 3492 | | try sema.air_values.append(gpa, try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{ |
| 3493 | | .decl_index = undefined, |
| 3494 | | .alignment = alignment, |
| 3495 | | })); |
| 3496 | 3503 | try sema.air_instructions.append(gpa, .{ |
| 3497 | 3504 | .tag = .inferred_alloc_comptime, |
| 3498 | | .data = .{ .ty_pl = .{ |
| 3499 | | .ty = ty_inst, |
| 3500 | | .payload = @intCast(u32, sema.air_values.items.len - 1), |
| 3505 | .data = .{ .inferred_alloc_comptime = .{ |
| 3506 | .decl_index = undefined, |
| 3507 | .alignment = InternPool.Alignment.fromByteUnits(alignment), |
| 3508 | .is_const = small.is_const, |
| 3501 | 3509 | } }, |
| 3502 | 3510 | }); |
| 3503 | 3511 | return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); |
| ... | ... | @@ -3518,18 +3526,14 @@ fn zirAllocExtended( |
| 3518 | 3526 | return block.addTy(.alloc, ptr_type); |
| 3519 | 3527 | } |
| 3520 | 3528 | |
| 3521 | | const ty_inst = try sema.addType(inferred_alloc_ty); |
| 3522 | | try sema.air_values.append(gpa, try Value.Tag.inferred_alloc.create(sema.arena, .{ |
| 3523 | | .alignment = alignment, |
| 3524 | | })); |
| 3525 | 3529 | const result_index = try block.addInstAsIndex(.{ |
| 3526 | 3530 | .tag = .inferred_alloc, |
| 3527 | | .data = .{ .ty_pl = .{ |
| 3528 | | .ty = ty_inst, |
| 3529 | | .payload = @intCast(u32, sema.air_values.items.len - 1), |
| 3531 | .data = .{ .inferred_alloc = .{ |
| 3532 | .alignment = InternPool.Alignment.fromByteUnits(alignment), |
| 3533 | .is_const = small.is_const, |
| 3530 | 3534 | } }, |
| 3531 | 3535 | }); |
| 3532 | | try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, {}); |
| 3536 | try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, .{}); |
| 3533 | 3537 | return Air.indexToRef(result_index); |
| 3534 | 3538 | } |
| 3535 | 3539 | |
| ... | ... | @@ -3623,23 +3627,19 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai |
| 3623 | 3627 | fn zirAllocInferredComptime( |
| 3624 | 3628 | sema: *Sema, |
| 3625 | 3629 | inst: Zir.Inst.Index, |
| 3626 | | inferred_alloc_ty: Type, |
| 3630 | is_const: bool, |
| 3627 | 3631 | ) CompileError!Air.Inst.Ref { |
| 3628 | 3632 | const gpa = sema.gpa; |
| 3629 | 3633 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 3630 | 3634 | const src = LazySrcLoc.nodeOffset(src_node); |
| 3631 | 3635 | sema.src = src; |
| 3632 | 3636 | |
| 3633 | | const ty_inst = try sema.addType(inferred_alloc_ty); |
| 3634 | | try sema.air_values.append(gpa, try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{ |
| 3635 | | .decl_index = undefined, |
| 3636 | | .alignment = 0, |
| 3637 | | })); |
| 3638 | 3637 | try sema.air_instructions.append(gpa, .{ |
| 3639 | 3638 | .tag = .inferred_alloc_comptime, |
| 3640 | | .data = .{ .ty_pl = .{ |
| 3641 | | .ty = ty_inst, |
| 3642 | | .payload = @intCast(u32, sema.air_values.items.len - 1), |
| 3639 | .data = .{ .inferred_alloc_comptime = .{ |
| 3640 | .decl_index = undefined, |
| 3641 | .alignment = .none, |
| 3642 | .is_const = is_const, |
| 3643 | 3643 | } }, |
| 3644 | 3644 | }); |
| 3645 | 3645 | return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); |
| ... | ... | @@ -3688,7 +3688,7 @@ fn zirAllocInferred( |
| 3688 | 3688 | sema: *Sema, |
| 3689 | 3689 | block: *Block, |
| 3690 | 3690 | inst: Zir.Inst.Index, |
| 3691 | | inferred_alloc_ty: Type, |
| 3691 | is_const: bool, |
| 3692 | 3692 | ) CompileError!Air.Inst.Ref { |
| 3693 | 3693 | const tracy = trace(@src()); |
| 3694 | 3694 | defer tracy.end(); |
| ... | ... | @@ -3698,33 +3698,26 @@ fn zirAllocInferred( |
| 3698 | 3698 | const src = LazySrcLoc.nodeOffset(src_node); |
| 3699 | 3699 | sema.src = src; |
| 3700 | 3700 | |
| 3701 | | const ty_inst = try sema.addType(inferred_alloc_ty); |
| 3702 | 3701 | if (block.is_comptime) { |
| 3703 | | try sema.air_values.append(gpa, try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{ |
| 3704 | | .decl_index = undefined, |
| 3705 | | .alignment = 0, |
| 3706 | | })); |
| 3707 | 3702 | try sema.air_instructions.append(gpa, .{ |
| 3708 | 3703 | .tag = .inferred_alloc_comptime, |
| 3709 | | .data = .{ .ty_pl = .{ |
| 3710 | | .ty = ty_inst, |
| 3711 | | .payload = @intCast(u32, sema.air_values.items.len - 1), |
| 3704 | .data = .{ .inferred_alloc_comptime = .{ |
| 3705 | .decl_index = undefined, |
| 3706 | .alignment = .none, |
| 3707 | .is_const = is_const, |
| 3712 | 3708 | } }, |
| 3713 | 3709 | }); |
| 3714 | 3710 | return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); |
| 3715 | 3711 | } |
| 3716 | 3712 | |
| 3717 | | try sema.air_values.append(gpa, try Value.Tag.inferred_alloc.create(sema.arena, .{ |
| 3718 | | .alignment = 0, |
| 3719 | | })); |
| 3720 | 3713 | const result_index = try block.addInstAsIndex(.{ |
| 3721 | 3714 | .tag = .inferred_alloc, |
| 3722 | | .data = .{ .ty_pl = .{ |
| 3723 | | .ty = ty_inst, |
| 3724 | | .payload = @intCast(u32, sema.air_values.items.len - 1), |
| 3715 | .data = .{ .inferred_alloc = .{ |
| 3716 | .alignment = .none, |
| 3717 | .is_const = is_const, |
| 3725 | 3718 | } }, |
| 3726 | 3719 | }); |
| 3727 | | try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, {}); |
| 3720 | try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, .{}); |
| 3728 | 3721 | return Air.indexToRef(result_index); |
| 3729 | 3722 | } |
| 3730 | 3723 | |
| ... | ... | @@ -3732,44 +3725,36 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3732 | 3725 | const tracy = trace(@src()); |
| 3733 | 3726 | defer tracy.end(); |
| 3734 | 3727 | |
| 3728 | const mod = sema.mod; |
| 3735 | 3729 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3736 | 3730 | const src = inst_data.src(); |
| 3737 | 3731 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 3738 | 3732 | const ptr = try sema.resolveInst(inst_data.operand); |
| 3739 | 3733 | const ptr_inst = Air.refToIndex(ptr).?; |
| 3740 | | const value_index = sema.air_instructions.items(.data)[ptr_inst].ty_pl.payload; |
| 3741 | | const ptr_val = sema.air_values.items[value_index]; |
| 3742 | | const var_is_mut = switch (sema.typeOf(ptr).toIntern()) { |
| 3743 | | .inferred_alloc_const_type => false, |
| 3744 | | .inferred_alloc_mut_type => true, |
| 3745 | | else => unreachable, |
| 3746 | | }; |
| 3747 | | const target = sema.mod.getTarget(); |
| 3734 | const target = mod.getTarget(); |
| 3748 | 3735 | |
| 3749 | 3736 | switch (sema.air_instructions.items(.tag)[ptr_inst]) { |
| 3750 | 3737 | .inferred_alloc_comptime => { |
| 3751 | | const iac = ptr_val.castTag(.inferred_alloc_comptime).?; |
| 3752 | | const decl_index = iac.data.decl_index; |
| 3753 | | try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index); |
| 3738 | const iac = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime; |
| 3739 | const decl_index = iac.decl_index; |
| 3740 | try mod.declareDeclDependency(sema.owner_decl_index, decl_index); |
| 3754 | 3741 | |
| 3755 | | const decl = sema.mod.declPtr(decl_index); |
| 3742 | const decl = mod.declPtr(decl_index); |
| 3756 | 3743 | const final_elem_ty = decl.ty; |
| 3757 | | const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 3758 | | .pointee_type = final_elem_ty, |
| 3759 | | .mutable = true, |
| 3760 | | .@"align" = iac.data.alignment, |
| 3761 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3744 | const final_ptr_ty = try mod.ptrType(.{ |
| 3745 | .elem_type = final_elem_ty.toIntern(), |
| 3746 | .is_const = false, |
| 3747 | .alignment = iac.alignment, |
| 3748 | .address_space = target_util.defaultAddressSpace(target, .local), |
| 3762 | 3749 | }); |
| 3763 | | const final_ptr_ty_inst = try sema.addType(final_ptr_ty); |
| 3764 | | sema.air_instructions.items(.data)[ptr_inst].ty_pl.ty = final_ptr_ty_inst; |
| 3765 | 3750 | |
| 3766 | 3751 | try sema.maybeQueueFuncBodyAnalysis(decl_index); |
| 3767 | 3752 | // Change it to an interned. |
| 3768 | 3753 | sema.air_instructions.set(ptr_inst, .{ |
| 3769 | 3754 | .tag = .interned, |
| 3770 | | .data = .{ .interned = try sema.mod.intern(.{ .ptr = .{ |
| 3755 | .data = .{ .interned = try mod.intern(.{ .ptr = .{ |
| 3771 | 3756 | .ty = final_ptr_ty.toIntern(), |
| 3772 | | .addr = if (var_is_mut) .{ .mut_decl = .{ |
| 3757 | .addr = if (!iac.is_const) .{ .mut_decl = .{ |
| 3773 | 3758 | .decl = decl_index, |
| 3774 | 3759 | .runtime_index = block.runtime_index, |
| 3775 | 3760 | } } else .{ .decl = decl_index }, |
| ... | ... | @@ -3777,19 +3762,18 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3777 | 3762 | }); |
| 3778 | 3763 | }, |
| 3779 | 3764 | .inferred_alloc => { |
| 3780 | | assert(sema.unresolved_inferred_allocs.remove(ptr_inst)); |
| 3781 | | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; |
| 3782 | | const peer_inst_list = inferred_alloc.data.prongs.items(.stored_inst); |
| 3765 | const ia1 = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc; |
| 3766 | const ia2 = sema.unresolved_inferred_allocs.fetchRemove(ptr_inst).?.value; |
| 3767 | const peer_inst_list = ia2.prongs.items(.stored_inst); |
| 3783 | 3768 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); |
| 3784 | 3769 | |
| 3785 | | const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 3786 | | .pointee_type = final_elem_ty, |
| 3787 | | .mutable = true, |
| 3788 | | .@"align" = inferred_alloc.data.alignment, |
| 3789 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3770 | const final_ptr_ty = try mod.ptrType(.{ |
| 3771 | .elem_type = final_elem_ty.toIntern(), |
| 3772 | .alignment = ia1.alignment, |
| 3773 | .address_space = target_util.defaultAddressSpace(target, .local), |
| 3790 | 3774 | }); |
| 3791 | 3775 | |
| 3792 | | if (var_is_mut) { |
| 3776 | if (!ia1.is_const) { |
| 3793 | 3777 | try sema.validateVarType(block, ty_src, final_elem_ty, false); |
| 3794 | 3778 | } else ct: { |
| 3795 | 3779 | // Detect if the value is comptime-known. In such case, the |
| ... | ... | @@ -3858,23 +3842,23 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3858 | 3842 | const new_decl_index = try anon_decl.finish( |
| 3859 | 3843 | final_elem_ty, |
| 3860 | 3844 | try store_val.copy(anon_decl.arena()), |
| 3861 | | inferred_alloc.data.alignment, |
| 3845 | ia1.alignment.toByteUnits(0), |
| 3862 | 3846 | ); |
| 3863 | 3847 | break :d new_decl_index; |
| 3864 | 3848 | }; |
| 3865 | | try sema.mod.declareDeclDependency(sema.owner_decl_index, new_decl_index); |
| 3849 | try mod.declareDeclDependency(sema.owner_decl_index, new_decl_index); |
| 3866 | 3850 | |
| 3867 | 3851 | // Even though we reuse the constant instruction, we still remove it from the |
| 3868 | 3852 | // block so that codegen does not see it. |
| 3869 | 3853 | block.instructions.shrinkRetainingCapacity(search_index); |
| 3870 | 3854 | try sema.maybeQueueFuncBodyAnalysis(new_decl_index); |
| 3871 | | sema.air_values.items[value_index] = (try sema.mod.intern(.{ .ptr = .{ |
| 3872 | | .ty = final_elem_ty.toIntern(), |
| 3873 | | .addr = .{ .decl = new_decl_index }, |
| 3874 | | } })).toValue(); |
| 3875 | | // if bitcast ty ref needs to be made const, make_ptr_const |
| 3876 | | // ZIR handles it later, so we can just use the ty ref here. |
| 3877 | | air_datas[ptr_inst].ty_pl.ty = air_datas[bitcast_inst].ty_op.ty; |
| 3855 | sema.air_instructions.set(ptr_inst, .{ |
| 3856 | .tag = .interned, |
| 3857 | .data = .{ .interned = try mod.intern(.{ .ptr = .{ |
| 3858 | .ty = final_elem_ty.toIntern(), |
| 3859 | .addr = .{ .decl = new_decl_index }, |
| 3860 | } }) }, |
| 3861 | }); |
| 3878 | 3862 | |
| 3879 | 3863 | // Unless the block is comptime, `alloc_inferred` always produces |
| 3880 | 3864 | // a runtime constant. The final inferred type needs to be |
| ... | ... | @@ -3895,18 +3879,17 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3895 | 3879 | // Now we need to go back over all the coerce_result_ptr instructions, which |
| 3896 | 3880 | // previously inserted a bitcast as a placeholder, and do the logic as if |
| 3897 | 3881 | // the new result ptr type was available. |
| 3898 | | const placeholders = inferred_alloc.data.prongs.items(.placeholder); |
| 3882 | const placeholders = ia2.prongs.items(.placeholder); |
| 3899 | 3883 | const gpa = sema.gpa; |
| 3900 | 3884 | |
| 3901 | 3885 | var trash_block = block.makeSubBlock(); |
| 3902 | 3886 | trash_block.is_comptime = false; |
| 3903 | 3887 | defer trash_block.instructions.deinit(gpa); |
| 3904 | 3888 | |
| 3905 | | const mut_final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 3906 | | .pointee_type = final_elem_ty, |
| 3907 | | .mutable = true, |
| 3908 | | .@"align" = inferred_alloc.data.alignment, |
| 3909 | | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3889 | const mut_final_ptr_ty = try mod.ptrType(.{ |
| 3890 | .elem_type = final_elem_ty.toIntern(), |
| 3891 | .alignment = ia1.alignment, |
| 3892 | .address_space = target_util.defaultAddressSpace(target, .local), |
| 3910 | 3893 | }); |
| 3911 | 3894 | const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); |
| 3912 | 3895 | const empty_trash_count = trash_block.instructions.items.len; |
| ... | ... | @@ -3914,7 +3897,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3914 | 3897 | for (peer_inst_list, placeholders) |peer_inst, placeholder_inst| { |
| 3915 | 3898 | const sub_ptr_ty = sema.typeOf(Air.indexToRef(placeholder_inst)); |
| 3916 | 3899 | |
| 3917 | | if (mut_final_ptr_ty.eql(sub_ptr_ty, sema.mod)) { |
| 3900 | if (mut_final_ptr_ty.eql(sub_ptr_ty, mod)) { |
| 3918 | 3901 | // New result location type is the same as the old one; nothing |
| 3919 | 3902 | // to do here. |
| 3920 | 3903 | continue; |
| ... | ... | @@ -5009,17 +4992,14 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 5009 | 4992 | const src: LazySrcLoc = sema.src; |
| 5010 | 4993 | blk: { |
| 5011 | 4994 | const ptr_inst = Air.refToIndex(ptr) orelse break :blk; |
| 5012 | | const air_data = sema.air_instructions.items(.data)[ptr_inst]; |
| 5013 | 4995 | switch (sema.air_instructions.items(.tag)[ptr_inst]) { |
| 5014 | 4996 | .inferred_alloc_comptime => { |
| 5015 | | const ptr_val = sema.air_values.items[air_data.ty_pl.payload]; |
| 5016 | | const iac = ptr_val.castTag(.inferred_alloc_comptime).?; |
| 4997 | const iac = &sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime; |
| 5017 | 4998 | return sema.storeToInferredAllocComptime(block, src, operand, iac); |
| 5018 | 4999 | }, |
| 5019 | 5000 | .inferred_alloc => { |
| 5020 | | const ptr_val = sema.air_values.items[air_data.ty_pl.payload]; |
| 5021 | | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; |
| 5022 | | return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); |
| 5001 | const ia = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?; |
| 5002 | return sema.storeToInferredAlloc(block, ptr, operand, ia); |
| 5023 | 5003 | }, |
| 5024 | 5004 | else => break :blk, |
| 5025 | 5005 | } |
| ... | ... | @@ -5038,16 +5018,15 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 5038 | 5018 | const operand = try sema.resolveInst(bin_inst.rhs); |
| 5039 | 5019 | const ptr_inst = Air.refToIndex(ptr).?; |
| 5040 | 5020 | const air_datas = sema.air_instructions.items(.data); |
| 5041 | | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; |
| 5042 | 5021 | |
| 5043 | 5022 | switch (sema.air_instructions.items(.tag)[ptr_inst]) { |
| 5044 | 5023 | .inferred_alloc_comptime => { |
| 5045 | | const iac = ptr_val.castTag(.inferred_alloc_comptime).?; |
| 5024 | const iac = &air_datas[ptr_inst].inferred_alloc_comptime; |
| 5046 | 5025 | return sema.storeToInferredAllocComptime(block, src, operand, iac); |
| 5047 | 5026 | }, |
| 5048 | 5027 | .inferred_alloc => { |
| 5049 | | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; |
| 5050 | | return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); |
| 5028 | const ia = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?; |
| 5029 | return sema.storeToInferredAlloc(block, ptr, operand, ia); |
| 5051 | 5030 | }, |
| 5052 | 5031 | else => unreachable, |
| 5053 | 5032 | } |
| ... | ... | @@ -5058,14 +5037,14 @@ fn storeToInferredAlloc( |
| 5058 | 5037 | block: *Block, |
| 5059 | 5038 | ptr: Air.Inst.Ref, |
| 5060 | 5039 | operand: Air.Inst.Ref, |
| 5061 | | inferred_alloc: *Value.Payload.InferredAlloc, |
| 5040 | inferred_alloc: *InferredAlloc, |
| 5062 | 5041 | ) CompileError!void { |
| 5063 | 5042 | // Create a store instruction as a placeholder. This will be replaced by a |
| 5064 | 5043 | // proper store sequence once we know the stored type. |
| 5065 | 5044 | const dummy_store = try block.addBinOp(.store, ptr, operand); |
| 5066 | 5045 | // Add the stored instruction to the set we will use to resolve peer types |
| 5067 | 5046 | // for the inferred allocation. |
| 5068 | | try inferred_alloc.data.prongs.append(sema.arena, .{ |
| 5047 | try inferred_alloc.prongs.append(sema.arena, .{ |
| 5069 | 5048 | .stored_inst = operand, |
| 5070 | 5049 | .placeholder = Air.refToIndex(dummy_store).?, |
| 5071 | 5050 | }); |
| ... | ... | @@ -5076,7 +5055,7 @@ fn storeToInferredAllocComptime( |
| 5076 | 5055 | block: *Block, |
| 5077 | 5056 | src: LazySrcLoc, |
| 5078 | 5057 | operand: Air.Inst.Ref, |
| 5079 | | iac: *Value.Payload.InferredAllocComptime, |
| 5058 | iac: *Air.Inst.Data.InferredAllocComptime, |
| 5080 | 5059 | ) CompileError!void { |
| 5081 | 5060 | const operand_ty = sema.typeOf(operand); |
| 5082 | 5061 | // There will be only one store_to_inferred_ptr because we are running at comptime. |
| ... | ... | @@ -5085,10 +5064,10 @@ fn storeToInferredAllocComptime( |
| 5085 | 5064 | if (operand_val.getVariable(sema.mod) != null) break :store; |
| 5086 | 5065 | var anon_decl = try block.startAnonDecl(); |
| 5087 | 5066 | defer anon_decl.deinit(); |
| 5088 | | iac.data.decl_index = try anon_decl.finish( |
| 5067 | iac.decl_index = try anon_decl.finish( |
| 5089 | 5068 | operand_ty, |
| 5090 | 5069 | try operand_val.copy(anon_decl.arena()), |
| 5091 | | iac.data.alignment, |
| 5070 | iac.alignment.toByteUnits(0), |
| 5092 | 5071 | ); |
| 5093 | 5072 | return; |
| 5094 | 5073 | } |
| ... | ... | @@ -27643,17 +27622,6 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 27643 | 27622 | const prev_ptr = air_datas[ptr_inst].ty_op.operand; |
| 27644 | 27623 | const prev_ptr_ty = sema.typeOf(prev_ptr); |
| 27645 | 27624 | if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null; |
| 27646 | | |
| 27647 | | // TODO: I noticed that the behavior tests do not pass if these two |
| 27648 | | // checks are missing. I don't understand why the presence of inferred |
| 27649 | | // allocations is relevant to this function, or why it would have |
| 27650 | | // different behavior depending on whether the types were inferred. |
| 27651 | | // Something seems wrong here. |
| 27652 | | switch (prev_ptr_ty.toIntern()) { |
| 27653 | | .inferred_alloc_mut_type, .inferred_alloc_const_type => return null, |
| 27654 | | else => {}, |
| 27655 | | } |
| 27656 | | |
| 27657 | 27625 | const prev_ptr_child_ty = prev_ptr_ty.childType(mod); |
| 27658 | 27626 | if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr; |
| 27659 | 27627 | ptr_inst = Air.refToIndex(prev_ptr) orelse return null; |
| ... | ... | @@ -31749,9 +31717,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 31749 | 31717 | .enum_literal, |
| 31750 | 31718 | .type_info, |
| 31751 | 31719 | => true, |
| 31752 | | |
| 31753 | | .inferred_alloc_const => unreachable, |
| 31754 | | .inferred_alloc_mut => unreachable, |
| 31755 | 31720 | }, |
| 31756 | 31721 | .struct_type => |struct_type| { |
| 31757 | 31722 | const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false; |
| ... | ... | @@ -32009,8 +31974,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { |
| 32009 | 31974 | .bool_false => unreachable, |
| 32010 | 31975 | .empty_struct => unreachable, |
| 32011 | 31976 | .generic_poison => unreachable, |
| 32012 | | .inferred_alloc_const_type => unreachable, |
| 32013 | | .inferred_alloc_mut_type => unreachable, |
| 32014 | 31977 | |
| 32015 | 31978 | .type_info_type => return sema.getBuiltinType("Type"), |
| 32016 | 31979 | .extern_options_type => return sema.getBuiltinType("ExternOptions"), |
| ... | ... | @@ -33201,8 +33164,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33201 | 33164 | .undefined => Value.undef, |
| 33202 | 33165 | |
| 33203 | 33166 | .generic_poison => return error.GenericPoison, |
| 33204 | | .inferred_alloc_const => unreachable, |
| 33205 | | .inferred_alloc_mut => unreachable, |
| 33206 | 33167 | }, |
| 33207 | 33168 | .struct_type => |struct_type| { |
| 33208 | 33169 | const resolved_ty = try sema.resolveTypeFields(ty); |
| ... | ... | @@ -33737,9 +33698,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 33737 | 33698 | .enum_literal, |
| 33738 | 33699 | .type_info, |
| 33739 | 33700 | => true, |
| 33740 | | |
| 33741 | | .inferred_alloc_const => unreachable, |
| 33742 | | .inferred_alloc_mut => unreachable, |
| 33743 | 33701 | }, |
| 33744 | 33702 | .struct_type => |struct_type| { |
| 33745 | 33703 | const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false; |
| ... | ... | @@ -34501,3 +34459,13 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type { |
| 34501 | 34459 | |
| 34502 | 34460 | return mod.errorSetFromUnsortedNames(names.keys()); |
| 34503 | 34461 | } |
| 34462 | |
| 34463 | /// Avoids crashing the compiler when asking if inferred allocations are noreturn. |
| 34464 | fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { |
| 34465 | if (ref == .noreturn_type) return true; |
| 34466 | if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) { |
| 34467 | .inferred_alloc, .inferred_alloc_comptime => return false, |
| 34468 | else => {}, |
| 34469 | }; |
| 34470 | return sema.typeOf(ref).isNoReturn(sema.mod); |
| 34471 | } |