| ... | @@ -154,9 +154,6 @@ pub fn analyzeBody( | ... | @@ -154,9 +154,6 @@ pub fn analyzeBody( |
| 154 | // We use a while(true) loop here to avoid a redundant way of breaking out of | 154 | // We use a while(true) loop here to avoid a redundant way of breaking out of |
| 155 | // the loop. The only way to break out of the loop is with a `noreturn` | 155 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 156 | // instruction. | 156 | // instruction. |
| 157 | // TODO: As an optimization, make sure the codegen for these switch prongs | | |
| 158 | // directly jump to the next one, rather than detouring through the loop | | |
| 159 | // continue expression. Related: https://github.com/ziglang/zig/issues/8220 | | |
| 160 | var i: usize = 0; | 157 | var i: usize = 0; |
| 161 | while (true) { | 158 | while (true) { |
| 162 | const inst = body[i]; | 159 | const inst = body[i]; |
| ... | @@ -391,7 +388,7 @@ pub fn analyzeBody( | ... | @@ -391,7 +388,7 @@ pub fn analyzeBody( |
| 391 | .condbr => return sema.zirCondbr(block, inst), | 388 | .condbr => return sema.zirCondbr(block, inst), |
| 392 | .@"break" => return sema.zirBreak(block, inst), | 389 | .@"break" => return sema.zirBreak(block, inst), |
| 393 | .compile_error => return sema.zirCompileError(block, inst), | 390 | .compile_error => return sema.zirCompileError(block, inst), |
| 394 | .ret_coerce => return sema.zirRetCoerce(block, inst, true), | 391 | .ret_coerce => return sema.zirRetCoerce(block, inst), |
| 395 | .ret_node => return sema.zirRetNode(block, inst), | 392 | .ret_node => return sema.zirRetNode(block, inst), |
| 396 | .ret_err_value => return sema.zirRetErrValue(block, inst), | 393 | .ret_err_value => return sema.zirRetErrValue(block, inst), |
| 397 | .@"unreachable" => return sema.zirUnreachable(block, inst), | 394 | .@"unreachable" => return sema.zirUnreachable(block, inst), |
| ... | @@ -1396,14 +1393,19 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp | ... | @@ -1396,14 +1393,19 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp |
| 1396 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); | 1393 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| 1397 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); | 1394 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| 1398 | | 1395 | |
| 1399 | const val_payload = try sema.arena.create(Value.Payload.ComptimeAlloc); | 1396 | var anon_decl = try block.startAnonDecl(); |
| 1400 | val_payload.* = .{ | 1397 | defer anon_decl.deinit(); |
| 1401 | .data = .{ | 1398 | const decl = try anon_decl.finish( |
| 1402 | .runtime_index = block.runtime_index, | 1399 | try var_type.copy(anon_decl.arena()), |
| 1403 | .val = undefined, // astgen guarantees there will be a store before the first load | 1400 | // AstGen guarantees there will be a store before the first load, so we put a value |
| 1404 | }, | 1401 | // here indicating there is no valid value. |
| 1405 | }; | 1402 | Value.initTag(.unreachable_value), |
| 1406 | return sema.addConstant(ptr_type, Value.initPayload(&val_payload.base)); | 1403 | ); |
| | 1404 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); |
| | 1405 | return sema.addConstant(ptr_type, try Value.Tag.decl_ref_mut.create(sema.arena, .{ |
| | 1406 | .runtime_index = block.runtime_index, |
| | 1407 | .decl = decl, |
| | 1408 | })); |
| 1407 | } | 1409 | } |
| 1408 | | 1410 | |
| 1409 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1411 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -1450,16 +1452,23 @@ fn zirAllocInferred( | ... | @@ -1450,16 +1452,23 @@ fn zirAllocInferred( |
| 1450 | | 1452 | |
| 1451 | const src_node = sema.code.instructions.items(.data)[inst].node; | 1453 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 1452 | const src: LazySrcLoc = .{ .node_offset = src_node }; | 1454 | const src: LazySrcLoc = .{ .node_offset = src_node }; |
| | 1455 | sema.src = src; |
| 1453 | | 1456 | |
| 1454 | const val_payload = try sema.arena.create(Value.Payload.InferredAlloc); | 1457 | if (block.is_comptime) { |
| 1455 | val_payload.* = .{ | 1458 | return sema.addConstant( |
| 1456 | .data = .{}, | 1459 | inferred_alloc_ty, |
| 1457 | }; | 1460 | try Value.Tag.inferred_alloc_comptime.create(sema.arena, undefined), |
| 1458 | // `Module.constInst` does not add the instruction to the block because it is | 1461 | ); |
| | 1462 | } |
| | 1463 | |
| | 1464 | // `Sema.addConstant` does not add the instruction to the block because it is |
| 1459 | // not needed in the case of constant values. However here, we plan to "downgrade" | 1465 | // not needed in the case of constant values. However here, we plan to "downgrade" |
| 1460 | // to a normal instruction when we hit `resolve_inferred_alloc`. So we append | 1466 | // to a normal instruction when we hit `resolve_inferred_alloc`. So we append |
| 1461 | // to the block even though it is currently a `.constant`. | 1467 | // to the block even though it is currently a `.constant`. |
| 1462 | const result = try sema.addConstant(inferred_alloc_ty, Value.initPayload(&val_payload.base)); | 1468 | const result = try sema.addConstant( |
| | 1469 | inferred_alloc_ty, |
| | 1470 | try Value.Tag.inferred_alloc.create(sema.arena, .{}), |
| | 1471 | ); |
| 1463 | try sema.requireFunctionBlock(block, src); | 1472 | try sema.requireFunctionBlock(block, src); |
| 1464 | try block.instructions.append(sema.gpa, Air.refToIndex(result).?); | 1473 | try block.instructions.append(sema.gpa, Air.refToIndex(result).?); |
| 1465 | return result; | 1474 | return result; |
| ... | @@ -1475,25 +1484,47 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde | ... | @@ -1475,25 +1484,47 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1475 | const ptr_inst = Air.refToIndex(ptr).?; | 1484 | const ptr_inst = Air.refToIndex(ptr).?; |
| 1476 | assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant); | 1485 | assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant); |
| 1477 | const air_datas = sema.air_instructions.items(.data); | 1486 | const air_datas = sema.air_instructions.items(.data); |
| 1478 | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; | 1487 | const value_index = air_datas[ptr_inst].ty_pl.payload; |
| 1479 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; | 1488 | const ptr_val = sema.air_values.items[value_index]; |
| 1480 | const peer_inst_list = inferred_alloc.data.stored_inst_list.items; | | |
| 1481 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list); | | |
| 1482 | const var_is_mut = switch (sema.typeOf(ptr).tag()) { | 1489 | const var_is_mut = switch (sema.typeOf(ptr).tag()) { |
| 1483 | .inferred_alloc_const => false, | 1490 | .inferred_alloc_const => false, |
| 1484 | .inferred_alloc_mut => true, | 1491 | .inferred_alloc_mut => true, |
| 1485 | else => unreachable, | 1492 | else => unreachable, |
| 1486 | }; | 1493 | }; |
| 1487 | if (var_is_mut) { | 1494 | |
| 1488 | try sema.validateVarType(block, ty_src, final_elem_ty); | 1495 | if (ptr_val.castTag(.inferred_alloc_comptime)) |iac| { |
| | 1496 | const decl = iac.data; |
| | 1497 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); |
| | 1498 | |
| | 1499 | const final_elem_ty = try decl.ty.copy(sema.arena); |
| | 1500 | const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One); |
| | 1501 | air_datas[ptr_inst].ty_pl.ty = try sema.addType(final_ptr_ty); |
| | 1502 | |
| | 1503 | if (var_is_mut) { |
| | 1504 | sema.air_values.items[value_index] = try Value.Tag.decl_ref_mut.create(sema.arena, .{ |
| | 1505 | .decl = decl, |
| | 1506 | .runtime_index = block.runtime_index, |
| | 1507 | }); |
| | 1508 | } else { |
| | 1509 | sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, decl); |
| | 1510 | } |
| | 1511 | return; |
| 1489 | } | 1512 | } |
| 1490 | const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One); | | |
| 1491 | | 1513 | |
| 1492 | // Change it to a normal alloc. | 1514 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { |
| 1493 | sema.air_instructions.set(ptr_inst, .{ | 1515 | const peer_inst_list = inferred_alloc.data.stored_inst_list.items; |
| 1494 | .tag = .alloc, | 1516 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list); |
| 1495 | .data = .{ .ty = final_ptr_ty }, | 1517 | if (var_is_mut) { |
| 1496 | }); | 1518 | try sema.validateVarType(block, ty_src, final_elem_ty); |
| | 1519 | } |
| | 1520 | // Change it to a normal alloc. |
| | 1521 | const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One); |
| | 1522 | sema.air_instructions.set(ptr_inst, .{ |
| | 1523 | .tag = .alloc, |
| | 1524 | .data = .{ .ty = final_ptr_ty }, |
| | 1525 | }); |
| | 1526 | return; |
| | 1527 | } |
| 1497 | } | 1528 | } |
| 1498 | | 1529 | |
| 1499 | fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { | 1530 | fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -1654,23 +1685,45 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) | ... | @@ -1654,23 +1685,45 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) |
| 1654 | const tracy = trace(@src()); | 1685 | const tracy = trace(@src()); |
| 1655 | defer tracy.end(); | 1686 | defer tracy.end(); |
| 1656 | | 1687 | |
| 1657 | const src: LazySrcLoc = .unneeded; | 1688 | const src: LazySrcLoc = sema.src; |
| 1658 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 1689 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; |
| 1659 | const ptr = sema.resolveInst(bin_inst.lhs); | 1690 | const ptr = sema.resolveInst(bin_inst.lhs); |
| 1660 | const value = sema.resolveInst(bin_inst.rhs); | 1691 | const operand = sema.resolveInst(bin_inst.rhs); |
| | 1692 | const operand_ty = sema.typeOf(operand); |
| 1661 | const ptr_inst = Air.refToIndex(ptr).?; | 1693 | const ptr_inst = Air.refToIndex(ptr).?; |
| 1662 | assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant); | 1694 | assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant); |
| 1663 | const air_datas = sema.air_instructions.items(.data); | 1695 | const air_datas = sema.air_instructions.items(.data); |
| 1664 | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; | 1696 | const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload]; |
| 1665 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; | 1697 | |
| 1666 | // Add the stored instruction to the set we will use to resolve peer types | 1698 | if (ptr_val.castTag(.inferred_alloc_comptime)) |iac| { |
| 1667 | // for the inferred allocation. | 1699 | // There will be only one store_to_inferred_ptr because we are running at comptime. |
| 1668 | try inferred_alloc.data.stored_inst_list.append(sema.arena, value); | 1700 | // The alloc will turn into a Decl. |
| 1669 | // Create a runtime bitcast instruction with exactly the type the pointer wants. | 1701 | if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| { |
| 1670 | const ptr_ty = try Module.simplePtrType(sema.arena, sema.typeOf(value), true, .One); | 1702 | if (operand_val.tag() == .variable) { |
| 1671 | try sema.requireRuntimeBlock(block, src); | 1703 | return sema.failWithNeededComptime(block, src); |
| 1672 | const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr); | 1704 | } |
| 1673 | return sema.storePtr(block, src, bitcasted_ptr, value); | 1705 | var anon_decl = try block.startAnonDecl(); |
| | 1706 | defer anon_decl.deinit(); |
| | 1707 | iac.data = try anon_decl.finish( |
| | 1708 | try operand_ty.copy(anon_decl.arena()), |
| | 1709 | try operand_val.copy(anon_decl.arena()), |
| | 1710 | ); |
| | 1711 | return; |
| | 1712 | } else { |
| | 1713 | return sema.failWithNeededComptime(block, src); |
| | 1714 | } |
| | 1715 | } |
| | 1716 | |
| | 1717 | if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| { |
| | 1718 | // Add the stored instruction to the set we will use to resolve peer types |
| | 1719 | // for the inferred allocation. |
| | 1720 | try inferred_alloc.data.stored_inst_list.append(sema.arena, operand); |
| | 1721 | // Create a runtime bitcast instruction with exactly the type the pointer wants. |
| | 1722 | const ptr_ty = try Module.simplePtrType(sema.arena, operand_ty, true, .One); |
| | 1723 | const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr); |
| | 1724 | return sema.storePtr(block, src, bitcasted_ptr, operand); |
| | 1725 | } |
| | 1726 | unreachable; |
| 1674 | } | 1727 | } |
| 1675 | | 1728 | |
| 1676 | fn zirSetEvalBranchQuota(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { | 1729 | fn zirSetEvalBranchQuota(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -5643,7 +5696,6 @@ fn zirRetCoerce( | ... | @@ -5643,7 +5696,6 @@ fn zirRetCoerce( |
| 5643 | sema: *Sema, | 5696 | sema: *Sema, |
| 5644 | block: *Scope.Block, | 5697 | block: *Scope.Block, |
| 5645 | inst: Zir.Inst.Index, | 5698 | inst: Zir.Inst.Index, |
| 5646 | need_coercion: bool, | | |
| 5647 | ) CompileError!Zir.Inst.Index { | 5699 | ) CompileError!Zir.Inst.Index { |
| 5648 | const tracy = trace(@src()); | 5700 | const tracy = trace(@src()); |
| 5649 | defer tracy.end(); | 5701 | defer tracy.end(); |
| ... | @@ -5652,7 +5704,7 @@ fn zirRetCoerce( | ... | @@ -5652,7 +5704,7 @@ fn zirRetCoerce( |
| 5652 | const operand = sema.resolveInst(inst_data.operand); | 5704 | const operand = sema.resolveInst(inst_data.operand); |
| 5653 | const src = inst_data.src(); | 5705 | const src = inst_data.src(); |
| 5654 | | 5706 | |
| 5655 | return sema.analyzeRet(block, operand, src, need_coercion); | 5707 | return sema.analyzeRet(block, operand, src, true); |
| 5656 | } | 5708 | } |
| 5657 | | 5709 | |
| 5658 | fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | 5710 | fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | @@ -5673,23 +5725,20 @@ fn analyzeRet( | ... | @@ -5673,23 +5725,20 @@ fn analyzeRet( |
| 5673 | src: LazySrcLoc, | 5725 | src: LazySrcLoc, |
| 5674 | need_coercion: bool, | 5726 | need_coercion: bool, |
| 5675 | ) CompileError!Zir.Inst.Index { | 5727 | ) CompileError!Zir.Inst.Index { |
| | 5728 | const casted_operand = if (!need_coercion) operand else op: { |
| | 5729 | const func = sema.func.?; |
| | 5730 | const fn_ty = func.owner_decl.ty; |
| | 5731 | const fn_ret_ty = fn_ty.fnReturnType(); |
| | 5732 | break :op try sema.coerce(block, fn_ret_ty, operand, src); |
| | 5733 | }; |
| 5676 | if (block.inlining) |inlining| { | 5734 | if (block.inlining) |inlining| { |
| 5677 | // We are inlining a function call; rewrite the `ret` as a `break`. | 5735 | // We are inlining a function call; rewrite the `ret` as a `break`. |
| 5678 | try inlining.merges.results.append(sema.gpa, operand); | 5736 | try inlining.merges.results.append(sema.gpa, casted_operand); |
| 5679 | _ = try block.addBr(inlining.merges.block_inst, operand); | 5737 | _ = try block.addBr(inlining.merges.block_inst, casted_operand); |
| 5680 | return always_noreturn; | 5738 | return always_noreturn; |
| 5681 | } | 5739 | } |
| 5682 | | 5740 | |
| 5683 | if (need_coercion) { | 5741 | _ = try block.addUnOp(.ret, casted_operand); |
| 5684 | if (sema.func) |func| { | | |
| 5685 | const fn_ty = func.owner_decl.ty; | | |
| 5686 | const fn_ret_ty = fn_ty.fnReturnType(); | | |
| 5687 | const casted_operand = try sema.coerce(block, fn_ret_ty, operand, src); | | |
| 5688 | _ = try block.addUnOp(.ret, casted_operand); | | |
| 5689 | return always_noreturn; | | |
| 5690 | } | | |
| 5691 | } | | |
| 5692 | _ = try block.addUnOp(.ret, operand); | | |
| 5693 | return always_noreturn; | 5742 | return always_noreturn; |
| 5694 | } | 5743 | } |
| 5695 | | 5744 | |
| ... | @@ -7603,37 +7652,45 @@ fn storePtr( | ... | @@ -7603,37 +7652,45 @@ fn storePtr( |
| 7603 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) | 7652 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) |
| 7604 | return; | 7653 | return; |
| 7605 | | 7654 | |
| 7606 | if (try sema.resolveMaybeUndefVal(block, src, ptr)) |ptr_val| blk: { | 7655 | if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| { |
| 7607 | const const_val = (try sema.resolveMaybeUndefVal(block, src, value)) orelse | 7656 | if (ptr_val.castTag(.decl_ref_mut)) |decl_ref_mut| { |
| 7608 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); | 7657 | const const_val = (try sema.resolveMaybeUndefVal(block, src, value)) orelse |
| 7609 | | 7658 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); |
| 7610 | if (ptr_val.tag() == .int_u64) | 7659 | |
| 7611 | break :blk; // propogate it down to runtime | 7660 | if (decl_ref_mut.data.runtime_index < block.runtime_index) { |
| 7612 | | 7661 | if (block.runtime_cond) |cond_src| { |
| 7613 | const comptime_alloc = ptr_val.castTag(.comptime_alloc).?; | 7662 | const msg = msg: { |
| 7614 | if (comptime_alloc.data.runtime_index < block.runtime_index) { | 7663 | const msg = try sema.mod.errMsg(&block.base, src, "store to comptime variable depends on runtime condition", .{}); |
| 7615 | if (block.runtime_cond) |cond_src| { | 7664 | errdefer msg.destroy(sema.gpa); |
| 7616 | const msg = msg: { | 7665 | try sema.mod.errNote(&block.base, cond_src, msg, "runtime condition here", .{}); |
| 7617 | const msg = try sema.mod.errMsg(&block.base, src, "store to comptime variable depends on runtime condition", .{}); | 7666 | break :msg msg; |
| 7618 | errdefer msg.destroy(sema.gpa); | 7667 | }; |
| 7619 | try sema.mod.errNote(&block.base, cond_src, msg, "runtime condition here", .{}); | 7668 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| 7620 | break :msg msg; | 7669 | } |
| 7621 | }; | 7670 | if (block.runtime_loop) |loop_src| { |
| 7622 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); | 7671 | const msg = msg: { |
| 7623 | } | 7672 | const msg = try sema.mod.errMsg(&block.base, src, "cannot store to comptime variable in non-inline loop", .{}); |
| 7624 | if (block.runtime_loop) |loop_src| { | 7673 | errdefer msg.destroy(sema.gpa); |
| 7625 | const msg = msg: { | 7674 | try sema.mod.errNote(&block.base, loop_src, msg, "non-inline loop here", .{}); |
| 7626 | const msg = try sema.mod.errMsg(&block.base, src, "cannot store to comptime variable in non-inline loop", .{}); | 7675 | break :msg msg; |
| 7627 | errdefer msg.destroy(sema.gpa); | 7676 | }; |
| 7628 | try sema.mod.errNote(&block.base, loop_src, msg, "non-inline loop here", .{}); | 7677 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); |
| 7629 | break :msg msg; | 7678 | } |
| 7630 | }; | 7679 | unreachable; |
| 7631 | return sema.mod.failWithOwnedErrorMsg(&block.base, msg); | | |
| 7632 | } | 7680 | } |
| 7633 | unreachable; | 7681 | var new_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| | 7682 | errdefer new_arena.deinit(); |
| | 7683 | const new_ty = try elem_ty.copy(&new_arena.allocator); |
| | 7684 | const new_val = try const_val.copy(&new_arena.allocator); |
| | 7685 | const decl = decl_ref_mut.data.decl; |
| | 7686 | var old_arena = decl.value_arena.?.promote(sema.gpa); |
| | 7687 | decl.value_arena = null; |
| | 7688 | try decl.finalizeNewArena(&new_arena); |
| | 7689 | decl.ty = new_ty; |
| | 7690 | decl.val = new_val; |
| | 7691 | old_arena.deinit(); |
| | 7692 | return; |
| 7634 | } | 7693 | } |
| 7635 | comptime_alloc.data.val = const_val; | | |
| 7636 | return; | | |
| 7637 | } | 7694 | } |
| 7638 | // TODO handle if the element type requires comptime | 7695 | // TODO handle if the element type requires comptime |
| 7639 | | 7696 | |