luau icon indicating copy to clipboard operation
luau copied to clipboard

pcall return values are unexpected in strict mode, `any` and `any?` cause different results

Open kirdaaa opened this issue 2 years ago • 1 comments

when using strict mode, pcall only allows returning 1 value, for example:

--!strict
local function foo()
end

local success, response = pcall(foo)

TypeError: Function only returns 1 value. 2 are required here

even after adding error into the function's body the same issue happens, i was thinking of solving this by putting any type onto the response variable, that didn't help, however, when i did response: any? the error disappeared, this is overall confusing.

i looked at the source code and it now makes sense, pcall completely ignores possible error or assert calls and only counts in function return value... declare function pcall<A..., R...>(f: (A...) -> R..., ...: A...): (boolean, R...)... the temporary solution is to change foo's return type to any or ...any.

kirdaaa avatar Feb 26 '22 17:02 kirdaaa

Ran into this, this makes pcall basically impossible to use for anything in strict mode without it throwing a hissy fit. The return type of pcall() should always be boolean, ...any considering it can always return an error of any type. pcall is one of the most important functions in lua so this is really annoying that it's types are not correct at all. Code_2023-07-30_04-59-28 pcall returning ...any isn't exactly the nicest, so maybe Luau should looking into a better approach to error handling that can be correctly typed. I'd propose something like npcall(func: (a...) -> (b...), ...: a...): any?, b..., where any? is the error, nil if no error occured, and b... is the return value of the function. Usage could look like:

local err, a, b = npcall(function()
    return "hello", "world"
end)
if not err then
    print(a, b)
end

fewkz avatar Jul 30 '23 09:07 fewkz