diff options
-rw-r--r-- | meta/template/basic.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/param-type-mismatch.lua | 33 | ||||
-rw-r--r-- | script/vm/type.lua | 5 | ||||
-rw-r--r-- | test/diagnostics/type-check.lua | 16 |
4 files changed, 45 insertions, 13 deletions
diff --git a/meta/template/basic.lua b/meta/template/basic.lua index 268d6539..6a89fb01 100644 --- a/meta/template/basic.lua +++ b/meta/template/basic.lua @@ -215,8 +215,8 @@ function setfenv(f, table) end function setmetatable(table, metatable) end ---#DES 'tonumber' ----@overload fun(e: string|number, base: integer):integer? ----@param e string|number +---@overload fun(e: string, base: integer):integer +---@param e any ---@return number? ---@nodiscard function tonumber(e) end diff --git a/script/core/diagnostics/param-type-mismatch.lua b/script/core/diagnostics/param-type-mismatch.lua index a05b03e4..e4917456 100644 --- a/script/core/diagnostics/param-type-mismatch.lua +++ b/script/core/diagnostics/param-type-mismatch.lua @@ -42,20 +42,31 @@ return function (uri, callback) await.delay() local funcNode = vm.compileNode(source.node) for i, arg in ipairs(source.args) do + if i == 1 and source.node.type == 'getmethod' then + goto CONTINUE + end local refNode = vm.compileNode(arg) local defNode = getDefNode(funcNode, i) - if defNode then - if not vm.canCastType(uri, defNode, refNode) then - callback { - start = arg.start, - finish = arg.finish, - message = lang.script('DIAG_PARAM_TYPE_MISMATCH', { - def = vm.getInfer(defNode):view(uri), - ref = vm.getInfer(refNode):view(uri), - }) - } - end + if not defNode then + goto CONTINUE + end + if arg.type == 'getfield' + or arg.type == 'getindex' then + -- 由于无法对字段进行类型收窄, + -- 因此将假值移除再进行检查 + refNode = refNode:copy():setTruthy() + end + if not vm.canCastType(uri, defNode, refNode) then + callback { + start = arg.start, + finish = arg.finish, + message = lang.script('DIAG_PARAM_TYPE_MISMATCH', { + def = vm.getInfer(defNode):view(uri), + ref = vm.getInfer(refNode):view(uri), + }) + } end + ::CONTINUE:: end end) end diff --git a/script/vm/type.lua b/script/vm/type.lua index 982f937d..d8adac6e 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -58,6 +58,11 @@ function vm.isSubType(uri, child, parent, mark) return false end end + if child:isOptional() then + if not vm.isSubType(uri, 'nil', parent, mark) then + return false + end + end return true end diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua index 6b2c522f..147d6229 100644 --- a/test/diagnostics/type-check.lua +++ b/test/diagnostics/type-check.lua @@ -380,5 +380,21 @@ local t = { } ]] +TEST [[ +---@class A + +---@param n A +local function f(n) +end + +---@class B +local a = {} + +---@type A? +a.x = XX + +f(a.x) +]] + config.remove(nil, 'Lua.diagnostics.disable', 'unused-local') config.remove(nil, 'Lua.diagnostics.disable', 'undefined-global') |