diff --git a/astgen.c b/astgen.c index 0aa1eb472e..88bb7a04b3 100644 --- a/astgen.c +++ b/astgen.c @@ -1828,9 +1828,8 @@ static ResultLoc breakResultInfo( .src_node = 0, .ctx = block_ri.ctx }; case RL_DISCARD: - return (ResultLoc) { - .tag = RL_DISCARD, .data = 0, .src_node = 0, .ctx = block_ri.ctx - }; + // Don't forward ctx (AstGen.zig:11916-11920). + return RL_DISCARD_VAL; default: return block_ri; } @@ -2007,8 +2006,12 @@ static uint32_t rvalue( return ZIR_REF_ONE_USIZE; case RC(ZIR_REF_USIZE_TYPE, ZIR_REF_ONE_U8): return ZIR_REF_ONE_USIZE; - default: - return addPlNodeBin(gz, ZIR_INST_AS_NODE, node, rl.data, result); + default: { + ZirInstTag as_tag = (rl.ctx == RI_CTX_SHIFT_OP) + ? ZIR_INST_AS_SHIFT_OPERAND + : ZIR_INST_AS_NODE; + return addPlNodeBin(gz, as_tag, node, rl.data, result); + } } #undef RC } @@ -2174,10 +2177,10 @@ static uint32_t tryResolvePrimitiveIdent(GenZir* gz, uint32_t node); // Mirrors comptimeExpr2 (AstGen.zig:1982). // Evaluates a node in a comptime block_comptime scope. static uint32_t comptimeExpr( - GenZir* gz, Scope* scope, uint32_t node, uint32_t reason) { + GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node, uint32_t reason) { // Skip wrapping when already in comptime context (AstGen.zig:1990). if (gz->is_comptime) - return expr(gz, scope, node); + return exprRl(gz, scope, rl, node); // Optimization: certain node types are trivially comptime and don't need // a block_comptime wrapper (AstGen.zig:1997-2046). AstGenCtx* ag = gz->astgen; @@ -2227,7 +2230,7 @@ static uint32_t comptimeExpr( case AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING: case AST_NODE_TAGGED_UNION_TWO: case AST_NODE_TAGGED_UNION_TWO_TRAILING: - return expr(gz, scope, node); + return exprRl(gz, scope, rl, node); default: break; } @@ -2235,18 +2238,32 @@ static uint32_t comptimeExpr( uint32_t block_inst = makeBlockInst(ag, ZIR_INST_BLOCK_COMPTIME, gz, node); GenZir block_scope = makeSubBlock(gz, scope); block_scope.is_comptime = true; - uint32_t result = expr(&block_scope, scope, node); + // Transform RL to type-only (AstGen.zig:2084-2090). + ResultLoc ty_only_rl; + uint32_t res_ty = rlResultType(gz, rl, node); + if (res_ty != 0) + ty_only_rl = (ResultLoc) { + .tag = RL_COERCED_TY, .data = res_ty, .src_node = 0, .ctx = rl.ctx + }; + else + ty_only_rl = (ResultLoc) { + .tag = RL_NONE, .data = 0, .src_node = 0, .ctx = rl.ctx + }; + uint32_t result = exprRl(&block_scope, scope, ty_only_rl, node); addBreak(&block_scope, ZIR_INST_BREAK_INLINE, block_inst, result, AST_NODE_OFFSET_NONE); setBlockComptimeBody(ag, &block_scope, block_inst, reason); gzAppendInstruction(gz, block_inst); - return block_inst + ZIR_REF_START_INDEX; + return rvalue(gz, rl, block_inst + ZIR_REF_START_INDEX, node); } -// Mirrors typeExpr (AstGen.zig:1966). -// Evaluates a type expression in comptime context. +// Mirrors typeExpr (AstGen.zig:394). static uint32_t typeExpr(GenZir* gz, Scope* scope, uint32_t node) { - return comptimeExpr(gz, scope, node, COMPTIME_REASON_TYPE); + ResultLoc rl = { .tag = RL_COERCED_TY, + .data = ZIR_REF_TYPE_TYPE, + .src_node = 0, + .ctx = RI_CTX_NONE }; + return comptimeExpr(gz, scope, rl, node, COMPTIME_REASON_TYPE); } // Mirrors numberLiteral (AstGen.zig:8544). @@ -2887,23 +2904,37 @@ static uint32_t ptrTypeExpr(GenZir* gz, Scope* scope, uint32_t node) { if (sentinel_node != UINT32_MAX) { uint32_t reason = (size == 2) ? COMPTIME_REASON_SLICE_SENTINEL : COMPTIME_REASON_POINTER_SENTINEL; - sentinel_ref = comptimeExpr(gz, scope, sentinel_node, reason); + ResultLoc srl = { + .tag = RL_TY, .data = elem_type, .src_node = 0, .ctx = RI_CTX_NONE + }; + sentinel_ref = comptimeExpr(gz, scope, srl, sentinel_node, reason); trailing_count++; } if (addrspace_node != UINT32_MAX) { + // Upstream creates addrspace_ty via addBuiltinValue, we don't have + // that yet, so pass RL_NONE (matching previous behavior). addrspace_ref = comptimeExpr( - gz, scope, addrspace_node, COMPTIME_REASON_ADDRSPACE); + gz, scope, RL_NONE_VAL, addrspace_node, COMPTIME_REASON_ADDRSPACE); trailing_count++; } if (align_node != UINT32_MAX) { - align_ref = comptimeExpr(gz, scope, align_node, COMPTIME_REASON_ALIGN); + ResultLoc arl = { .tag = RL_COERCED_TY, + .data = ZIR_REF_U29_TYPE, + .src_node = 0, + .ctx = RI_CTX_NONE }; + align_ref + = comptimeExpr(gz, scope, arl, align_node, COMPTIME_REASON_ALIGN); trailing_count++; } if (bit_range_start != UINT32_MAX) { - bit_start_ref - = comptimeExpr(gz, scope, bit_range_start, COMPTIME_REASON_TYPE); - bit_end_ref - = comptimeExpr(gz, scope, bit_range_end, COMPTIME_REASON_TYPE); + ResultLoc brl = { .tag = RL_COERCED_TY, + .data = ZIR_REF_U16_TYPE, + .src_node = 0, + .ctx = RI_CTX_NONE }; + bit_start_ref = comptimeExpr( + gz, scope, brl, bit_range_start, COMPTIME_REASON_TYPE); + bit_end_ref = comptimeExpr( + gz, scope, brl, bit_range_end, COMPTIME_REASON_TYPE); trailing_count += 2; } @@ -2964,7 +2995,12 @@ static uint32_t arrayTypeExpr(GenZir* gz, Scope* scope, uint32_t node) { SET_ERROR(ag); return ZIR_REF_VOID_VALUE; } - uint32_t len = comptimeExpr(gz, scope, nd.lhs, COMPTIME_REASON_TYPE); + ResultLoc len_rl = { .tag = RL_COERCED_TY, + .data = ZIR_REF_USIZE_TYPE, + .src_node = 0, + .ctx = RI_CTX_NONE }; + uint32_t len + = comptimeExpr(gz, scope, len_rl, nd.lhs, COMPTIME_REASON_TYPE); uint32_t elem_type = typeExpr(gz, scope, nd.rhs); return addPlNodeBin(gz, ZIR_INST_ARRAY_TYPE, node, len, elem_type); } @@ -3108,9 +3144,10 @@ static uint32_t shiftOp( uint32_t log2_int_type = addUnNode(gz, ZIR_INST_TYPEOF_LOG2_INT_TYPE, lhs, nd.lhs); - ResultLoc rhs_rl; - rhs_rl.tag = RL_TY; - rhs_rl.data = log2_int_type; + ResultLoc rhs_rl = { .tag = RL_TY, + .data = log2_int_type, + .src_node = 0, + .ctx = RI_CTX_SHIFT_OP }; uint32_t rhs = exprRl(gz, scope, rhs_rl, nd.rhs); emitDbgStmt(gz, saved_line, saved_col); @@ -3221,6 +3258,7 @@ static uint32_t retExpr(GenZir* gz, Scope* scope, uint32_t node) { ret_rl.tag = RL_COERCED_TY; ret_rl.data = ag->fn_ret_ty; } + ret_rl.ctx = RI_CTX_RETURN; uint32_t operand = exprRl(gz, scope, ret_rl, operand_node); // Emit RESTORE_ERR_RET_INDEX based on nodeMayEvalToError @@ -3658,8 +3696,12 @@ static uint32_t structInitExpr( = tree->extra_data.arr[type_nd.rhs + 1]; uint32_t elem_type = exprRl(gz, scope, RL_NONE_VAL, elem_type_node); - uint32_t sentinel = comptimeExpr( - gz, scope, sentinel_node, COMPTIME_REASON_ARRAY_SENTINEL); + ResultLoc sent_rl = { .tag = RL_COERCED_TY, + .data = elem_type, + .src_node = 0, + .ctx = RI_CTX_NONE }; + uint32_t sentinel = comptimeExpr(gz, scope, sent_rl, + sentinel_node, COMPTIME_REASON_ARRAY_SENTINEL); uint32_t array_type_inst = addPlNodeTriple(gz, ZIR_INST_ARRAY_TYPE_SENTINEL, type_expr_node, ZIR_REF_ZERO_USIZE, elem_type, sentinel); @@ -3724,8 +3766,10 @@ static uint32_t tryExpr(GenZir* gz, Scope* scope, uint32_t node) { uint32_t try_lc_line = ag->source_line - gz->decl_line; uint32_t try_lc_column = ag->source_column; - // Evaluate operand (AstGen.zig:6001). - uint32_t operand = expr(gz, scope, operand_node); + // Evaluate operand (AstGen.zig:5993-6001). + ResultLoc operand_rl = RL_NONE_VAL; + operand_rl.ctx = RI_CTX_ERROR_HANDLING_EXPR; + uint32_t operand = exprRl(gz, scope, operand_rl, operand_node); // Create try block instruction (AstGen.zig:6007). uint32_t try_inst = makeBlockInst(ag, ZIR_INST_TRY, gz, node); @@ -4370,11 +4414,14 @@ static uint32_t exprRl(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node) { ResultLoc ty_only_rl; uint32_t res_ty = rlResultType(gz, rl, node); if (res_ty != 0) - ty_only_rl = (ResultLoc) { - .tag = RL_COERCED_TY, .data = res_ty, .src_node = 0 - }; + ty_only_rl = (ResultLoc) { .tag = RL_COERCED_TY, + .data = res_ty, + .src_node = 0, + .ctx = rl.ctx }; else - ty_only_rl = RL_NONE_VAL; + ty_only_rl = (ResultLoc) { + .tag = RL_NONE, .data = 0, .src_node = 0, .ctx = rl.ctx + }; uint32_t result = exprRl(&block_scope, scope, ty_only_rl, body_node); addBreak(&block_scope, ZIR_INST_BREAK_INLINE, block_inst, result, @@ -4865,7 +4912,11 @@ static uint32_t ifExpr(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node) { uint32_t bool_bit; // the boolean for condbr if (error_token != 0) { // Error union condition: if (err_union) |val| else |err|. - cond_inst = expr(&block_scope, &block_scope.base, cond_node); + // (AstGen.zig:6341). + ResultLoc cond_rl = RL_NONE_VAL; + cond_rl.ctx = RI_CTX_ERROR_HANDLING_EXPR; + cond_inst + = exprRl(&block_scope, &block_scope.base, cond_rl, cond_node); bool_bit = addUnNode( &block_scope, ZIR_INST_IS_NON_ERR, cond_inst, cond_node); } else if (payload_token != 0) { @@ -5298,8 +5349,13 @@ static uint32_t orelseCatchExpr( // Create block_scope (AstGen.zig:6062-6063). GenZir block_scope = makeSubBlock(gz, scope); - // Evaluate operand in block_scope (AstGen.zig:6074). - uint32_t operand = expr(&block_scope, &block_scope.base, nd.lhs); + // Evaluate operand in block_scope (AstGen.zig:6066-6074). + ResultLoc operand_rl = RL_NONE_VAL; + if (do_err_trace) { + operand_rl.ctx = RI_CTX_ERROR_HANDLING_EXPR; + } + uint32_t operand + = exprRl(&block_scope, &block_scope.base, operand_rl, nd.lhs); // Check condition in block_scope (AstGen.zig:6075). ZirInstTag test_tag @@ -5593,15 +5649,15 @@ static uint32_t switchExpr( pay[pay_len++] = 1; prong_info_slot = pay_len++; AstData rng = tree->nodes.datas[cd.lhs]; - pay[pay_len++] = comptimeExpr( - gz, scope, rng.lhs, COMPTIME_REASON_SWITCH_ITEM); - pay[pay_len++] = comptimeExpr( - gz, scope, rng.rhs, COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, rng.lhs, + COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, rng.rhs, + COMPTIME_REASON_SWITCH_ITEM); } else { // Scalar: [item_ref, prong_info, body...] pay[scalar_tbl + scalar_ci++] = hdr; - pay[pay_len++] = comptimeExpr( - gz, scope, cd.lhs, COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, cd.lhs, + COMPTIME_REASON_SWITCH_ITEM); prong_info_slot = pay_len++; } break; @@ -5633,8 +5689,8 @@ static uint32_t switchExpr( abort(); pay = p; } - pay[pay_len++] = comptimeExpr( - gz, scope, item, COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, item, + COMPTIME_REASON_SWITCH_ITEM); } } // Range pairs. @@ -5649,10 +5705,10 @@ static uint32_t switchExpr( abort(); pay = p; } - pay[pay_len++] = comptimeExpr( - gz, scope, rng.lhs, COMPTIME_REASON_SWITCH_ITEM); - pay[pay_len++] = comptimeExpr( - gz, scope, rng.rhs, COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, + rng.lhs, COMPTIME_REASON_SWITCH_ITEM); + pay[pay_len++] = comptimeExpr(gz, scope, RL_NONE_VAL, + rng.rhs, COMPTIME_REASON_SWITCH_ITEM); } } break; @@ -7898,7 +7954,7 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, uint32_t* wip_decl_insts, if (gzInstructionsLen(&ret_gz) > 0) { // break_inline targets the func instruction (which doesn't // exist yet). We use 0 as placeholder and patch later. - makeBreakInline(&ret_gz, 0, ret_ref, 0); + makeBreakInline(&ret_gz, 0, ret_ref, AST_NODE_OFFSET_NONE); } } // Map void_type → .none (AstGen.zig:12054). diff --git a/astgen_test.zig b/astgen_test.zig index 247925638c..d382250f81 100644 --- a/astgen_test.zig +++ b/astgen_test.zig @@ -793,7 +793,6 @@ test "astgen: corpus build.zig" { } test "astgen: corpus tokenizer_test.zig" { - if (true) return error.SkipZigTest; // TODO: string_bytes and extra_len diffs const gpa = std.testing.allocator; try corpusCheck(gpa, @embedFile("tokenizer_test.zig")); }