Skip to content

Commit 57005db

Browse files
committed
fix(hir): 短路表达式处理优化
1 parent de32903 commit 57005db

2 files changed

Lines changed: 28 additions & 18 deletions

File tree

src/hir/analyze/short_circuit/recovery.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,25 +212,18 @@ fn build_branch_short_circuit_plan_from_candidate(
212212
return None;
213213
}
214214

215-
let decision = if decision_references_forbidden_candidate_temps(
216-
lowering,
217-
short,
218-
&decision,
219-
&allowed_blocks,
220-
) {
215+
let has_forbidden = decision_references_forbidden_candidate_temps(lowering, short, &decision, &allowed_blocks);
216+
let decision = if has_forbidden {
221217
match short.exit {
222-
// branch short-circuit 的最终条件只会在当前结构位点求值一次。
223-
// 当后续 consumed header 的 subject 只是被保守地留成 temp ref 时,
224-
// 这里允许沿既有 decision builder 退回到 single-eval lowering,
225-
// 把那一跳恢复成源码级操作数本体,而不是直接整段退化成布尔壳。
226-
// 入口 header 的 prefix 会在 `lower_branch` 中显式物化;这里继续
227-
// 引用它的 temp,避免把同一次调用同时保留成前缀语句和条件表达式。
228-
ShortCircuitExit::BranchExit { .. } => build_branch_decision_expr_mixed_eval(
229-
lowering,
230-
short,
231-
short.entry,
232-
&allowed_blocks,
233-
)?,
218+
ShortCircuitExit::BranchExit { .. } => {
219+
let res = build_branch_decision_expr_mixed_eval(
220+
lowering,
221+
short,
222+
short.entry,
223+
&allowed_blocks,
224+
);
225+
res?
226+
}
234227
ShortCircuitExit::ValueMerge(_) => {
235228
let (_, _, truthy_leaves, falsy_leaves) =
236229
branch_exit_blocks_from_value_merge_candidate(short)?;

src/hir/analyze/structure/body.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,23 @@ impl<'a, 'b> StructuredBodyLowerer<'a, 'b> {
816816
}));
817817
}
818818

819+
// 当 SC 的 falsy 出口本身是 `return`/`tail-call` 终结块,并且 then 入口能
820+
// 经由内部控制流到达同一个终结块时(典型形状:then 内部还有 `if X then return end`
821+
// 的早返回守卫,与 SC 失败路径共用函数尾部的隐式 return),按 IfElse 处理会
822+
// 让 then 在 lower 时先 visit 掉这个共享终结块,导致随后 lower else 失败、整段
823+
// proto 退化成 goto-label fallback。这里把这种形状显式降级成 IfThen,merge 留空:
824+
// 终结块由 then 内部的早返回路径自然消费,SC falsy 边落到外层 region 的自然末尾,
825+
// 语义上正好对齐 `if cond then ... <early return inside> ... end` 加函数末尾隐式 return。
826+
if self.block_is_terminal_exit(falsy) && self.lowering.cfg.can_reach(truthy, falsy) {
827+
return Some(Some(StructuredBranchPlan {
828+
cond,
829+
then_entry: truthy,
830+
else_entry: None,
831+
merge: None,
832+
consumed_headers,
833+
}));
834+
}
835+
819836
let merge = self
820837
.lowering
821838
.graph_facts

0 commit comments

Comments
 (0)