summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/diagnostics/assign-type-mismatch.lua15
-rw-r--r--script/vm/compiler.lua10
-rw-r--r--script/vm/node.lua19
-rw-r--r--test/diagnostics/type-check.lua14
-rw-r--r--test/hover/init.lua2
5 files changed, 46 insertions, 14 deletions
diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua
index ae4b3512..b7d11226 100644
--- a/script/core/diagnostics/assign-type-mismatch.lua
+++ b/script/core/diagnostics/assign-type-mismatch.lua
@@ -38,14 +38,13 @@ return function (uri, callback)
end
end
local valueNode = vm.compileNode(value)
- if source.type == 'setindex'
- and vm.isSubType(uri, valueNode, 'nil') then
- -- boolean[1] = nil
- local tnode = vm.compileNode(source.node)
- for n in tnode:eachObject() do
- if n.type == 'doc.type.array'
- or n.type == 'doc.type.table'
- or n.type == 'table' then
+ if source.type == 'setindex'
+ or source.type == 'setfield'
+ or source.type == 'tablefield'
+ or source.type == 'tableindex' then
+ if valueNode:hasName 'nil' then
+ valueNode = valueNode:copy():removeOptional()
+ if valueNode:isEmpty() then
return
end
end
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 5ebf624c..27ba6273 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -1383,13 +1383,13 @@ local compilerSwitch = util.switch()
local uri = guide.getUri(source)
local value = vm.getTableValue(uri, vm.compileNode(source.node), key)
if value then
- vm.setNode(source, value)
+ vm.setNode(source, value):removeOptional()
end
else
vm.compileByParentNode(source.node, key, false, function (src)
vm.setNode(source, vm.compileNode(src))
if src.value then
- vm.setNode(source, vm.compileNode(src.value))
+ vm.setNode(source, vm.compileNode(src.value)):removeOptional()
end
end)
end
@@ -1403,7 +1403,7 @@ local compilerSwitch = util.switch()
vm.compileByParentNode(source.node, key, false, function (src)
if src.type == 'doc.type.field'
or src.type == 'doc.field' then
- vm.setNode(source, vm.compileNode(src))
+ vm.setNode(source, vm.compileNode(src)):removeOptional()
end
end)
end)
@@ -1433,13 +1433,13 @@ local compilerSwitch = util.switch()
if src.type == 'doc.field'
or src.type == 'doc.type.field' then
hasMarkDoc = true
- vm.setNode(source, vm.compileNode(src))
+ vm.setNode(source, vm.compileNode(src)):removeOptional()
end
end)
end
if not hasMarkDoc and source.value then
- vm.setNode(source, vm.compileNode(source.value))
+ vm.setNode(source, vm.compileNode(source.value)):removeOptional()
end
end)
diff --git a/script/vm/node.lua b/script/vm/node.lua
index 8ed5c027..65a203f8 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -81,6 +81,7 @@ end
function mt:removeOptional()
self:remove 'nil'
+ return self
end
---@return boolean
@@ -293,6 +294,24 @@ function mt:hasType(name)
return false
end
+---@param name string
+---@return boolean
+function mt:hasName(name)
+ if name == 'nil' and self.optional == true then
+ return true
+ end
+ for _, c in ipairs(self) do
+ if c.type == 'global' and c.cate == 'type' and c.name == name then
+ return true
+ end
+ if c.type == name then
+ return true
+ end
+ -- TODO
+ end
+ return false
+end
+
---@return fun():vm.object
function mt:eachObject()
local i = 0
diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua
index afd0a5b6..6b2c522f 100644
--- a/test/diagnostics/type-check.lua
+++ b/test/diagnostics/type-check.lua
@@ -366,5 +366,19 @@ local t
---@cast t <!number!>
]]
+TEST [[
+local n
+
+if G then
+ n = {}
+else
+ n = nil
+end
+
+local t = {
+ x = n,
+}
+]]
+
config.remove(nil, 'Lua.diagnostics.disable', 'unused-local')
config.remove(nil, 'Lua.diagnostics.disable', 'undefined-global')
diff --git a/test/hover/init.lua b/test/hover/init.lua
index a97cf3ae..0ee62c1b 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -772,7 +772,7 @@ local <?t?> = {
]]
[[
local t: {
- f?: file*,
+ f: file*,
}
]]