Skip to content

Commit

Permalink
fix: don't mistake __index for an incorrect method use
Browse files Browse the repository at this point in the history
Fixes #680.
  • Loading branch information
hishamhm committed Jul 17, 2023
1 parent 1001811 commit d4b1763
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
14 changes: 14 additions & 0 deletions spec/metamethods/index_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,18 @@ describe("metamethod __index", function()
]], {
{ y = 7, msg = "in assignment: argument 2: got string, expected number" }
}))

it("passes regression test for #680", util.check([[
local record R
metamethod __index: function(self: R, key: string): any
end
function R:brackets()
print(self["x"])
end
function R:dot()
print(self.x)
end
]]))
end)
9 changes: 6 additions & 3 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7546,9 +7546,12 @@ tl.type_check = function(ast, opts)
local f = is_func and func or func.types[i]
if f.is_method and not is_method then
if args[1] and is_a(args[1], f.args[1]) then
local receiver_is_typetype = where.e1.e1 and where.e1.e1.type and where.e1.e1.type.resolved and where.e1.e1.type.resolved.typename == "typetype"
if not receiver_is_typetype then
node_warning("hint", where, "invoked method as a regular function: consider using ':' instead of '.'")

if where.kind == "op" and where.op.op == "@funcall" then
local receiver_is_typetype = where.e1.e1 and where.e1.e1.type and where.e1.e1.type.resolved and where.e1.e1.type.resolved.typename == "typetype"
if not receiver_is_typetype then
node_warning("hint", where, "invoked method as a regular function: consider using ':' instead of '.'")
end
end
else
return node_error(where, "invoked method as a regular function: use ':' instead of '.'")
Expand Down
9 changes: 6 additions & 3 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -7546,9 +7546,12 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
local f = is_func and func or func.types[i]
if f.is_method and not is_method then
if args[1] and is_a(args[1], f.args[1]) then
local receiver_is_typetype = where.e1.e1 and where.e1.e1.type and where.e1.e1.type.resolved and where.e1.e1.type.resolved.typename == "typetype"
if not receiver_is_typetype then
node_warning("hint", where, "invoked method as a regular function: consider using ':' instead of '.'")
-- a non-"@funcall" `where` means a synthesized call, e.g. from a metamethod
if where.kind == "op" and where.op.op == "@funcall" then
local receiver_is_typetype = where.e1.e1 and where.e1.e1.type and where.e1.e1.type.resolved and where.e1.e1.type.resolved.typename == "typetype"
if not receiver_is_typetype then
node_warning("hint", where, "invoked method as a regular function: consider using ':' instead of '.'")
end
end
else
return node_error(where, "invoked method as a regular function: use ':' instead of '.'")
Expand Down

0 comments on commit d4b1763

Please sign in to comment.