diff --git a/spec/lang/declaration/local_function_spec.lua b/spec/lang/declaration/local_function_spec.lua index b953747d..3400468d 100644 --- a/spec/lang/declaration/local_function_spec.lua +++ b/spec/lang/declaration/local_function_spec.lua @@ -1,4 +1,3 @@ -local tl = require("tl") local util = require("spec.util") describe("local function", function() @@ -21,6 +20,16 @@ describe("local function", function() local ok = f(3, "abc") ]])) + it("can have type variables with constraints", util.check([[ + local type F = function(any...): any... + + local function partial(f: T, a: any): T + return function(...: any): any... + return f(a, ...) + end + end + ]])) + it("cannot have unused type variables", util.check_type_error([[ local function f(a: number, b: string): () return diff --git a/tl.lua b/tl.lua index 26216861..cbcfb863 100644 --- a/tl.lua +++ b/tl.lua @@ -8408,8 +8408,11 @@ do function TypeChecker:to_structural(t) assert(not (t.typename == "tuple")) + if t.typename == "typevar" and t.constraint then + t = t.constraint + end if t.typename == "nominal" then - return self:resolve_nominal(t) + t = self:resolve_nominal(t) end return t end diff --git a/tl.tl b/tl.tl index f4d8d47b..25ef5faa 100644 --- a/tl.tl +++ b/tl.tl @@ -8408,8 +8408,11 @@ do function TypeChecker:to_structural(t: Type): Type assert(not t is TupleType) + if t is TypeVarType and t.constraint then + t = t.constraint + end if t is NominalType then - return self:resolve_nominal(t) + t = self:resolve_nominal(t) end return t end