Bug: yielding in '__close' mess up number of returns
Yielding in a __close metamethod called when returning vararg results changes the top and so messes up the number of returned values.
This commit is contained in:
@@ -813,6 +813,65 @@ do
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
-- yielding inside closing metamethods while returning
|
||||
-- (bug in 5.4.3)
|
||||
|
||||
local extrares -- result from extra yield (if any)
|
||||
|
||||
local function check (body, extra, ...)
|
||||
local t = table.pack(...) -- expected returns
|
||||
local co = coroutine.wrap(body)
|
||||
if extra then
|
||||
extrares = co() -- runs until first (extra) yield
|
||||
end
|
||||
local res = table.pack(co()) -- runs until yield inside '__close'
|
||||
assert(res.n == 2 and res[2] == nil)
|
||||
local res2 = table.pack(co()) -- runs until end of function
|
||||
assert(res2.n == t.n)
|
||||
for i = 1, #t do
|
||||
if t[i] == "x" then
|
||||
assert(res2[i] == res[1]) -- value that was closed
|
||||
else
|
||||
assert(res2[i] == t[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function foo ()
|
||||
local x <close> = func2close(coroutine.yield)
|
||||
local extra <close> = func2close(function (self)
|
||||
assert(self == extrares)
|
||||
coroutine.yield(100)
|
||||
end)
|
||||
extrares = extra
|
||||
return table.unpack{10, x, 30}
|
||||
end
|
||||
check(foo, true, 10, "x", 30)
|
||||
assert(extrares == 100)
|
||||
|
||||
local function foo ()
|
||||
local x <close> = func2close(coroutine.yield)
|
||||
return
|
||||
end
|
||||
check(foo, false)
|
||||
|
||||
local function foo ()
|
||||
local x <close> = func2close(coroutine.yield)
|
||||
local y, z = 20, 30
|
||||
return x
|
||||
end
|
||||
check(foo, false, "x")
|
||||
|
||||
local function foo ()
|
||||
local x <close> = func2close(coroutine.yield)
|
||||
local extra <close> = func2close(coroutine.yield)
|
||||
return table.unpack({}, 1, 100) -- 100 nils
|
||||
end
|
||||
check(foo, true, table.unpack({}, 1, 100))
|
||||
|
||||
end
|
||||
|
||||
do
|
||||
-- yielding inside closing metamethods after an error
|
||||
|
||||
|
||||
Reference in New Issue
Block a user