I'll quote the Lua reference:
Both function calls and vararg expressions can result in multiple
values. If an expression is used as a statement (only possible for
function calls (see §2.4.6)), then its return list is adjusted to zero
elements, thus discarding all returned values. If an expression is
used as the last (or the only) element of a list of expressions, then
no adjustment is made (unless the call is enclosed in parentheses). In
all other contexts, Lua adjusts the result list to one element,
discarding all values except the first one.
As you see your unpack call is reduced to one return value as it is neither the last nor the only expression in the list of expressions you pass to test:
test(unpack({1,2}), 3)
In the other case the answer is quite simple:
test(unpack({}), 3)
The first value passed to test is nil. Therefor for i, v in ipairs({...}) do end
will do nothing as your table's first value is nil
as unpack({})
returns nil
ipairs (t)
Returns three values (an iterator function, the table t, and 0) so
that the construction
for i,v in ipairs(t) do body end
will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first nil value.