This commit is contained in:
Kaan 2026-10-19 17:49:43 +03:00 • committed by GitHub
commit 911a4ca57b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 1 deletions

View file

@ -43,6 +43,7 @@ end
local function ycall<T, U>(fn: (T) -> U, arg: T): (boolean, string|U)
local n = scopes.n
local thread = coroutine.create(xpcall)
--local function efn(err: string) return debug.traceback(err, 3) end
local resume_ok, run_ok, result = coroutine.resume(thread, fn, efn, arg)
@ -50,7 +51,15 @@ local function ycall<T, U>(fn: (T) -> U, arg: T): (boolean, string|U)
assert(resume_ok)
if coroutine.status(thread) ~= "dead" then
return false, debug.traceback(thread, "attempt to yield in reactive scope")
local trace = debug.traceback(thread, "attempt to yield in reactive scope")
-- the thread can still be resumed (e.g. by task.wait), so stop it and
-- pop the scopes it pushed before yielding
if task then task.cancel(thread) else coroutine.close(thread) end
for i = scopes.n, n + 1, -1 do scopes[i] = nil end
scopes.n = n
return false, trace
end
return run_ok, result

View file

@ -3009,6 +3009,27 @@ TEST("strict", wrap_root(function()
CHECK(not ok)
end
do CASE "yield in a component"
local input = source(false)
local thread
local resumed = false
local destroy = root(function()
show(input, function()
thread = coroutine.running()
coroutine.yield()
resumed = true
return {}
end)
end)
CHECK(not pcall(input, true))
CHECK(not coroutine.resume(thread))
CHECK(not resumed)
CHECK(pcall(input, false))
CHECK(pcall(destroy))
end
do CASE "run derived callback twice"
local src = source(1)
local count = 0