tl icon indicating copy to clipboard operation
tl copied to clipboard

cannot match types if union is behind a type alias

Open Frityet opened this issue 1 year ago • 3 comments

local type nilable<T> = T | nil
local function divide(a: number, b: number): nilable<number>, nilable<string>
    if b == 0 then
        return nil, "division by zero"
    end
    return a / b, nil
end

local x, err = divide(10, 2)
if err is nil and not x is nil then
    print("Result: "..x)
else
    print("Error: "..err)
end

Results in x being inferred as nil, and err being inferred as nilable<string>. I am using the next branch.

Frityet avatar Aug 21 '24 07:08 Frityet

Can you reproduce this with types other than nil? Teal does not support discriminating nil in unions, so you cannot implement nil-strictness by hand, it will need to be added to the language eventually.

hishamhm avatar Aug 21 '24 10:08 hishamhm

I've confirmed this misbehavior with a non-nil-related minimized example

local type Maybe<T> = T | boolean
local x: Maybe<string>
if not x is boolean then
    print("Result: "..x)
end

hishamhm avatar Aug 21 '24 12:08 hishamhm

Note to self: the solution to this bug is that union types need to be handled as generic types the same way as functions and records currently are — that is, the type object for the union needs to store type variables, so that resolve_decl_into_nominal can run match_typevals on it correctly — my current plan is to solve this by generalizing all generic types into a single internal $\Lambda$ type, so that we can do beta-reduction at the type level like $(Λα.t^α)(T) \rightarrow t[α := T]$.

hishamhm avatar Oct 13 '24 04:10 hishamhm