Skip to content

Commit

Permalink
fix: union specialization with interface subtyping produces a valid type
Browse files Browse the repository at this point in the history
  • Loading branch information
hishamhm committed Jan 27, 2025
1 parent 10edd04 commit f3df905
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
25 changes: 25 additions & 0 deletions spec/lang/operator/is_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -777,4 +777,29 @@ end]]))
print("Result: "..x)
end
]]))

it("union specialization with interface subtyping produces a valid type (regression test)", util.check([[
local interface IA
where self.t == "a"
t: string
end
local interface IB
where self.t == "b"
t: string
end
local record R is IA
where self.t == "r"
rfield: string
end
local t: IA | IB
if t and t is R and t.rfield then
end
]]))
end)
19 changes: 11 additions & 8 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9597,6 +9597,8 @@ a.types[i], b.types[i]), }
end

function TypeChecker:same_in_all_union_entries(u, check)
assert(#u.types > 0)

local t1, f = check(u.types[1])
if not t1 then
return nil
Expand Down Expand Up @@ -10844,16 +10846,17 @@ a.types[i], b.types[i]), }
table.insert(out, t)
end
end
return unite(w, out)
else
if self:is_a(t1, t2) then
return t1
elseif self:is_a(t2, t1) then
return t2
else
return a_type(w, "nil", {})
if #out > 0 then
return unite(w, out)
end
end
if self:is_a(t1, t2) then
return t1
elseif self:is_a(t2, t1) then
return t2
else
return a_type(w, "nil", {})
end
end

function TypeChecker:resolve_if_union(t)
Expand Down
19 changes: 11 additions & 8 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -9597,6 +9597,8 @@ do
end

function TypeChecker:same_in_all_union_entries<T is Type, F is Type>(u: UnionType, check: function(Type): (T, F)): F
assert(#u.types > 0)

local t1, f = check(u.types[1])
if not t1 then
return nil
Expand Down Expand Up @@ -10844,16 +10846,17 @@ do
table.insert(out, t)
end
end
return unite(w, out)
else
if self:is_a(t1, t2) then
return t1
elseif self:is_a(t2, t1) then
return t2
else
return a_type(w, "nil", {}) -- because of implicit nil in all unions
if #out > 0 then
return unite(w, out)
end
end
if self:is_a(t1, t2) then
return t1
elseif self:is_a(t2, t1) then
return t2
else
return a_type(w, "nil", {}) -- because of implicit nil in all unions
end
end

function TypeChecker:resolve_if_union(t: Type): Type
Expand Down

0 comments on commit f3df905

Please sign in to comment.