teal-language / tl

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

Type alias for nested generic crashes compiler #754

Open Zipperdoodle opened 1 week ago

Zipperdoodle commented 1 week ago

Hi, I reduced the issue down to the following.

This works:

local record MyGenericRecord<T>
    Data: T
end

local enum MyEnum
    "foo"
    "bar"
end

local type MyAlias = MyGenericRecord<MyEnum>

But this doesn't:

local record MyNamespace
    record MyGenericRecord<T>
        Data: T
    end
end

local enum MyEnum
    "foo"
    "bar"
end

local type MyAlias = MyNamespace.MyGenericRecord<MyEnum>

The latter version crashes the compiler with the following runtime error: tl.lua:4273: bad argument #1 to 'concat' (table expected, got nil)

Here is the relevant code section in tl.lua:

["newtype"] = {
         after = function(node, _children)
            local out = { y = node.y, h = 0 }
            if node.is_alias then
               table.insert(out, table.concat(node.newtype.def.names, "."))
            elseif is_record_type(node.newtype.def) then
               table.insert(out, print_record_def(node.newtype.def))
            else
               table.insert(out, "{}")
            end
            return out
         end,
Zipperdoodle commented 5 days ago

Never mind. Aliasing is broken anyway. Even if I don't use nested types, I can't alias a generic into a specific type and have the type checker accept it as an alias. It just sees it as a altogether different type.

This also means that coding with generics becomes very unwieldy very quickly. Because you have to write out the whole mess all the time making the code all but unreadable and unmaintainable. Makes it very tempting to slap on some kind of macro preprocessor that does simple template substitution, as that would be better than this.