Skip to content

Commit 55c3a3c

Browse files
committed
fix callbacks with less arguments than their contract erroring
1 parent fe6106f commit 55c3a3c

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

nattlua/analyzer/operators/call.lua

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ do
137137
obj:SetCalled(true)
138138

139139
-- infer any uncalled functions in the arguments to get their return type
140+
if not input then debug.trace() end
141+
140142
for i, b in ipairs(input:GetData()) do
141143
if b.Type == "function" and not b:IsCalled() and not b:IsExplicitOutputSignature() then
142144
local a = obj:GetInputSignature():GetWithNumber(i)
@@ -162,7 +164,19 @@ do
162164
-- TODO: callbacks with ref arguments should not be called
163165
-- mixed ref args make no sense, maybe ref should be a keyword for the function instead?
164166
if func.Type == "function" and not b:HasReferenceTypes() and func then
165-
self:Assert(self:Call(b, func:GetInputSignature():Copy(nil, true)))
167+
local len = b:GetInputSignature():GetTupleLength()
168+
local new = func:GetInputSignature():Copy(nil, true)
169+
local err
170+
171+
if not func:GetInputSignature():IsInfinite() then
172+
new, err = new:Slice(1, len)
173+
end
174+
175+
if not new then
176+
self:Assert(new, err)
177+
else
178+
self:Assert(self:Call(b, new))
179+
end
166180
end
167181
end
168182
end

nattlua/analyzer/operators/function_call_body.lua

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,19 @@ local function check_input(self, obj, input)
241241

242242
func:SetInputSignature(tup)
243243
elseif contract.Type == "function" then
244-
func:SetInputSignature(contract:GetInputSignature():Copy(nil, true)) -- force copy tables so we don't mutate the contract
244+
local len = func:GetInputSignature():GetTupleLength()
245+
local new = contract:GetInputSignature():Copy(nil, true)
246+
local err
247+
248+
if not contract:GetInputSignature():IsInfinite() then
249+
new, err = new:Slice(1, len)
250+
end
251+
252+
if not new then
253+
self:Assert(new, err)
254+
else
255+
func:SetInputSignature(new) -- force copy tables so we don't mutate the contract
256+
end
245257
end
246258

247259
func:SetCalled(false)
@@ -552,7 +564,13 @@ return function(self, obj, input)
552564
end
553565
end
554566

555-
obj:GetInputSignature():Merge(self:Assert(input:Slice(1, obj:GetInputSignature():GetMinimumLength())))
567+
local tup, err = input:Slice(1, obj:GetInputSignature():GetMinimumLength())
568+
569+
if not tup then
570+
self:Assert(tup, err)
571+
else
572+
obj:GetInputSignature():Merge(tup)
573+
end
556574
end
557575

558576
do -- this is for the emitter

nattlua/types/tuple.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ function META.Equal(a--[[#: TTuple]], b--[[#: TBaseType]], visited--[[#: Map<|TB
3838
if not ok then break end
3939
end
4040

41+
if not ok then
42+
reason = reason or "unknown reason"
43+
end
44+
4145
return ok, reason
4246
end
4347

test/tests/nattlua/analyzer/type_functions.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,3 +716,16 @@ attest.equal(x, 42 as number | false)
716716
attest.equal(y, "error" as string | nil)
717717
718718
]]
719+
720+
analyze[[
721+
local luadata = {}
722+
luadata.Types = {}
723+
724+
function luadata.SetModifier(type: string, callback: function=(string, number)>(string))
725+
luadata.Types[type] = callback
726+
end
727+
luadata.SetModifier("test", function(x)
728+
attest.equal(x, _ as string)
729+
return tostring(x)
730+
end)
731+
]]

0 commit comments

Comments
 (0)