fix(gen): ret(borrows=...) 支持 0 起序号写法(原来只认形参名)
现场:@life(noescape(a, b), ret(borrows=1)) 报 LifetimeError: @life(ret(borrows=...)) accepts only a parameter name or `none` —— _RetKindFromTag 的关键字分支只处理 Name(形参名)与 CONST_NONE,遇到整数常量 (形参位置序号)就落到 fail-fast。 修法:Name(形参名 / none)与 Constant(CONST_NONE = 非本帧)先分流, 其余一律交给 _WillFreeArgIndex —— 它本来就同时认"形参名"与"0 起序号" (与 willFree(...) 同口径,见 includes/stdlib.vp 注释),非法实参在那边 fail-fast。 于是 ret(borrows=x) 与 ret(borrows=0) 等价可用。
This commit is contained in:
1 parent
5ec75b2d38
commit
c1d3f62bf0
1 file changed
+12
-6
@@ -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=<param>` / `borrows=none`", "LifetimeError")
|
||||
|
||||
Reference in new issue
Block a user