diff --git a/spec/declaration/local_spec.lua b/spec/declaration/local_spec.lua index a141056f3..cd7eb9ee7 100644 --- a/spec/declaration/local_spec.lua +++ b/spec/declaration/local_spec.lua @@ -551,4 +551,11 @@ describe("local", function() { tag = "redeclaration", msg = "variable shadows previous declaration of 'integer'" }, { tag = "unused", msg = "unused type integer" }, })) + + it("does not accept type arguments declared twice", util.check_syntax_error([[ + local type Foo = record + end + ]], { + { y = 1, msg = "cannot declare type arguments twice in type declaration" }, + })) end) diff --git a/tl.lua b/tl.lua index 7721c0c60..a249f7ef8 100644 --- a/tl.lua +++ b/tl.lua @@ -4049,6 +4049,7 @@ do return fail(ps, i, "expected a type name") end local typeargs + local itypeargs = i if ps.tokens[i].tk == "<" then i, typeargs = parse_anglebracket_list(ps, i, parse_typearg) end @@ -4090,11 +4091,22 @@ do local nt = asgn.value.newtype if nt.typename == "typedecl" then + local def = nt.def + if typeargs then - nt.typeargs = typeargs + if def.typeargs then + if def.typeargs then + fail(ps, itypeargs, "cannot declare type arguments twice in type declaration") + else + def.typeargs = typeargs + end + else + + + nt.typeargs = typeargs + end end - local def = nt.def if def.fields or def.typename == "enum" then if not def.declname then def.declname = asgn.var.tk diff --git a/tl.tl b/tl.tl index f23eaf146..680a947b3 100644 --- a/tl.tl +++ b/tl.tl @@ -4049,6 +4049,7 @@ parse_type_declaration = function(ps: ParseState, i: integer, node_name: NodeKin return fail(ps, i, "expected a type name") end local typeargs: {TypeArgType} + local itypeargs = i if ps.tokens[i].tk == "<" then i, typeargs = parse_anglebracket_list(ps, i, parse_typearg) end @@ -4090,11 +4091,22 @@ parse_type_declaration = function(ps: ParseState, i: integer, node_name: NodeKin local nt = asgn.value.newtype if nt is TypeDeclType then + local def = nt.def + if typeargs then - nt.typeargs = typeargs + if def is HasTypeArgs then + if def.typeargs then + fail(ps, itypeargs, "cannot declare type arguments twice in type declaration") + else + def.typeargs = typeargs + end + else + -- FIXME how to resolve type arguments in unions properly + -- fail(ps, itypeargs, def.typename .. " does not accept type arguments") + nt.typeargs = typeargs + end end - local def = nt.def if def is RecordLikeType or def is EnumType then if not def.declname then def.declname = asgn.var.tk