Skip to content

Commit

Permalink
fix: resolve self correctly in methods
Browse files Browse the repository at this point in the history
Fixes #812.
  • Loading branch information
hishamhm committed Oct 12, 2024
1 parent d9911eb commit ba54466
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
22 changes: 22 additions & 0 deletions spec/lang/operator/colon_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
local util = require("spec.util")

describe(":", function()
describe("on self", function()
it("can resolve methods (regression test for #812)", util.check([[
local interface A
get_type: function(A): string
end
local interface B is A where self:get_type() == "b"
end
local b: A = {
get_type = function(): string return "b" end
}
if b is B then
print("woaw")
end
]]))
end)
end)
18 changes: 11 additions & 7 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8481,12 +8481,8 @@ do
if not t then
return a_type(w, "invalid", {})
end

if t.typename == "typedecl" then
t = t.def
end

return t
assert(t.typename == "typedecl")
return t.def
end


Expand Down Expand Up @@ -9431,7 +9427,11 @@ a.types[i], b.types[i]), }
check_call = function(self, w, wargs, f, args, expected_rets, cm, argdelta)
local arg1 = args.tuple[1]
if cm == "method" and arg1 then
self:add_var(nil, "@self", a_type(w, "typedecl", { def = arg1 }))
local selftype = arg1
if selftype.typename == "self" then
selftype = self:type_of_self(selftype)
end
self:add_var(nil, "@self", a_type(w, "typedecl", { def = selftype }))
end

local fargs = f.args.tuple
Expand Down Expand Up @@ -9661,6 +9661,10 @@ a.types[i], b.types[i]), }

tbl = self:to_structural(tbl)

if tbl.typename == "self" then
tbl = self:type_of_self(tbl)
end

if tbl.typename == "string" or tbl.typename == "enum" then
tbl = self:find_var_type("string")
end
Expand Down
18 changes: 11 additions & 7 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -8481,12 +8481,8 @@ do
if not t then
return an_invalid(w)
end

if t is TypeDeclType then
t = t.def
end

return t
assert(t is TypeDeclType)
return t.def
end

-- ∃ x ∈ xs. t <: x
Expand Down Expand Up @@ -9431,7 +9427,11 @@ do
check_call = function(self: TypeChecker, w: Where, wargs: {Where}, f: FunctionType, args: TupleType, expected_rets: TupleType, cm: CallMode, argdelta: integer): boolean, {Error}
local arg1 = args.tuple[1]
if cm == "method" and arg1 then
self:add_var(nil, "@self", a_typedecl(w, arg1))
local selftype = arg1
if selftype is SelfType then
selftype = self:type_of_self(selftype)
end
self:add_var(nil, "@self", a_typedecl(w, selftype))
end

local fargs = f.args.tuple
Expand Down Expand Up @@ -9661,6 +9661,10 @@ do

tbl = self:to_structural(tbl)

if tbl is SelfType then
tbl = self:type_of_self(tbl)
end

if tbl is StringType or tbl is EnumType then
tbl = self:find_var_type("string") -- simulate string metatable
end
Expand Down

0 comments on commit ba54466

Please sign in to comment.