Skip to content

Commit 7cb9c4f

Browse files
committed
Fix bug in returning nil-prefixed multi values from async function
1 parent b93ace0 commit 7cb9c4f

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

src/lua.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,11 +1741,14 @@ impl Lua {
17411741
Ok(2)
17421742
}
17431743
Poll::Ready(results) => {
1744-
let results = lua.create_sequence_from(results?)?;
1745-
check_stack(state, 2)?;
1744+
let results = results?;
1745+
let nresults = results.len() as Integer;
1746+
let results = lua.create_sequence_from(results)?;
1747+
check_stack(state, 3)?;
17461748
ffi::lua_pushboolean(state, 1);
17471749
lua.push_value(Value::Table(results))?;
1748-
Ok(2)
1750+
lua.push_value(Value::Integer(nresults))?;
1751+
Ok(3)
17491752
}
17501753
}
17511754
})
@@ -1772,9 +1775,10 @@ impl Lua {
17721775
env.set("yield", coroutine.get::<_, Function>("yield")?)?;
17731776
env.set(
17741777
"unpack",
1775-
self.create_function(|_, tbl: Table| {
1778+
self.create_function(|_, (tbl, len): (Table, Integer)| {
17761779
Ok(MultiValue::from_vec(
1777-
tbl.sequence_values().collect::<Result<Vec<Value>>>()?,
1780+
tbl.raw_sequence_values_by_len(Some(len))
1781+
.collect::<Result<Vec<Value>>>()?,
17781782
))
17791783
})?,
17801784
)?;
@@ -1785,9 +1789,9 @@ impl Lua {
17851789
poll = get_poll(...)
17861790
local poll, yield, unpack = poll, yield, unpack
17871791
while true do
1788-
ready, res = poll()
1792+
local ready, res, nres = poll()
17891793
if ready then
1790-
return unpack(res)
1794+
return unpack(res, nres)
17911795
end
17921796
yield(res)
17931797
end

src/table.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,11 @@ impl<'lua> Table<'lua> {
474474
}
475475
}
476476

477-
#[cfg(feature = "serialize")]
478-
pub(crate) fn raw_sequence_values_by_len<V: FromLua<'lua>>(self) -> TableSequence<'lua, V> {
479-
let len = self.raw_len();
477+
pub(crate) fn raw_sequence_values_by_len<V: FromLua<'lua>>(
478+
self,
479+
len: Option<Integer>,
480+
) -> TableSequence<'lua, V> {
481+
let len = len.unwrap_or_else(|| self.raw_len());
480482
TableSequence {
481483
table: self.0,
482484
index: Some(1),
@@ -641,7 +643,7 @@ impl<'lua> Serialize for Table<'lua> {
641643
let len = self.raw_len() as usize;
642644
if len > 0 || self.is_array() {
643645
let mut seq = serializer.serialize_seq(Some(len))?;
644-
for v in self.clone().raw_sequence_values_by_len::<Value>() {
646+
for v in self.clone().raw_sequence_values_by_len::<Value>(None) {
645647
let v = v.map_err(serde::ser::Error::custom)?;
646648
seq.serialize_element(&v)?;
647649
}

tests/async.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ async fn test_async_handle_yield() -> Result<()> {
136136
Ok(())
137137
}
138138

139+
#[tokio::test]
140+
async fn test_async_multi_return_nil() -> Result<()> {
141+
let lua = Lua::new();
142+
lua.globals().set(
143+
"func",
144+
lua.create_async_function(|_, _: ()| async { Ok((Option::<String>::None, "error")) })?,
145+
)?;
146+
147+
lua.load(
148+
r#"
149+
local ok, err = func()
150+
assert(err == "error")
151+
"#,
152+
)
153+
.exec_async()
154+
.await
155+
}
156+
139157
#[tokio::test]
140158
async fn test_async_return_async_closure() -> Result<()> {
141159
let lua = Lua::new();

0 commit comments

Comments
 (0)