diff --git a/spec/statement/return_spec.lua b/spec/statement/return_spec.lua index 86727eb80..b52fc912a 100644 --- a/spec/statement/return_spec.lua +++ b/spec/statement/return_spec.lua @@ -189,4 +189,23 @@ describe("return", function() assert.same({}, result.type_errors) end) + it("does not crash when a return type inference causes an error", util.check_type_error([[ + local type A = record + end + + local type B = record + end + + local function f(): A + end + + local function fail(): A | B + return f() + end + ]], { + -- the duplicated error is not ideal, but it's harmless, and better than a crash + { y = 10, msg = "cannot discriminate a union between multiple table types" }, + { y = 11, msg = "cannot discriminate a union between multiple table types" }, + })) + end) diff --git a/tl.lua b/tl.lua index 1288f5297..1d1a8a20f 100644 --- a/tl.lua +++ b/tl.lua @@ -6234,6 +6234,9 @@ tl.type_check = function(ast, opts) local function infer_at(where, t) local ret = resolve_typevars_at(where, t) + if ret.typename == "invalid" then + ret = t + end ret = (ret ~= t) and ret or shallow_copy_type(t) ret.inferred_at = where ret.inferred_at_file = filename diff --git a/tl.tl b/tl.tl index ecc7ab67e..9bf74695c 100644 --- a/tl.tl +++ b/tl.tl @@ -6234,6 +6234,9 @@ tl.type_check = function(ast: Node, opts: TypeCheckOptions): Result, string local function infer_at(where: Node, t: Type): Type local ret = resolve_typevars_at(where, t) + if ret.typename == "invalid" then + ret = t -- errors are produced by resolve_typevars_at + end ret = (ret ~= t) and ret or shallow_copy_type(t) ret.inferred_at = where ret.inferred_at_file = filename