diff --git a/spec/declaration/nominal_spec.lua b/spec/declaration/nominal_spec.lua new file mode 100644 index 000000000..2f192b809 --- /dev/null +++ b/spec/declaration/nominal_spec.lua @@ -0,0 +1,39 @@ +local util = require("spec.util") + +describe("nominals", function() + it("references get resolved in the same scope", util.check([[ + -- unresolved nominal reference + local has_unr: function(where: Node) + + -- circular type definitions + local type MyFn = function(MyMap) + local type MyMap = {string:MyFn} + + -- above nominal reference gets resolved + local record Node + end + + has_unr = function(where: Node) + print(where) + end + ]])) + + it("references get resolved across scopes", util.check([[ + -- unresolved nominal reference + local has_unr: function(where: Node) + + do + -- circular type definitions + local type MyFn = function(MyMap) + local type MyMap = {string:MyFn} + end + + -- above nominal reference gets resolved + local record Node + end + + has_unr = function(where: Node) + print(where) + end + ]])) +end) diff --git a/tl.lua b/tl.lua index fc41e4bfb..75f620d92 100644 --- a/tl.lua +++ b/tl.lua @@ -8332,14 +8332,17 @@ tl.type_check = function(ast, opts) end local function dismiss_unresolved(name) - local unresolved = st[#st]["@unresolved"] - if unresolved then - if unresolved.t.nominals[name] then - for _, t in ipairs(unresolved.t.nominals[name]) do - resolve_nominal(t) + for i = #st, 1, -1 do + local unresolved = st[i]["@unresolved"] + if unresolved then + if unresolved.t.nominals[name] then + for _, t in ipairs(unresolved.t.nominals[name]) do + resolve_nominal(t) + end + unresolved.t.nominals[name] = nil + return end end - unresolved.t.nominals[name] = nil end end diff --git a/tl.tl b/tl.tl index 6cd53e702..2518d7ec5 100644 --- a/tl.tl +++ b/tl.tl @@ -8332,14 +8332,17 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string end local function dismiss_unresolved(name: string) - local unresolved = st[#st]["@unresolved"] - if unresolved then - if unresolved.t.nominals[name] then - for _, t in ipairs(unresolved.t.nominals[name]) do - resolve_nominal(t) + for i = #st, 1, -1 do + local unresolved = st[i]["@unresolved"] + if unresolved then + if unresolved.t.nominals[name] then + for _, t in ipairs(unresolved.t.nominals[name]) do + resolve_nominal(t) + end + unresolved.t.nominals[name] = nil + return end end - unresolved.t.nominals[name] = nil end end