Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix is inference taking into account that unions imply nil #699

Merged
merged 1 commit into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions spec/inference/if_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,17 @@ describe("flow typing in 'if' statements", function()
]], {
{ msg = "cannot use operator '+' for types integer | boolean | string and integer" },
}))

-- see also pending test "detects empty unions" in spec/operators/is_spec.lua
it("detects a union value to be nil if all types are exhausted (regression test for #695)", util.check_warnings([[
global function f2(val: string|number)
if val is string then
print(val)
elseif val is number then
print(val)
else
error("string or number expected")
end
end
]], {}, {}))
end)
3 changes: 2 additions & 1 deletion spec/operator/is_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ describe("flow analysis with is", function()
{ y = 5, msg = [[cannot use operator '+' for types string (inferred at foo.tl:4:10) and integer]] },
}))

it("detects empty unions", util.check_type_error([[
-- this is not an empty union because `number | string` implies nil.
pending("detects empty unions", util.check_type_error([[
local t: number | string
if t is number then
t = t + 1
Expand Down
7 changes: 4 additions & 3 deletions tl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8238,7 +8238,7 @@ tl.type_check = function(ast, opts)
elseif is_a(t2, t1) then
return t2
else
return INVALID
return NIL
end
end
end
Expand Down Expand Up @@ -8279,7 +8279,7 @@ tl.type_check = function(ast, opts)
end

if #types == 0 then
return INVALID
return NIL
end

return unite(types)
Expand Down Expand Up @@ -8403,7 +8403,8 @@ tl.type_check = function(ast, opts)
end
if typ.typename ~= "typevar" then
if is_a(typ, f.typ) then
node_warning("branch", f.where, f.var .. " (of type %s) is always a %s", show_type(typ), show_type(f.typ))


return { [f.var] = f }
elseif not is_a(f.typ, typ) then
node_error(f.where, f.var .. " (of type %s) can never be a %s", typ, f.typ)
Expand Down
7 changes: 4 additions & 3 deletions tl.tl
Original file line number Diff line number Diff line change
Expand Up @@ -8238,7 +8238,7 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
elseif is_a(t2, t1) then
return t2
else
return INVALID
return NIL -- because of implicit nil in all unions
end
end
end
Expand Down Expand Up @@ -8279,7 +8279,7 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
end

if #types == 0 then
return INVALID
return NIL -- because of implicit nil in all unions
end

return unite(types)
Expand Down Expand Up @@ -8403,7 +8403,8 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string
end
if typ.typename ~= "typevar" then
if is_a(typ, f.typ) then
node_warning("branch", f.where, f.var .. " (of type %s) is always a %s", show_type(typ), show_type(f.typ))
-- drop this warning because of implicit nil in all unions
-- node_warning("branch", f.where, f.var .. " (of type %s) is always a %s", show_type(typ), show_type(f.typ))
return { [f.var] = f }
elseif not is_a(f.typ, typ) then
node_error(f.where, f.var .. " (of type %s) can never be a %s", typ, f.typ)
Expand Down
Loading