teal-language / tl

The compiler for Teal, a typed dialect of Lua
MIT License
2.1k stars 108 forks source link

Regression with `or` on table types from a37f385 #554

Closed euclidianAce closed 2 years ago

euclidianAce commented 2 years ago

The following code now produces an error:

local function ivalues<Value>(t: {any:Value}): function(): Value
   local i = 0
   return function(): Value
      i = i + 1
      return t[i]
   end
end

local list: {string}
for x in ivalues(list or {}) do
   print(x)
end
$ tl check repro.tl
========================================
1 error:
repro.tl:10:23: cannot use operator 'or' for types {string} and {<any type> : Value}

From a quick glance it looks like the empty table type is flowing in from the function argument (due to the generic parameter name there) rather than the other operand of the or.

It's not hard to work around, but seems like an issue.

hishamhm commented 2 years ago

Thank you for the test case!

This is a bit trickier than it seems at first glance because it touches on our (not very well-defined) variance rules. In essence, we're getting here the same error as:

local map: {any:string}
local list: {string}
list = map

...which one could argue both ways whether it should be an error or not. Turns out that, in general, in Teal that currently is an error, but for exp or {} we've been special-casing it for a long time, since it's such a common idiom. What happened is that the flow-typing overrode my special-case hack. So I think we need another hack on top to stop flow-typing on its tracks for exp or {}, which I implemented in 7725d60.