Skip to content

Commit

Permalink
fix: type inference with if x == nil or ...
Browse files Browse the repository at this point in the history
Thanks @svermeulen for the testcase!

Fixes #823.
  • Loading branch information
hishamhm committed Oct 16, 2024
1 parent e240869 commit e457d38
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions spec/lang/operator/is_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe("flow analysis with is", function()
end
]], {
{ y = 1, msg = "unknown type b"},
{ y = 2, msg = "cannot resolve a type for x here"},
{ y = 2, msg = "unknown variable: x"},
{ y = 2, msg = "cannot resolve a type for x here"},
}))
Expand Down
13 changes: 13 additions & 0 deletions spec/lang/operator/or_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ describe("or", function()
end
]]))

it("resolves the negation of 'or' with '== nil' when 'if' returns (regression test for #823)", util.check([[
local function foo(bar:string):boolean
if bar == nil or #bar == 0 then
return true
end
print(bar:upper())
return false
end
foo("asdf")
]]))

it("resolves the negation of 'or' when 'if' returns, error case with interface", util.check_type_error([[
local interface Type
t: string
Expand Down
2 changes: 1 addition & 1 deletion tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10487,7 +10487,7 @@ a.types[i], b.types[i]), }
elseif f.fact == "and" and f.f2 and f.f2.fact == "truthy" then
return eval_not(self, f.f1)
elseif f.fact == "or" and f.f2 and f.f2.fact == "truthy" then
return eval_fact(self, f.f1)
return eval_not(self, f.f1)
elseif f.fact == "and" then
return or_facts(self, eval_not(self, f.f1), eval_not(self, f.f2))
elseif f.fact == "or" then
Expand Down
2 changes: 1 addition & 1 deletion tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -10487,7 +10487,7 @@ do
elseif f is AndFact and f.f2 and f.f2.fact == "truthy" then
return eval_not(self, f.f1)
elseif f is OrFact and f.f2 and f.f2.fact == "truthy" then
return eval_fact(self, f.f1)
return eval_not(self, f.f1)
elseif f is AndFact then
return or_facts(self, eval_not(self, f.f1), eval_not(self, f.f2))
elseif f is OrFact then
Expand Down

0 comments on commit e457d38

Please sign in to comment.