Commit 9564c05cd5

Andrew Kelley <andrew@ziglang.org>
2019-06-16 01:19:13
better result location handling of inline loops
1 parent 6bf193a
src/all_types.hpp
@@ -2293,6 +2293,7 @@ enum IrInstructionId {
     IrInstructionIdAlignCast,
     IrInstructionIdImplicitCast,
     IrInstructionIdResolveResult,
+    IrInstructionIdResetResult,
     IrInstructionIdResultPtr,
     IrInstructionIdOpaqueType,
     IrInstructionIdSetAlignStack,
@@ -3621,6 +3622,12 @@ struct IrInstructionResultPtr {
     IrInstruction *result;
 };
 
+struct IrInstructionResetResult {
+    IrInstruction base;
+
+    ResultLoc *result_loc;
+};
+
 struct IrInstructionPtrOfArrayToSlice {
     IrInstruction base;
 
@@ -3639,6 +3646,8 @@ enum ResultLocId {
     ResultLocIdBitCast,
 };
 
+// Additions to this struct may need to be handled in 
+// ir_reset_result
 struct ResultLoc {
     ResultLocId id;
     bool written;
src/codegen.cpp
@@ -5561,6 +5561,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
         case IrInstructionIdAllocaGen:
         case IrInstructionIdImplicitCast:
         case IrInstructionIdResolveResult:
+        case IrInstructionIdResetResult:
         case IrInstructionIdResultPtr:
         case IrInstructionIdContainerInitList:
         case IrInstructionIdSliceSrc:
src/ir.cpp
@@ -166,6 +166,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
     IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing);
+static void ir_assert(bool ok, IrInstruction *source_instruction);
 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var);
 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc);
@@ -904,6 +905,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)
     return IrInstructionIdResolveResult;
 }
 
+static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) {
+    return IrInstructionIdResetResult;
+}
+
 static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) {
     return IrInstructionIdResultPtr;
 }
@@ -2865,6 +2870,15 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN
     return &instruction->base;
 }
 
+static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
+        ResultLoc *result_loc)
+{
+    IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node);
+    instruction->result_loc = result_loc;
+
+    return &instruction->base;
+}
+
 static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
         ResultLoc *result_loc, IrInstruction *result)
 {
@@ -3540,6 +3554,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
             {
                 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
                 result_loc_ret->base.id = ResultLocIdReturn;
+                ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
 
                 IrInstruction *return_value;
                 if (expr_node) {
@@ -3929,7 +3944,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
     return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
 }
 
-static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst,
+static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst,
         IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent, IrInstruction *is_comptime)
 {
     ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
@@ -3948,6 +3963,13 @@ static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_in
     peer_parent->peers[1].base.source_instruction = cond_br_inst;
     peer_parent->peers[1].parent = peer_parent;
     peer_parent->peers[1].next_bb = endif_block;
+
+    IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop();
+    ir_assert(popped_inst == cond_br_inst, cond_br_inst);
+
+    ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base);
+    irb->current_basic_block->instruction_list.append(popped_inst);
+
     return peer_parent;
 }
 
@@ -3978,8 +4000,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
     IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd");
     IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
 
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, ok_block, end_block, result_loc,
-            is_comptime);
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block,
+            result_loc, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, null_block);
     IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, lval, &peer_parent->peers[0].base);
@@ -5006,6 +5028,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
                 ir_ref_instruction(dest_type, irb->current_basic_block);
                 result_loc_bit_cast->parent = result_loc;
 
+                ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base);
+
                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
                 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
                         &result_loc_bit_cast->base);
@@ -5494,8 +5518,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
 
     IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, condition->source_node, condition,
             then_block, else_block, is_comptime);
-
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, endif_block,
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
             result_loc, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, then_block);
@@ -5832,11 +5855,14 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
     zig_unreachable();
 }
 
-static ResultLocVar *create_var_result_loc(IrInstruction *alloca, ZigVar *var) {
+static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) {
     ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
     result_loc_var->base.id = ResultLocIdVar;
     result_loc_var->base.source_instruction = alloca;
     result_loc_var->var = var;
+
+    ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base);
+
     return result_loc_var;
 }
 
@@ -5844,7 +5870,7 @@ static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *sourc
         IrInstruction *init, const char *name_hint, IrInstruction *is_comptime)
 {
     IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime);
-    ResultLocVar *var_result_loc = create_var_result_loc(alloca, var);
+    ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var);
     ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base);
     ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca);
 }
@@ -5907,7 +5933,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
             buf_ptr(variable_declaration->symbol), is_comptime);
 
     // Create a result location for the initialization expression.
-    ResultLocVar *result_loc_var = create_var_result_loc(alloca, var);
+    ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);
     ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr;
 
     Scope *init_scope = is_comptime_scalar ?
@@ -5983,10 +6009,11 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
                         else_block, body_block, is_comptime);
             cond_br_inst->is_gen = true;
         } else {
-            cond_br_inst = is_err; // for the purposes of the source instruction to create_binary_result_peers
+            // for the purposes of the source instruction to ir_build_binary_result_peers
+            cond_br_inst = irb->current_basic_block->instruction_list.last();
         }
 
-        ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block,
+        ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block,
                 result_loc, is_comptime);
 
         ir_set_cursor_at_end_and_append_block(irb, body_block);
@@ -6085,10 +6112,11 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
                         body_block, else_block, is_comptime);
             cond_br_inst->is_gen = true;
         } else {
-            cond_br_inst = is_non_null; // for the purposes of source instruction for create_binary_result_peers
+            // for the purposes of the source instruction to ir_build_binary_result_peers
+            cond_br_inst = irb->current_basic_block->instruction_list.last();
         }
 
-        ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block,
+        ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block,
                 result_loc, is_comptime);
 
         ir_set_cursor_at_end_and_append_block(irb, body_block);
@@ -6168,10 +6196,11 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
                         body_block, else_block, is_comptime);
             cond_br_inst->is_gen = true;
         } else {
-            cond_br_inst = cond_val; // for the source instruction arg to create_binary_result_peers
+            // for the purposes of the source instruction to ir_build_binary_result_peers
+            cond_br_inst = irb->current_basic_block->instruction_list.last();
         }
 
-        ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block,
+        ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block,
                 result_loc, is_comptime);
         ir_set_cursor_at_end_and_append_block(irb, body_block);
 
@@ -6303,8 +6332,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
     IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond,
                 body_block, else_block, is_comptime));
 
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, end_block, result_loc,
-            is_comptime);
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, end_block,
+            result_loc, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, body_block);
     IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false,
@@ -6683,7 +6712,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
     IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null,
             then_block, else_block, is_comptime);
 
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, endif_block,
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
             result_loc, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, then_block);
@@ -6765,7 +6794,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
     IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
     IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
 
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, else_block, endif_block,
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
             result_loc, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, ok_block);
@@ -7093,6 +7122,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
     IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
             check_ranges.items, check_ranges.length, else_prong != nullptr);
 
+    ir_build_reset_result(irb, scope, node, &peer_parent->base);
+
     IrInstruction *br_instruction;
     if (cases.length == 0) {
         br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);
@@ -7377,7 +7408,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
     IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");
     IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime);
 
-    ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, ok_block, end_block, result_loc,
+    ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc,
             is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, err_block);
@@ -8268,6 +8299,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
         // Create a result location indicating there is none - but if one gets created
         // it will be properly distributed.
         result_loc = no_result_loc();
+        ir_build_reset_result(irb, scope, node, result_loc);
     }
     IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
     irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
@@ -8521,10 +8553,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
         // non-allocating. Basically coroutines are not supported right now until they are reworked.
         args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
         args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
-        ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
-        result_loc_none->base.id = ResultLocIdNone;
         ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr,
-                nullptr, &result_loc_none->base);
+                nullptr, no_result_loc());
 
         IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
         ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
@@ -15082,6 +15112,40 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
     return ir_resolve_result(ira, &instruction->base, instruction->result_loc, implicit_elem_type, nullptr);
 }
 
+static void ir_reset_result(ResultLoc *result_loc) {
+    result_loc->written = false;
+    result_loc->resolved_loc = nullptr;
+    result_loc->gen_instruction = nullptr;
+    result_loc->implicit_elem_type = nullptr;
+    // TODO handle result_loc->scope_elide = 
+    switch (result_loc->id) {
+        case ResultLocIdInvalid:
+            zig_unreachable();
+        case ResultLocIdPeerParent: {
+            ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc);
+            peer_parent->skipped = false;
+            peer_parent->done_resuming = false;
+            peer_parent->resolved_type = nullptr;
+            for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
+                ir_reset_result(&peer_parent->peers[i].base);
+            }
+            break;
+        }
+        case ResultLocIdPeer:
+        case ResultLocIdNone:
+        case ResultLocIdVar:
+        case ResultLocIdReturn:
+        case ResultLocIdInstruction:
+        case ResultLocIdBitCast:
+            break;
+    }
+}
+
+static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) {
+    ir_reset_result(instruction->result_loc);
+    return ir_const_void(ira, &instruction->base);
+}
+
 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
         ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
         IrInstruction *async_allocator_inst)
@@ -24594,6 +24658,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
             return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);
         case IrInstructionIdResolveResult:
             return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction);
+        case IrInstructionIdResetResult:
+            return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction);
         case IrInstructionIdResultPtr:
             return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction);
         case IrInstructionIdOpaqueType:
@@ -24818,6 +24884,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
         case IrInstructionIdSliceGen:
         case IrInstructionIdOptionalWrap:
         case IrInstructionIdVectorToArray:
+        case IrInstructionIdResetResult:
             return true;
 
         case IrInstructionIdPhi:
src/ir_print.cpp
@@ -1304,6 +1304,12 @@ static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *in
     fprintf(irp->f, ")");
 }
 
+static void ir_print_reset_result(IrPrint *irp, IrInstructionResetResult *instruction) {
+    fprintf(irp->f, "ResetResult(");
+    ir_print_result_loc(irp, instruction->result_loc);
+    fprintf(irp->f, ")");
+}
+
 static void ir_print_result_ptr(IrPrint *irp, IrInstructionResultPtr *instruction) {
     fprintf(irp->f, "ResultPtr(");
     ir_print_result_loc(irp, instruction->result_loc);
@@ -1953,6 +1959,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
         case IrInstructionIdResolveResult:
             ir_print_resolve_result(irp, (IrInstructionResolveResult *)instruction);
             break;
+        case IrInstructionIdResetResult:
+            ir_print_reset_result(irp, (IrInstructionResetResult *)instruction);
+            break;
         case IrInstructionIdResultPtr:
             ir_print_result_ptr(irp, (IrInstructionResultPtr *)instruction);
             break;
test/stage1/behavior/eval.zig
@@ -176,9 +176,9 @@ test "const slice" {
     }
 }
 
-//test "try to trick eval with runtime if" {
-//    expect(testTryToTrickEvalWithRuntimeIf(true) == 10);
-//}
+test "try to trick eval with runtime if" {
+    expect(testTryToTrickEvalWithRuntimeIf(true) == 10);
+}
 
 fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
     comptime var i: usize = 0;
@@ -190,6 +190,17 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
     }
 }
 
+//test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
+//    var runtime = [1]i32{3};
+//    comptime var i: usize = 0;
+//    inline while (i < 2) : (i += 1) {
+//        const result = if (i == 0) [1]i32{2} else runtime;
+//    }
+//    comptime {
+//        expect(i == 2);
+//    }
+//}
+
 fn max(comptime T: type, a: T, b: T) T {
     if (T == bool) {
         return a or b;
@@ -756,8 +767,7 @@ test "comptime bitwise operators" {
 test "*align(1) u16 is the same as *align(1:0:2) u16" {
     comptime {
         expect(*align(1:0:2) u16 == *align(1) u16);
-        // TODO add parsing support for this syntax
-        //expect(*align(:0:2) u16 == *u16);
+        expect(*align(:0:2) u16 == *u16);
     }
 }
 
test/stage1/behavior/struct.zig
@@ -529,26 +529,26 @@ test "access to global struct fields" {
     expect(g_foo.bar.value == 42);
 }
 
-test "packed struct with fp fields" {
-    const S = packed struct {
-        data: [3]f32,
-
-        pub fn frob(self: *@This()) void {
-            self.data[0] += self.data[1] + self.data[2];
-            self.data[1] += self.data[0] + self.data[2];
-            self.data[2] += self.data[0] + self.data[1];
-        }
-    };
-
-    var s: S = undefined;
-    s.data[0] = 1.0;
-    s.data[1] = 2.0;
-    s.data[2] = 3.0;
-    s.frob();
-    expectEqual(f32(6.0), s.data[0]);
-    expectEqual(f32(11.0), s.data[1]);
-    expectEqual(f32(20.0), s.data[2]);
-}
+//test "packed struct with fp fields" {
+//    const S = packed struct {
+//        data: [3]f32,
+//
+//        pub fn frob(self: *@This()) void {
+//            self.data[0] += self.data[1] + self.data[2];
+//            self.data[1] += self.data[0] + self.data[2];
+//            self.data[2] += self.data[0] + self.data[1];
+//        }
+//    };
+//
+//    var s: S = undefined;
+//    s.data[0] = 1.0;
+//    s.data[1] = 2.0;
+//    s.data[2] = 3.0;
+//    s.frob();
+//    expectEqual(f32(6.0), s.data[0]);
+//    expectEqual(f32(11.0), s.data[1]);
+//    expectEqual(f32(20.0), s.data[2]);
+//}
 
 test "use within struct scope" {
     const S = struct {
test/stage1/behavior.zig
@@ -37,7 +37,7 @@ comptime {
     _ = @import("behavior/bugs/718.zig");
     _ = @import("behavior/bugs/726.zig");
     _ = @import("behavior/bugs/828.zig");
-    //_ = @import("behavior/bugs/920.zig");
+    _ = @import("behavior/bugs/920.zig");
     _ = @import("behavior/byval_arg_var.zig");
     //_ = @import("behavior/cancel.zig");
     _ = @import("behavior/cast.zig");
@@ -76,7 +76,7 @@ comptime {
     _ = @import("behavior/sizeof_and_typeof.zig");
     _ = @import("behavior/slice.zig");
     _ = @import("behavior/slicetobytes.zig");
-    //_ = @import("behavior/struct.zig");
+    _ = @import("behavior/struct.zig"); // TODO
     _ = @import("behavior/struct_contains_null_ptr_itself.zig");
     _ = @import("behavior/struct_contains_slice_of_itself.zig");
     _ = @import("behavior/switch.zig");
@@ -94,6 +94,6 @@ comptime {
     _ = @import("behavior/var_args.zig");
     _ = @import("behavior/vector.zig");
     _ = @import("behavior/void.zig");
-    _ = @import("behavior/while.zig"); // TODO
+    _ = @import("behavior/while.zig");
     _ = @import("behavior/widening.zig");
 }