authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-25 22:28:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
logf37c0a459382fa033cefc9bb139277436a78b25e
tree6860bcc6f0d95190cb68fb43fc7da6d593322b1c
parent5d0d5893fd39047e4fdbb6623e4d69babf0b2ed4

Sema: inferred allocations no longer abuse type/value system

Previously, there were types and values for inferred allocations and a lot of special-case handling. Now, instead, the special casing is limited to AIR instructions for these use cases. Instead of storing data in Value payloads, the data is now stored in AIR instruction data as well as the previously `void` value type of the `unresolved_inferred_allocs` hash map.

7 files changed, 160 insertions(+), 264 deletions(-)

src/Air.zig+26-10
...@@ -186,13 +186,17 @@ pub const Inst = struct {...@@ -186,13 +186,17 @@ pub const Inst = struct {
186 /// Allocates stack local memory.186 /// Allocates stack local memory.
187 /// Uses the `ty` field.187 /// Uses the `ty` field.
188 alloc,188 alloc,
189 /// This is a special value that tracks a set of types that have been stored189 /// This special instruction only exists temporarily during semantic
190 /// to an inferred allocation. It does not support any of the normal value queries.190 /// analysis and is guaranteed to be unreachable in machine code
191 /// Uses the `ty_pl` field, payload is an index of `values` array.191 /// backends. It tracks a set of types that have been stored to an
192 /// inferred allocation.
193 /// Uses the `inferred_alloc` field.
192 inferred_alloc,194 inferred_alloc,
193 /// Used to coordinate alloc_inferred, store_to_inferred_ptr, and resolve_inferred_alloc195 /// This special instruction only exists temporarily during semantic
194 /// instructions for comptime code.196 /// analysis and is guaranteed to be unreachable in machine code
195 /// Uses the `ty_pl` field, payload is an index of `values` array.197 /// backends. Used to coordinate alloc_inferred, store_to_inferred_ptr,
198 /// and resolve_inferred_alloc instructions for comptime code.
199 /// Uses the `inferred_alloc_comptime` field.
196 inferred_alloc_comptime,200 inferred_alloc_comptime,
197 /// If the function will pass the result by-ref, this instruction returns the201 /// If the function will pass the result by-ref, this instruction returns the
198 /// result pointer. Otherwise it is equivalent to `alloc`.202 /// result pointer. Otherwise it is equivalent to `alloc`.
...@@ -908,8 +912,6 @@ pub const Inst = struct {...@@ -908,8 +912,6 @@ pub const Inst = struct {
908 slice_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.slice_const_u8_sentinel_0_type),912 slice_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.slice_const_u8_sentinel_0_type),
909 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),913 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
910 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),914 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
911 inferred_alloc_const_type = @enumToInt(InternPool.Index.inferred_alloc_const_type),
912 inferred_alloc_mut_type = @enumToInt(InternPool.Index.inferred_alloc_mut_type),
913 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),915 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
914 undef = @enumToInt(InternPool.Index.undef),916 undef = @enumToInt(InternPool.Index.undef),
915 zero = @enumToInt(InternPool.Index.zero),917 zero = @enumToInt(InternPool.Index.zero),
...@@ -997,6 +999,19 @@ pub const Inst = struct {...@@ -997,6 +999,19 @@ pub const Inst = struct {
997 // Index into a different array.999 // Index into a different array.
998 payload: u32,1000 payload: u32,
999 },1001 },
1002 inferred_alloc_comptime: InferredAllocComptime,
1003 inferred_alloc: InferredAlloc,
1004
1005 pub const InferredAllocComptime = struct {
1006 decl_index: Module.Decl.Index,
1007 alignment: InternPool.Alignment,
1008 is_const: bool,
1009 };
1010
1011 pub const InferredAlloc = struct {
1012 alignment: InternPool.Alignment,
1013 is_const: bool,
1014 };
10001015
1001 // Make sure we don't accidentally add a field to make this union1016 // Make sure we don't accidentally add a field to make this union
1002 // bigger than expected. Note that in Debug builds, Zig is allowed1017 // bigger than expected. Note that in Debug builds, Zig is allowed
...@@ -1287,8 +1302,6 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {...@@ -1287,8 +1302,6 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
1287 .sub_with_overflow,1302 .sub_with_overflow,
1288 .mul_with_overflow,1303 .mul_with_overflow,
1289 .shl_with_overflow,1304 .shl_with_overflow,
1290 .inferred_alloc,
1291 .inferred_alloc_comptime,
1292 .ptr_add,1305 .ptr_add,
1293 .ptr_sub,1306 .ptr_sub,
1294 .try_ptr,1307 .try_ptr,
...@@ -1424,6 +1437,9 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {...@@ -1424,6 +1437,9 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
1424 .work_group_size,1437 .work_group_size,
1425 .work_group_id,1438 .work_group_id,
1426 => return Type.u32,1439 => return Type.u32,
1440
1441 .inferred_alloc => unreachable,
1442 .inferred_alloc_comptime => unreachable,
1427 }1443 }
1428}1444}
14291445
src/InternPool.zig-12
...@@ -1156,8 +1156,6 @@ pub const Index = enum(u32) {...@@ -1156,8 +1156,6 @@ pub const Index = enum(u32) {
1156 slice_const_u8_sentinel_0_type,1156 slice_const_u8_sentinel_0_type,
1157 anyerror_void_error_union_type,1157 anyerror_void_error_union_type,
1158 generic_poison_type,1158 generic_poison_type,
1159 inferred_alloc_const_type,
1160 inferred_alloc_mut_type,
1161 /// `@TypeOf(.{})`1159 /// `@TypeOf(.{})`
1162 empty_struct_type,1160 empty_struct_type,
11631161
...@@ -1525,10 +1523,6 @@ pub const static_keys = [_]Key{...@@ -1525,10 +1523,6 @@ pub const static_keys = [_]Key{
15251523
1526 // generic_poison_type1524 // generic_poison_type
1527 .{ .simple_type = .generic_poison },1525 .{ .simple_type = .generic_poison },
1528 // inferred_alloc_const_type
1529 .{ .simple_type = .inferred_alloc_const },
1530 // inferred_alloc_mut_type
1531 .{ .simple_type = .inferred_alloc_mut },
15321526
1533 // empty_struct_type1527 // empty_struct_type
1534 .{ .anon_struct_type = .{1528 .{ .anon_struct_type = .{
...@@ -1958,12 +1952,6 @@ pub const SimpleType = enum(u32) {...@@ -1958,12 +1952,6 @@ pub const SimpleType = enum(u32) {
1958 type_info,1952 type_info,
19591953
1960 generic_poison,1954 generic_poison,
1961 /// TODO: remove this from `SimpleType`; instead make it only a special `Index` tag like
1962 /// `var_args_param_type`.
1963 inferred_alloc_const,
1964 /// TODO: remove this from `SimpleType`; instead make it only a special `Index` tag like
1965 /// `var_args_param_type`.
1966 inferred_alloc_mut,
1967};1955};
19681956
1969pub const SimpleValue = enum(u32) {1957pub const SimpleValue = enum(u32) {
src/Sema.zig+128-160
...@@ -89,7 +89,9 @@ is_generic_instantiation: bool = false,...@@ -89,7 +89,9 @@ is_generic_instantiation: bool = false,
89/// function types will emit generic poison instead of a partial type.89/// function types will emit generic poison instead of a partial type.
90no_partial_func_ty: bool = false,90no_partial_func_ty: bool = false,
9191
92unresolved_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.
94unresolved_inferred_allocs: std.AutoHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{},
9395
94const std = @import("std");96const std = @import("std");
95const math = std.math;97const math = std.math;
...@@ -718,7 +720,7 @@ pub const Block = struct {...@@ -718,7 +720,7 @@ pub const Block = struct {
718 }720 }
719721
720 /// `alignment` value of 0 means to use ABI alignment.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 const sema = wad.block.sema;724 const sema = wad.block.sema;
723 // Do this ahead of time because `createAnonymousDecl` depends on calling725 // Do this ahead of time because `createAnonymousDecl` depends on calling
724 // `type.hasRuntimeBits()`.726 // `type.hasRuntimeBits()`.
...@@ -728,7 +730,8 @@ pub const Block = struct {...@@ -728,7 +730,8 @@ pub const Block = struct {
728 .val = val,730 .val = val,
729 });731 });
730 const new_decl = sema.mod.declPtr(new_decl_index);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 errdefer sema.mod.abortAnonDecl(new_decl_index);735 errdefer sema.mod.abortAnonDecl(new_decl_index);
733 try new_decl.finalizeNewArena(&wad.new_decl_arena);736 try new_decl.finalizeNewArena(&wad.new_decl_arena);
734 wad.finished = true;737 wad.finished = true;
...@@ -748,6 +751,23 @@ const LabeledBlock = struct {...@@ -748,6 +751,23 @@ const LabeledBlock = struct {
748 }751 }
749};752};
750753
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`.
758const 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
751pub fn deinit(sema: *Sema) void {771pub fn deinit(sema: *Sema) void {
752 const gpa = sema.gpa;772 const gpa = sema.gpa;
753 sema.air_instructions.deinit(gpa);773 sema.air_instructions.deinit(gpa);
...@@ -909,10 +929,10 @@ fn analyzeBodyInner(...@@ -909,10 +929,10 @@ fn analyzeBodyInner(
909 const air_inst: Air.Inst.Ref = switch (tags[inst]) {929 const air_inst: Air.Inst.Ref = switch (tags[inst]) {
910 // zig fmt: off930 // zig fmt: off
911 .alloc => try sema.zirAlloc(block, inst),931 .alloc => try sema.zirAlloc(block, inst),
912 .alloc_inferred => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_const_type }),932 .alloc_inferred => try sema.zirAllocInferred(block, inst, true),
913 .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_mut_type }),933 .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, false),
914 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_const_type }),934 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, true),
915 .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_mut_type }),935 .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, false),
916 .alloc_mut => try sema.zirAllocMut(block, inst),936 .alloc_mut => try sema.zirAllocMut(block, inst),
917 .alloc_comptime_mut => try sema.zirAllocComptime(block, inst),937 .alloc_comptime_mut => try sema.zirAllocComptime(block, inst),
918 .make_ptr_const => try sema.zirMakePtrConst(block, inst),938 .make_ptr_const => try sema.zirMakePtrConst(block, inst),
...@@ -1707,7 +1727,7 @@ fn analyzeBodyInner(...@@ -1707,7 +1727,7 @@ fn analyzeBodyInner(
1707 break :blk Air.Inst.Ref.void_value;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 break always_noreturn;1731 break always_noreturn;
1712 map.putAssumeCapacity(inst, air_inst);1732 map.putAssumeCapacity(inst, air_inst);
1713 i += 1;1733 i += 1;
...@@ -1751,8 +1771,6 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {...@@ -1751,8 +1771,6 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
1751 // The last section of indexes refers to the map of ZIR => AIR.1771 // The last section of indexes refers to the map of ZIR => AIR.
1752 const inst = sema.inst_map.get(i - InternPool.static_len).?;1772 const inst = sema.inst_map.get(i - InternPool.static_len).?;
1753 if (inst == .generic_poison) return error.GenericPoison;1773 if (inst == .generic_poison) return error.GenericPoison;
1754 const ty = sema.typeOf(inst);
1755 assert(!ty.isGenericPoison());
1756 return inst;1774 return inst;
1757}1775}
17581776
...@@ -2431,20 +2449,20 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2431,20 +2449,20 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2431 const tracy = trace(@src());2449 const tracy = trace(@src());
2432 defer tracy.end();2450 defer tracy.end();
24332451
2452 const mod = sema.mod;
2434 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2453 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2435 const src = inst_data.src();2454 const src = inst_data.src();
2436 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;2455 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2437 const pointee_ty = try sema.resolveType(block, src, extra.lhs);2456 const pointee_ty = try sema.resolveType(block, src, extra.lhs);
2438 const ptr = try sema.resolveInst(extra.rhs);2457 const ptr = try sema.resolveInst(extra.rhs);
2439 const target = sema.mod.getTarget();2458 const target = mod.getTarget();
2440 const addr_space = target_util.defaultAddressSpace(target, .local);2459 const addr_space = target_util.defaultAddressSpace(target, .local);
24412460
2442 if (Air.refToIndex(ptr)) |ptr_inst| {2461 if (Air.refToIndex(ptr)) |ptr_inst| {
2443 switch (sema.air_instructions.items(.tag)[ptr_inst]) {2462 switch (sema.air_instructions.items(.tag)[ptr_inst]) {
2444 .inferred_alloc => {2463 .inferred_alloc => {
2445 const air_datas = sema.air_instructions.items(.data);2464 const ia1 = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc;
2446 const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];2465 const ia2 = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?;
2447 const inferred_alloc = &ptr_val.castTag(.inferred_alloc).?.data;
2448 // Add the stored instruction to the set we will use to resolve peer types2466 // Add the stored instruction to the set we will use to resolve peer types
2449 // for the inferred allocation.2467 // for the inferred allocation.
2450 // This instruction will not make it to codegen; it is only to participate2468 // 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,14 +2471,14 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2453 defer trash_block.instructions.deinit(sema.gpa);2471 defer trash_block.instructions.deinit(sema.gpa);
2454 const operand = try trash_block.addBitCast(pointee_ty, .void_value);2472 const operand = try trash_block.addBitCast(pointee_ty, .void_value);
24552473
2456 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{2474 const ptr_ty = try mod.ptrType(.{
2457 .pointee_type = pointee_ty,2475 .elem_type = pointee_ty.toIntern(),
2458 .@"align" = inferred_alloc.alignment,2476 .alignment = ia1.alignment,
2459 .@"addrspace" = addr_space,2477 .address_space = addr_space,
2460 });2478 });
2461 const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr);2479 const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr);
24622480
2463 try inferred_alloc.prongs.append(sema.arena, .{2481 try ia2.prongs.append(sema.arena, .{
2464 .stored_inst = operand,2482 .stored_inst = operand,
2465 .placeholder = Air.refToIndex(bitcasted_ptr).?,2483 .placeholder = Air.refToIndex(bitcasted_ptr).?,
2466 });2484 });
...@@ -2468,31 +2486,30 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2468,31 +2486,30 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2468 return bitcasted_ptr;2486 return bitcasted_ptr;
2469 },2487 },
2470 .inferred_alloc_comptime => {2488 .inferred_alloc_comptime => {
2471 const air_datas = sema.air_instructions.items(.data);2489 const alignment = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime.alignment;
2472 const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];
2473 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;
2474 // There will be only one coerce_result_ptr because we are running at comptime.2490 // There will be only one coerce_result_ptr because we are running at comptime.
2475 // The alloc will turn into a Decl.2491 // The alloc will turn into a Decl.
2476 var anon_decl = try block.startAnonDecl();2492 var anon_decl = try block.startAnonDecl();
2477 defer anon_decl.deinit();2493 defer anon_decl.deinit();
2478 iac.data.decl_index = try anon_decl.finish(2494 const decl_index = try anon_decl.finish(
2479 pointee_ty,2495 pointee_ty,
2480 Value.undef,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 try sema.resolveTypeLayout(pointee_ty);2501 try sema.resolveTypeLayout(pointee_ty);
2485 }2502 }
2486 const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{2503 const ptr_ty = try mod.ptrType(.{
2487 .pointee_type = pointee_ty,2504 .elem_type = pointee_ty.toIntern(),
2488 .@"align" = iac.data.alignment,2505 .alignment = alignment,
2489 .@"addrspace" = addr_space,2506 .address_space = addr_space,
2490 });2507 });
2491 try sema.maybeQueueFuncBodyAnalysis(iac.data.decl_index);2508 try sema.maybeQueueFuncBodyAnalysis(decl_index);
2492 return sema.addConstant(ptr_ty, (try sema.mod.intern(.{ .ptr = .{2509 return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{
2493 .ty = ptr_ty.toIntern(),2510 .ty = ptr_ty.toIntern(),
2494 .addr = .{ .mut_decl = .{2511 .addr = .{ .mut_decl = .{
2495 .decl = iac.data.decl_index,2512 .decl = decl_index,
2496 .runtime_index = block.runtime_index,2513 .runtime_index = block.runtime_index,
2497 } },2514 } },
2498 } })).toValue());2515 } })).toValue());
...@@ -3479,25 +3496,16 @@ fn zirAllocExtended(...@@ -3479,25 +3496,16 @@ fn zirAllocExtended(
3479 break :blk alignment;3496 break :blk alignment;
3480 } else 0;3497 } else 0;
34813498
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 if (block.is_comptime or small.is_comptime) {3499 if (block.is_comptime or small.is_comptime) {
3488 if (small.has_type) {3500 if (small.has_type) {
3489 return sema.analyzeComptimeAlloc(block, var_ty, alignment);3501 return sema.analyzeComptimeAlloc(block, var_ty, alignment);
3490 } else {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 try sema.air_instructions.append(gpa, .{3503 try sema.air_instructions.append(gpa, .{
3497 .tag = .inferred_alloc_comptime,3504 .tag = .inferred_alloc_comptime,
3498 .data = .{ .ty_pl = .{3505 .data = .{ .inferred_alloc_comptime = .{
3499 .ty = ty_inst,3506 .decl_index = undefined,
3500 .payload = @intCast(u32, sema.air_values.items.len - 1),3507 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3508 .is_const = small.is_const,
3501 } },3509 } },
3502 });3510 });
3503 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));3511 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
...@@ -3518,18 +3526,14 @@ fn zirAllocExtended(...@@ -3518,18 +3526,14 @@ fn zirAllocExtended(
3518 return block.addTy(.alloc, ptr_type);3526 return block.addTy(.alloc, ptr_type);
3519 }3527 }
35203528
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 const result_index = try block.addInstAsIndex(.{3529 const result_index = try block.addInstAsIndex(.{
3526 .tag = .inferred_alloc,3530 .tag = .inferred_alloc,
3527 .data = .{ .ty_pl = .{3531 .data = .{ .inferred_alloc = .{
3528 .ty = ty_inst,3532 .alignment = InternPool.Alignment.fromByteUnits(alignment),
3529 .payload = @intCast(u32, sema.air_values.items.len - 1),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 return Air.indexToRef(result_index);3537 return Air.indexToRef(result_index);
3534}3538}
35353539
...@@ -3623,23 +3627,19 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai...@@ -3623,23 +3627,19 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
3623fn zirAllocInferredComptime(3627fn zirAllocInferredComptime(
3624 sema: *Sema,3628 sema: *Sema,
3625 inst: Zir.Inst.Index,3629 inst: Zir.Inst.Index,
3626 inferred_alloc_ty: Type,3630 is_const: bool,
3627) CompileError!Air.Inst.Ref {3631) CompileError!Air.Inst.Ref {
3628 const gpa = sema.gpa;3632 const gpa = sema.gpa;
3629 const src_node = sema.code.instructions.items(.data)[inst].node;3633 const src_node = sema.code.instructions.items(.data)[inst].node;
3630 const src = LazySrcLoc.nodeOffset(src_node);3634 const src = LazySrcLoc.nodeOffset(src_node);
3631 sema.src = src;3635 sema.src = src;
36323636
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 try sema.air_instructions.append(gpa, .{3637 try sema.air_instructions.append(gpa, .{
3639 .tag = .inferred_alloc_comptime,3638 .tag = .inferred_alloc_comptime,
3640 .data = .{ .ty_pl = .{3639 .data = .{ .inferred_alloc_comptime = .{
3641 .ty = ty_inst,3640 .decl_index = undefined,
3642 .payload = @intCast(u32, sema.air_values.items.len - 1),3641 .alignment = .none,
3642 .is_const = is_const,
3643 } },3643 } },
3644 });3644 });
3645 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));3645 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
...@@ -3688,7 +3688,7 @@ fn zirAllocInferred(...@@ -3688,7 +3688,7 @@ fn zirAllocInferred(
3688 sema: *Sema,3688 sema: *Sema,
3689 block: *Block,3689 block: *Block,
3690 inst: Zir.Inst.Index,3690 inst: Zir.Inst.Index,
3691 inferred_alloc_ty: Type,3691 is_const: bool,
3692) CompileError!Air.Inst.Ref {3692) CompileError!Air.Inst.Ref {
3693 const tracy = trace(@src());3693 const tracy = trace(@src());
3694 defer tracy.end();3694 defer tracy.end();
...@@ -3698,33 +3698,26 @@ fn zirAllocInferred(...@@ -3698,33 +3698,26 @@ fn zirAllocInferred(
3698 const src = LazySrcLoc.nodeOffset(src_node);3698 const src = LazySrcLoc.nodeOffset(src_node);
3699 sema.src = src;3699 sema.src = src;
37003700
3701 const ty_inst = try sema.addType(inferred_alloc_ty);
3702 if (block.is_comptime) {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 try sema.air_instructions.append(gpa, .{3702 try sema.air_instructions.append(gpa, .{
3708 .tag = .inferred_alloc_comptime,3703 .tag = .inferred_alloc_comptime,
3709 .data = .{ .ty_pl = .{3704 .data = .{ .inferred_alloc_comptime = .{
3710 .ty = ty_inst,3705 .decl_index = undefined,
3711 .payload = @intCast(u32, sema.air_values.items.len - 1),3706 .alignment = .none,
3707 .is_const = is_const,
3712 } },3708 } },
3713 });3709 });
3714 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));3710 return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1));
3715 }3711 }
37163712
3717 try sema.air_values.append(gpa, try Value.Tag.inferred_alloc.create(sema.arena, .{
3718 .alignment = 0,
3719 }));
3720 const result_index = try block.addInstAsIndex(.{3713 const result_index = try block.addInstAsIndex(.{
3721 .tag = .inferred_alloc,3714 .tag = .inferred_alloc,
3722 .data = .{ .ty_pl = .{3715 .data = .{ .inferred_alloc = .{
3723 .ty = ty_inst,3716 .alignment = .none,
3724 .payload = @intCast(u32, sema.air_values.items.len - 1),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 return Air.indexToRef(result_index);3721 return Air.indexToRef(result_index);
3729}3722}
37303723
...@@ -3732,44 +3725,36 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3732,44 +3725,36 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3732 const tracy = trace(@src());3725 const tracy = trace(@src());
3733 defer tracy.end();3726 defer tracy.end();
37343727
3728 const mod = sema.mod;
3735 const inst_data = sema.code.instructions.items(.data)[inst].un_node;3729 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
3736 const src = inst_data.src();3730 const src = inst_data.src();
3737 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };3731 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
3738 const ptr = try sema.resolveInst(inst_data.operand);3732 const ptr = try sema.resolveInst(inst_data.operand);
3739 const ptr_inst = Air.refToIndex(ptr).?;3733 const ptr_inst = Air.refToIndex(ptr).?;
3740 const value_index = sema.air_instructions.items(.data)[ptr_inst].ty_pl.payload;3734 const target = mod.getTarget();
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();
37483735
3749 switch (sema.air_instructions.items(.tag)[ptr_inst]) {3736 switch (sema.air_instructions.items(.tag)[ptr_inst]) {
3750 .inferred_alloc_comptime => {3737 .inferred_alloc_comptime => {
3751 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;3738 const iac = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime;
3752 const decl_index = iac.data.decl_index;3739 const decl_index = iac.decl_index;
3753 try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);3740 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
37543741
3755 const decl = sema.mod.declPtr(decl_index);3742 const decl = mod.declPtr(decl_index);
3756 const final_elem_ty = decl.ty;3743 const final_elem_ty = decl.ty;
3757 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{3744 const final_ptr_ty = try mod.ptrType(.{
3758 .pointee_type = final_elem_ty,3745 .elem_type = final_elem_ty.toIntern(),
3759 .mutable = true,3746 .is_const = false,
3760 .@"align" = iac.data.alignment,3747 .alignment = iac.alignment,
3761 .@"addrspace" = target_util.defaultAddressSpace(target, .local),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;
37653750
3766 try sema.maybeQueueFuncBodyAnalysis(decl_index);3751 try sema.maybeQueueFuncBodyAnalysis(decl_index);
3767 // Change it to an interned.3752 // Change it to an interned.
3768 sema.air_instructions.set(ptr_inst, .{3753 sema.air_instructions.set(ptr_inst, .{
3769 .tag = .interned,3754 .tag = .interned,
3770 .data = .{ .interned = try sema.mod.intern(.{ .ptr = .{3755 .data = .{ .interned = try mod.intern(.{ .ptr = .{
3771 .ty = final_ptr_ty.toIntern(),3756 .ty = final_ptr_ty.toIntern(),
3772 .addr = if (var_is_mut) .{ .mut_decl = .{3757 .addr = if (!iac.is_const) .{ .mut_decl = .{
3773 .decl = decl_index,3758 .decl = decl_index,
3774 .runtime_index = block.runtime_index,3759 .runtime_index = block.runtime_index,
3775 } } else .{ .decl = decl_index },3760 } } else .{ .decl = decl_index },
...@@ -3777,19 +3762,18 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3777,19 +3762,18 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3777 });3762 });
3778 },3763 },
3779 .inferred_alloc => {3764 .inferred_alloc => {
3780 assert(sema.unresolved_inferred_allocs.remove(ptr_inst));3765 const ia1 = sema.air_instructions.items(.data)[ptr_inst].inferred_alloc;
3781 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;3766 const ia2 = sema.unresolved_inferred_allocs.fetchRemove(ptr_inst).?.value;
3782 const peer_inst_list = inferred_alloc.data.prongs.items(.stored_inst);3767 const peer_inst_list = ia2.prongs.items(.stored_inst);
3783 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none);3768 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none);
37843769
3785 const final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{3770 const final_ptr_ty = try mod.ptrType(.{
3786 .pointee_type = final_elem_ty,3771 .elem_type = final_elem_ty.toIntern(),
3787 .mutable = true,3772 .alignment = ia1.alignment,
3788 .@"align" = inferred_alloc.data.alignment,3773 .address_space = target_util.defaultAddressSpace(target, .local),
3789 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3790 });3774 });
37913775
3792 if (var_is_mut) {3776 if (!ia1.is_const) {
3793 try sema.validateVarType(block, ty_src, final_elem_ty, false);3777 try sema.validateVarType(block, ty_src, final_elem_ty, false);
3794 } else ct: {3778 } else ct: {
3795 // Detect if the value is comptime-known. In such case, the3779 // 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,23 +3842,23 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3858 const new_decl_index = try anon_decl.finish(3842 const new_decl_index = try anon_decl.finish(
3859 final_elem_ty,3843 final_elem_ty,
3860 try store_val.copy(anon_decl.arena()),3844 try store_val.copy(anon_decl.arena()),
3861 inferred_alloc.data.alignment,3845 ia1.alignment.toByteUnits(0),
3862 );3846 );
3863 break :d new_decl_index;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);
38663850
3867 // Even though we reuse the constant instruction, we still remove it from the3851 // Even though we reuse the constant instruction, we still remove it from the
3868 // block so that codegen does not see it.3852 // block so that codegen does not see it.
3869 block.instructions.shrinkRetainingCapacity(search_index);3853 block.instructions.shrinkRetainingCapacity(search_index);
3870 try sema.maybeQueueFuncBodyAnalysis(new_decl_index);3854 try sema.maybeQueueFuncBodyAnalysis(new_decl_index);
3871 sema.air_values.items[value_index] = (try sema.mod.intern(.{ .ptr = .{3855 sema.air_instructions.set(ptr_inst, .{
3872 .ty = final_elem_ty.toIntern(),3856 .tag = .interned,
3873 .addr = .{ .decl = new_decl_index },3857 .data = .{ .interned = try mod.intern(.{ .ptr = .{
3874 } })).toValue();3858 .ty = final_elem_ty.toIntern(),
3875 // if bitcast ty ref needs to be made const, make_ptr_const3859 .addr = .{ .decl = new_decl_index },
3876 // ZIR handles it later, so we can just use the ty ref here.3860 } }) },
3877 air_datas[ptr_inst].ty_pl.ty = air_datas[bitcast_inst].ty_op.ty;3861 });
38783862
3879 // Unless the block is comptime, `alloc_inferred` always produces3863 // Unless the block is comptime, `alloc_inferred` always produces
3880 // a runtime constant. The final inferred type needs to be3864 // 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,18 +3879,17 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3895 // Now we need to go back over all the coerce_result_ptr instructions, which3879 // Now we need to go back over all the coerce_result_ptr instructions, which
3896 // previously inserted a bitcast as a placeholder, and do the logic as if3880 // previously inserted a bitcast as a placeholder, and do the logic as if
3897 // the new result ptr type was available.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 const gpa = sema.gpa;3883 const gpa = sema.gpa;
39003884
3901 var trash_block = block.makeSubBlock();3885 var trash_block = block.makeSubBlock();
3902 trash_block.is_comptime = false;3886 trash_block.is_comptime = false;
3903 defer trash_block.instructions.deinit(gpa);3887 defer trash_block.instructions.deinit(gpa);
39043888
3905 const mut_final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{3889 const mut_final_ptr_ty = try mod.ptrType(.{
3906 .pointee_type = final_elem_ty,3890 .elem_type = final_elem_ty.toIntern(),
3907 .mutable = true,3891 .alignment = ia1.alignment,
3908 .@"align" = inferred_alloc.data.alignment,3892 .address_space = target_util.defaultAddressSpace(target, .local),
3909 .@"addrspace" = target_util.defaultAddressSpace(target, .local),
3910 });3893 });
3911 const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty);3894 const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty);
3912 const empty_trash_count = trash_block.instructions.items.len;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,7 +3897,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3914 for (peer_inst_list, placeholders) |peer_inst, placeholder_inst| {3897 for (peer_inst_list, placeholders) |peer_inst, placeholder_inst| {
3915 const sub_ptr_ty = sema.typeOf(Air.indexToRef(placeholder_inst));3898 const sub_ptr_ty = sema.typeOf(Air.indexToRef(placeholder_inst));
39163899
3917 if (mut_final_ptr_ty.eql(sub_ptr_ty, sema.mod)) {3900 if (mut_final_ptr_ty.eql(sub_ptr_ty, mod)) {
3918 // New result location type is the same as the old one; nothing3901 // New result location type is the same as the old one; nothing
3919 // to do here.3902 // to do here.
3920 continue;3903 continue;
...@@ -5009,17 +4992,14 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -5009,17 +4992,14 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
5009 const src: LazySrcLoc = sema.src;4992 const src: LazySrcLoc = sema.src;
5010 blk: {4993 blk: {
5011 const ptr_inst = Air.refToIndex(ptr) orelse break :blk;4994 const ptr_inst = Air.refToIndex(ptr) orelse break :blk;
5012 const air_data = sema.air_instructions.items(.data)[ptr_inst];
5013 switch (sema.air_instructions.items(.tag)[ptr_inst]) {4995 switch (sema.air_instructions.items(.tag)[ptr_inst]) {
5014 .inferred_alloc_comptime => {4996 .inferred_alloc_comptime => {
5015 const ptr_val = sema.air_values.items[air_data.ty_pl.payload];4997 const iac = &sema.air_instructions.items(.data)[ptr_inst].inferred_alloc_comptime;
5016 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;
5017 return sema.storeToInferredAllocComptime(block, src, operand, iac);4998 return sema.storeToInferredAllocComptime(block, src, operand, iac);
5018 },4999 },
5019 .inferred_alloc => {5000 .inferred_alloc => {
5020 const ptr_val = sema.air_values.items[air_data.ty_pl.payload];5001 const ia = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?;
5021 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;5002 return sema.storeToInferredAlloc(block, ptr, operand, ia);
5022 return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc);
5023 },5003 },
5024 else => break :blk,5004 else => break :blk,
5025 }5005 }
...@@ -5038,16 +5018,15 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi...@@ -5038,16 +5018,15 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
5038 const operand = try sema.resolveInst(bin_inst.rhs);5018 const operand = try sema.resolveInst(bin_inst.rhs);
5039 const ptr_inst = Air.refToIndex(ptr).?;5019 const ptr_inst = Air.refToIndex(ptr).?;
5040 const air_datas = sema.air_instructions.items(.data);5020 const air_datas = sema.air_instructions.items(.data);
5041 const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];
50425021
5043 switch (sema.air_instructions.items(.tag)[ptr_inst]) {5022 switch (sema.air_instructions.items(.tag)[ptr_inst]) {
5044 .inferred_alloc_comptime => {5023 .inferred_alloc_comptime => {
5045 const iac = ptr_val.castTag(.inferred_alloc_comptime).?;5024 const iac = &air_datas[ptr_inst].inferred_alloc_comptime;
5046 return sema.storeToInferredAllocComptime(block, src, operand, iac);5025 return sema.storeToInferredAllocComptime(block, src, operand, iac);
5047 },5026 },
5048 .inferred_alloc => {5027 .inferred_alloc => {
5049 const inferred_alloc = ptr_val.castTag(.inferred_alloc).?;5028 const ia = sema.unresolved_inferred_allocs.getPtr(ptr_inst).?;
5050 return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc);5029 return sema.storeToInferredAlloc(block, ptr, operand, ia);
5051 },5030 },
5052 else => unreachable,5031 else => unreachable,
5053 }5032 }
...@@ -5058,14 +5037,14 @@ fn storeToInferredAlloc(...@@ -5058,14 +5037,14 @@ fn storeToInferredAlloc(
5058 block: *Block,5037 block: *Block,
5059 ptr: Air.Inst.Ref,5038 ptr: Air.Inst.Ref,
5060 operand: Air.Inst.Ref,5039 operand: Air.Inst.Ref,
5061 inferred_alloc: *Value.Payload.InferredAlloc,5040 inferred_alloc: *InferredAlloc,
5062) CompileError!void {5041) CompileError!void {
5063 // Create a store instruction as a placeholder. This will be replaced by a5042 // Create a store instruction as a placeholder. This will be replaced by a
5064 // proper store sequence once we know the stored type.5043 // proper store sequence once we know the stored type.
5065 const dummy_store = try block.addBinOp(.store, ptr, operand);5044 const dummy_store = try block.addBinOp(.store, ptr, operand);
5066 // Add the stored instruction to the set we will use to resolve peer types5045 // Add the stored instruction to the set we will use to resolve peer types
5067 // for the inferred allocation.5046 // for the inferred allocation.
5068 try inferred_alloc.data.prongs.append(sema.arena, .{5047 try inferred_alloc.prongs.append(sema.arena, .{
5069 .stored_inst = operand,5048 .stored_inst = operand,
5070 .placeholder = Air.refToIndex(dummy_store).?,5049 .placeholder = Air.refToIndex(dummy_store).?,
5071 });5050 });
...@@ -5076,7 +5055,7 @@ fn storeToInferredAllocComptime(...@@ -5076,7 +5055,7 @@ fn storeToInferredAllocComptime(
5076 block: *Block,5055 block: *Block,
5077 src: LazySrcLoc,5056 src: LazySrcLoc,
5078 operand: Air.Inst.Ref,5057 operand: Air.Inst.Ref,
5079 iac: *Value.Payload.InferredAllocComptime,5058 iac: *Air.Inst.Data.InferredAllocComptime,
5080) CompileError!void {5059) CompileError!void {
5081 const operand_ty = sema.typeOf(operand);5060 const operand_ty = sema.typeOf(operand);
5082 // There will be only one store_to_inferred_ptr because we are running at comptime.5061 // There will be only one store_to_inferred_ptr because we are running at comptime.
...@@ -5085,10 +5064,10 @@ fn storeToInferredAllocComptime(...@@ -5085,10 +5064,10 @@ fn storeToInferredAllocComptime(
5085 if (operand_val.getVariable(sema.mod) != null) break :store;5064 if (operand_val.getVariable(sema.mod) != null) break :store;
5086 var anon_decl = try block.startAnonDecl();5065 var anon_decl = try block.startAnonDecl();
5087 defer anon_decl.deinit();5066 defer anon_decl.deinit();
5088 iac.data.decl_index = try anon_decl.finish(5067 iac.decl_index = try anon_decl.finish(
5089 operand_ty,5068 operand_ty,
5090 try operand_val.copy(anon_decl.arena()),5069 try operand_val.copy(anon_decl.arena()),
5091 iac.data.alignment,5070 iac.alignment.toByteUnits(0),
5092 );5071 );
5093 return;5072 return;
5094 }5073 }
...@@ -27643,17 +27622,6 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {...@@ -27643,17 +27622,6 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
27643 const prev_ptr = air_datas[ptr_inst].ty_op.operand;27622 const prev_ptr = air_datas[ptr_inst].ty_op.operand;
27644 const prev_ptr_ty = sema.typeOf(prev_ptr);27623 const prev_ptr_ty = sema.typeOf(prev_ptr);
27645 if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null;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 const prev_ptr_child_ty = prev_ptr_ty.childType(mod);27625 const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
27658 if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;27626 if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
27659 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;27627 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
...@@ -31749,9 +31717,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -31749,9 +31717,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
31749 .enum_literal,31717 .enum_literal,
31750 .type_info,31718 .type_info,
31751 => true,31719 => true,
31752
31753 .inferred_alloc_const => unreachable,
31754 .inferred_alloc_mut => unreachable,
31755 },31720 },
31756 .struct_type => |struct_type| {31721 .struct_type => |struct_type| {
31757 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false;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,8 +31974,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
32009 .bool_false => unreachable,31974 .bool_false => unreachable,
32010 .empty_struct => unreachable,31975 .empty_struct => unreachable,
32011 .generic_poison => unreachable,31976 .generic_poison => unreachable,
32012 .inferred_alloc_const_type => unreachable,
32013 .inferred_alloc_mut_type => unreachable,
3201431977
32015 .type_info_type => return sema.getBuiltinType("Type"),31978 .type_info_type => return sema.getBuiltinType("Type"),
32016 .extern_options_type => return sema.getBuiltinType("ExternOptions"),31979 .extern_options_type => return sema.getBuiltinType("ExternOptions"),
...@@ -33201,8 +33164,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33201,8 +33164,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33201 .undefined => Value.undef,33164 .undefined => Value.undef,
3320233165
33203 .generic_poison => return error.GenericPoison,33166 .generic_poison => return error.GenericPoison,
33204 .inferred_alloc_const => unreachable,
33205 .inferred_alloc_mut => unreachable,
33206 },33167 },
33207 .struct_type => |struct_type| {33168 .struct_type => |struct_type| {
33208 const resolved_ty = try sema.resolveTypeFields(ty);33169 const resolved_ty = try sema.resolveTypeFields(ty);
...@@ -33737,9 +33698,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -33737,9 +33698,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
33737 .enum_literal,33698 .enum_literal,
33738 .type_info,33699 .type_info,
33739 => true,33700 => true,
33740
33741 .inferred_alloc_const => unreachable,
33742 .inferred_alloc_mut => unreachable,
33743 },33701 },
33744 .struct_type => |struct_type| {33702 .struct_type => |struct_type| {
33745 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false;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,3 +34459,13 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
3450134459
34502 return mod.errorSetFromUnsortedNames(names.keys());34460 return mod.errorSetFromUnsortedNames(names.keys());
34503}34461}
34462
34463/// Avoids crashing the compiler when asking if inferred allocations are noreturn.
34464fn 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}
src/TypedValue.zig-3
...@@ -178,9 +178,6 @@ pub fn print(...@@ -178,9 +178,6 @@ pub fn print(
178 ty = ty.optionalChild(mod);178 ty = ty.optionalChild(mod);
179 return print(.{ .ty = ty, .val = val }, writer, level, mod);179 return print(.{ .ty = ty, .val = val }, writer, level, mod);
180 },180 },
181 // TODO these should not appear in this function
182 .inferred_alloc => return writer.writeAll("(inferred allocation value)"),
183 .inferred_alloc_comptime => return writer.writeAll("(inferred comptime allocation value)"),
184 },181 },
185 else => {182 else => {
186 const key = mod.intern_pool.indexToKey(val.ip_index);183 const key = mod.intern_pool.indexToKey(val.ip_index);
src/Zir.zig-2
...@@ -2112,8 +2112,6 @@ pub const Inst = struct {...@@ -2112,8 +2112,6 @@ pub const Inst = struct {
2112 slice_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.slice_const_u8_sentinel_0_type),2112 slice_const_u8_sentinel_0_type = @enumToInt(InternPool.Index.slice_const_u8_sentinel_0_type),
2113 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),2113 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
2114 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),2114 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
2115 inferred_alloc_const_type = @enumToInt(InternPool.Index.inferred_alloc_const_type),
2116 inferred_alloc_mut_type = @enumToInt(InternPool.Index.inferred_alloc_mut_type),
2117 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),2115 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
2118 undef = @enumToInt(InternPool.Index.undef),2116 undef = @enumToInt(InternPool.Index.undef),
2119 zero = @enumToInt(InternPool.Index.zero),2117 zero = @enumToInt(InternPool.Index.zero),
src/type.zig+6-30
...@@ -88,8 +88,6 @@ pub const Type = struct {...@@ -88,8 +88,6 @@ pub const Type = struct {
88 .type_info => .Union,88 .type_info => .Union,
8989
90 .generic_poison => return error.GenericPoison,90 .generic_poison => return error.GenericPoison,
91
92 .inferred_alloc_const, .inferred_alloc_mut => return .Pointer,
93 },91 },
9492
95 // values, not types93 // values, not types
...@@ -620,8 +618,6 @@ pub const Type = struct {...@@ -620,8 +618,6 @@ pub const Type = struct {
620 => false,618 => false,
621619
622 .generic_poison => unreachable,620 .generic_poison => unreachable,
623 .inferred_alloc_const => unreachable,
624 .inferred_alloc_mut => unreachable,
625 },621 },
626 .struct_type => |struct_type| {622 .struct_type => |struct_type| {
627 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {623 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
...@@ -777,9 +773,6 @@ pub const Type = struct {...@@ -777,9 +773,6 @@ pub const Type = struct {
777 .type_info,773 .type_info,
778 .generic_poison,774 .generic_poison,
779 => false,775 => false,
780
781 .inferred_alloc_const => unreachable,
782 .inferred_alloc_mut => unreachable,
783 },776 },
784 .struct_type => |struct_type| {777 .struct_type => |struct_type| {
785 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {778 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
...@@ -1028,8 +1021,6 @@ pub const Type = struct {...@@ -1028,8 +1021,6 @@ pub const Type = struct {
10281021
1029 .noreturn => unreachable,1022 .noreturn => unreachable,
1030 .generic_poison => unreachable,1023 .generic_poison => unreachable,
1031 .inferred_alloc_const => unreachable,
1032 .inferred_alloc_mut => unreachable,
1033 },1024 },
1034 .struct_type => |struct_type| {1025 .struct_type => |struct_type| {
1035 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse1026 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse
...@@ -1488,8 +1479,6 @@ pub const Type = struct {...@@ -1488,8 +1479,6 @@ pub const Type = struct {
1488 .type_info => unreachable,1479 .type_info => unreachable,
1489 .noreturn => unreachable,1480 .noreturn => unreachable,
1490 .generic_poison => unreachable,1481 .generic_poison => unreachable,
1491 .inferred_alloc_const => unreachable,
1492 .inferred_alloc_mut => unreachable,
1493 },1482 },
1494 .struct_type => |struct_type| switch (ty.containerLayout(mod)) {1483 .struct_type => |struct_type| switch (ty.containerLayout(mod)) {
1495 .Packed => {1484 .Packed => {
...@@ -1732,8 +1721,6 @@ pub const Type = struct {...@@ -1732,8 +1721,6 @@ pub const Type = struct {
1732 .undefined => unreachable,1721 .undefined => unreachable,
1733 .enum_literal => unreachable,1722 .enum_literal => unreachable,
1734 .generic_poison => unreachable,1723 .generic_poison => unreachable,
1735 .inferred_alloc_const => unreachable,
1736 .inferred_alloc_mut => unreachable,
17371724
1738 .atomic_order => unreachable, // missing call to resolveTypeFields1725 .atomic_order => unreachable, // missing call to resolveTypeFields
1739 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields1726 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
...@@ -1833,12 +1820,9 @@ pub const Type = struct {...@@ -1833,12 +1820,9 @@ pub const Type = struct {
1833 }1820 }
18341821
1835 pub fn isSinglePointer(ty: Type, mod: *const Module) bool {1822 pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
1836 return switch (ty.ip_index) {1823 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1837 .inferred_alloc_const_type, .inferred_alloc_mut_type => true,1824 .ptr_type => |ptr_info| ptr_info.size == .One,
1838 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1825 else => false,
1839 .ptr_type => |ptr_info| ptr_info.size == .One,
1840 else => false,
1841 },
1842 };1826 };
1843 }1827 }
18441828
...@@ -1849,12 +1833,9 @@ pub const Type = struct {...@@ -1849,12 +1833,9 @@ pub const Type = struct {
18491833
1850 /// Returns `null` if `ty` is not a pointer.1834 /// Returns `null` if `ty` is not a pointer.
1851 pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size {1835 pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size {
1852 return switch (ty.ip_index) {1836 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1853 .inferred_alloc_const_type, .inferred_alloc_mut_type => .One,1837 .ptr_type => |ptr_info| ptr_info.size,
1854 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {1838 else => null,
1855 .ptr_type => |ptr_info| ptr_info.size,
1856 else => null,
1857 },
1858 };1839 };
1859 }1840 }
18601841
...@@ -2612,8 +2593,6 @@ pub const Type = struct {...@@ -2612,8 +2593,6 @@ pub const Type = struct {
2612 .undefined => return Value.undef,2593 .undefined => return Value.undef,
26132594
2614 .generic_poison => unreachable,2595 .generic_poison => unreachable,
2615 .inferred_alloc_const => unreachable,
2616 .inferred_alloc_mut => unreachable,
2617 },2596 },
2618 .struct_type => |struct_type| {2597 .struct_type => |struct_type| {
2619 if (mod.structPtrUnwrap(struct_type.index)) |s| {2598 if (mod.structPtrUnwrap(struct_type.index)) |s| {
...@@ -2799,9 +2778,6 @@ pub const Type = struct {...@@ -2799,9 +2778,6 @@ pub const Type = struct {
2799 .enum_literal,2778 .enum_literal,
2800 .type_info,2779 .type_info,
2801 => true,2780 => true,
2802
2803 .inferred_alloc_const => unreachable,
2804 .inferred_alloc_mut => unreachable,
2805 },2781 },
2806 .struct_type => |struct_type| {2782 .struct_type => |struct_type| {
2807 // A struct with no fields is not comptime-only.2783 // A struct with no fields is not comptime-only.
src/value.zig-47
...@@ -63,12 +63,6 @@ pub const Value = struct {...@@ -63,12 +63,6 @@ pub const Value = struct {
63 aggregate,63 aggregate,
64 /// An instance of a union.64 /// An instance of a union.
65 @"union",65 @"union",
66 /// This is a special value that tracks a set of types that have been stored
67 /// to an inferred allocation. It does not support any of the normal value queries.
68 inferred_alloc,
69 /// Used to coordinate alloc_inferred, store_to_inferred_ptr, and resolve_inferred_alloc
70 /// instructions for comptime code.
71 inferred_alloc_comptime,
7266
73 pub const no_payload_count = 0;67 pub const no_payload_count = 0;
7468
...@@ -82,8 +76,6 @@ pub const Value = struct {...@@ -82,8 +76,6 @@ pub const Value = struct {
82 .bytes => Payload.Bytes,76 .bytes => Payload.Bytes,
83 .aggregate => Payload.Aggregate,77 .aggregate => Payload.Aggregate,
84 .@"union" => Payload.Union,78 .@"union" => Payload.Union,
85 .inferred_alloc => Payload.InferredAlloc,
86 .inferred_alloc_comptime => Payload.InferredAllocComptime,
87 };79 };
88 }80 }
8981
...@@ -250,8 +242,6 @@ pub const Value = struct {...@@ -250,8 +242,6 @@ pub const Value = struct {
250 .legacy = .{ .ptr_otherwise = &new_payload.base },242 .legacy = .{ .ptr_otherwise = &new_payload.base },
251 };243 };
252 },244 },
253 .inferred_alloc => unreachable,
254 .inferred_alloc_comptime => unreachable,
255 }245 }
256 }246 }
257247
...@@ -308,8 +298,6 @@ pub const Value = struct {...@@ -308,8 +298,6 @@ pub const Value = struct {
308 val = val.castTag(.repeated).?.data;298 val = val.castTag(.repeated).?.data;
309 },299 },
310 .slice => return out_stream.writeAll("(slice)"),300 .slice => return out_stream.writeAll("(slice)"),
311 .inferred_alloc => return out_stream.writeAll("(inferred allocation value)"),
312 .inferred_alloc_comptime => return out_stream.writeAll("(inferred comptime allocation value)"),
313 };301 };
314 }302 }
315303
...@@ -4147,41 +4135,6 @@ pub const Value = struct {...@@ -4147,41 +4135,6 @@ pub const Value = struct {
4147 val: Value,4135 val: Value,
4148 };4136 };
4149 };4137 };
4150
4151 pub const InferredAlloc = struct {
4152 pub const base_tag = Tag.inferred_alloc;
4153
4154 base: Payload = .{ .tag = base_tag },
4155 data: struct {
4156 /// The value stored in the inferred allocation. This will go into
4157 /// peer type resolution. This is stored in a separate list so that
4158 /// the items are contiguous in memory and thus can be passed to
4159 /// `Module.resolvePeerTypes`.
4160 prongs: std.MultiArrayList(struct {
4161 /// The dummy instruction used as a peer to resolve the type.
4162 /// Although this has a redundant type with placeholder, this is
4163 /// needed in addition because it may be a constant value, which
4164 /// affects peer type resolution.
4165 stored_inst: Air.Inst.Ref,
4166 /// The bitcast instruction used as a placeholder when the
4167 /// new result pointer type is not yet known.
4168 placeholder: Air.Inst.Index,
4169 }) = .{},
4170 /// 0 means ABI-aligned.
4171 alignment: u32,
4172 },
4173 };
4174
4175 pub const InferredAllocComptime = struct {
4176 pub const base_tag = Tag.inferred_alloc_comptime;
4177
4178 base: Payload = .{ .tag = base_tag },
4179 data: struct {
4180 decl_index: Module.Decl.Index,
4181 /// 0 means ABI-aligned.
4182 alignment: u32,
4183 },
4184 };
4185 };4138 };
41864139
4187 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;4140 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;