Repository navigation
Conversation
cloneObject rebuilt doc.type.function without copying `async`/`asyncPos`, so `---@alias Name<T> async fun(): T` lost its async flag once used as `Name<string>`, and await-in-sync/hover treated it as a sync function. Fixes LuaLS#3469
There was a problem hiding this comment.
中文:变更整体方向正确:cloneObject 在克隆泛型别名解析后的函数类型时保留了 async/asyncPos,测试覆盖了诊断与 hover 场景。未发现明确的功能性缺陷或安全问题。建议补充一个回归测试,覆盖 asyncPos 的保留(例如 hover 或诊断中依赖 async 关键字位置的行为),因为当前测试只验证了 async 标志,未验证 asyncPos 是否被正确保留;若 asyncPos 指向原类型节点而克隆对象位置不同,可能导致定位异常。另外建议确认 cloneObject 的其他调用路径不会因新增字段而产生意外行为(例如非函数类型的克隆),但基于当前 diff 未发现证据表明存在问题。
English: The change is directionally correct: cloneObject now preserves async/asyncPos when cloning a resolved generic alias function type, and tests cover diagnostics and hover. No clear functional defects or security issues were found. Suggest adding a regression test that covers preservation of asyncPos (e.g., behavior relying on the async keyword position in hover or diagnostics), since current tests only verify the async flag and not whether asyncPos is correctly retained; if asyncPos points to the original type node while the cloned object has different positions, it could cause incorrect location reporting. Also suggest confirming that other call paths of cloneObject are not affected by the new fields (e.g., cloning non-function types), though no evidence of a problem was found in the current diff.
Summary
cloneObjectinscript/vm/generic.luabuilds a newdoc.type.functionwhen a generic is resolved, but it copied onlyargs/returns. Theasyncflag (andasyncPos) set by the LuaDoc parser forasync funwas dropped. So---@alias Name<T> async fun(): Tlost its async-ness once used asName<string>, whether through---@type, a---@field, or alocal functionannotated with it.await-in-syncstopped warning and hover stopped showingasync. Non-generic aliases andasync fun<T>(...)were not affected, because they are not cloned.asyncandasyncPosfrom the source.FIXentry that links Async flag lost when alias with type parameters (@alias Name<T> async fun) is used #3469.Test plan
test/diagnostics/await-in-sync.lua: a generic async alias used via---@typeon a local, on alocal function, and via a class---@fieldnow reportsawait-in-syncin a sync caller. Each of these fails without the change and passes with it. Another case checks there is no warning inside an---@asynccaller.test/hover/init.lua: hover of---@type AsyncGenericFunc<string>now showslocal f: async AsyncGenericFunc<string>(it waslocal f: AsyncGenericFunc<string>).bin/lua-language-server test.lua --name=diagnosticsand--name=hoverpass.bin/lua-language-server test.luapasses (test finish.), on darwin-arm64 only.Fixes #3469