Closed fperrad closed 9 months ago
The error is not spurious: if the type is A|B
, and you have branches already covering cases for both A
and B
, the third branch is unreachable: there is no valid type inferrable for var
in that branch.
The error is not spurious: if the type is
A|B
, and you have branches already covering cases for bothA
andB
, the third branch is unreachable: there is no valid type inferrable forvar
in that branch.
considering that teal uses lua's type
function to work with the is
syntax, and that every value in teal can be nil
regardless of type, shouldn't the type be nil
in the else branch?
after adding a explicit nil
in union, tl
gives the same kind of error & warnings
$ cat union2.tl
global function f1(val: string|nil)
if val is string then -- warning: val (of type string | nil) is always a string
print(val)
else
error("string expected")
end
end
global function f2(val: string|number|nil)
if val is string then
print(val)
elseif val is number then -- warning: val (of type number (inferred at ...)) is always a number
print(val)
else -- ERROR: cannot resolve a type for val here
error("string or number expected")
end
end
$ tl check union2.tl
========================================
2 warnings:
union2.tl:2:12: val (of type string | nil) is always a string
union2.tl:12:16: val (of type number (inferred at union2.tl:12:5)) is always a number
========================================
1 error:
union2.tl:14:5: cannot resolve a type for val here
but when adding a any
, tl
is happy.
$ cat union3.tl
global function f1(val: string|any)
if val is string then
print(val)
else
error("string expected")
end
end
global function f2(val: string|number|any)
if val is string then
print(val)
elseif val is number then
print(val)
else
error("string or number expected")
end
end
$ tl check union3.tl
========================================
Type checked union3.tl
0 errors detected -- you can use:
...
considering that teal uses lua's type function to work with the is syntax, and that every value in teal can be nil regardless of type, shouldn't the type be nil in the else branch?
@lenscas fair point! I stand corrected.
after adding a explicit nil in union, tl gives the same kind of error & warnings
Because nil
is currently implied in every type, X|nil
is currently equivalent(-ish?*
) to X
, so this result doesn't suprise me.
But I agree that the behavior you described in the issue needs changing, at the very least to make the behavior of f1
and f2
consistent, and ideally, to make the else
block of f2
infer val
to nil
.
(*
I admit I don't have the precise semantics for that off the top of my head, which is a strong indicator that the current semantics are not ideal — I know, I know, we'll get rid of nil-everywhere eventually...)