diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 990be0f..b60f47e 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -555,18 +555,24 @@ def _RetKindFromTag(fn: ast.FunctionDef*, tcl: ast.Call*) -> int: if val is None: fatal_error(tcl, "@life(ret(borrows=...)) requires a parameter name or `none`", "LifetimeError") return -1 + # `borrows=none`:返回值不借用任何形参(非本帧)。 + # 其余一律交给 _WillFreeArgIndex:它同时认**形参名**与**0 起序号**(与 willFree(...) 同口径, + # 见 includes/stdlib.vp 的注释:"写法二选一:形参名 willFree(p) 或形参位置序号 willFree(0)"), + # 非法实参(非名非整数/越界/不是形参名)在那边 fail-fast。 if val.kind() == ast.ASTKind.Name: vn: ast.Name* = ast.Name*(val) if vn.id is None: return -1 if string.strcmp(vn.id, "none") == 0: return RET_KIND_NONFRAME - idx: int = _WillFreeArgIndex(fn, val) - if idx < 0: return -1 # 已 fail-fast - return RET_KIND_BORROW_BASE + idx - if val.kind() == ast.ASTKind.Constant: + elif val.kind() == ast.ASTKind.Constant: vc: ast.Constant* = ast.Constant*(val) if vc is not None and vc.const_kind == ast.CONST_NONE: return RET_KIND_NONFRAME - fatal_error(tcl, "@life(ret(borrows=...)) accepts only a parameter name or `none`", "LifetimeError") - return -1 + else: + fatal_error(tcl, "@life(ret(borrows=...)) accepts only a parameter name (or its 0-based position) or `none`", "LifetimeError") + return -1 + idx: int = _WillFreeArgIndex(fn, val) + if idx < 0: return -1 # 已 fail-fast + return RET_KIND_BORROW_BASE + idx + # 形式二:ret(frame) / ret(heap) / ret(static) if tcl.args is None or len(tcl.args) != 1: fatal_error(tcl, "@life(ret(...)) expects exactly one of `frame` / `heap` / `static`, or `borrows=` / `borrows=none`", "LifetimeError")