Fusion icon indicating copy to clipboard operation
Fusion copied to clipboard

Poor typechecking for use functions with UsedAs<T>

Open dphfox opened this issue 1 year ago • 0 comments

<T>(T | {T}) -> T creates a free type when called.

type Use = <T>(UsedAs<T>) -> T
type UsedAs<T> = T | {T} -- approximation of the real type in Fusion

-- only care about the static types, this doesn't need to run
local use: Use = nil :: any
local input: UsedAs<number> = nil :: any

 -- `output` inferred to be a free type, rather than the expected `number`
local output = use(input)

This relates to the currently-suboptimal type inference for use functions.

The new solver doesn't entirely solve for this, though it does give a "yes, technically" kind of answer.

It currently matches T to number | {number} and then substitutes it to get (number | {number} | {number | {number}}) -> number | {number}

I'll make a ticket for it though. We should be able to get it to do some structural matching to try to get the smallest possible type for the instantiation.

(and if we couldn't, that'd actually be a really strong motivator for adding explicit instantiation syntax for all those turbofish-heads out there.)

dphfox avatar Apr 16 '24 14:04 dphfox