Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* `FIX` reimplement section `luals.config` in file doc.json
* `FIX` incorrect file names in file doc.json
* `FIX` remove extra `./` path prefix in the check report when using `--check=.`
* `FIX` Narrowing of types with literal fields: [#3056](https://github.com/LuaLS/lua-language-server/issues/3056), [#3089](https://github.com/LuaLS/lua-language-server/issues/3089)

## 3.13.6
`2025-2-6`
Expand Down
13 changes: 9 additions & 4 deletions script/vm/tracer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ local function getNodeTypesWithLiteralField(uri, source, fieldName, literal)
return
end

-- Literal must has a value
if literal[1] == nil then
return
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is only reachable when literal.type = 'nil'.

end

local tys

for _, c in ipairs(vm.compileNode(loc)) do
Expand All @@ -277,10 +282,10 @@ local function getNodeTypesWithLiteralField(uri, source, fieldName, literal)
for _, f in ipairs(set.fields) do
if f.field[1] == fieldName then
for _, t in ipairs(f.extends.types) do
if t[1] == literal[1] then
tys = tys or {}
table.insert(tys, {set.class[1], #f.extends.types > 1})
break
if guide.isLiteral(t) and t[1] ~= nil and t[1] == literal[1] then
tys = tys or {}
table.insert(tys, { set.class[1], #f.extends.types > 1 })
break
end
end
break
Expand Down
14 changes: 14 additions & 0 deletions test/diagnostics/need-check-nil.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,17 @@ end

x()
]]

-- #3056
TEST [[
---@class A
---@field b string
---@field c 'string'|string1'
---@field d 0|1|2

---@type A?
local a

if <!a!>.b == "string1" then end
if <!a!>.b == "string" then end
]]
25 changes: 25 additions & 0 deletions test/type_inference/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4606,6 +4606,31 @@ local a = {}
function a:func(<?x?>) end
]]

-- #3089
TEST 'fun(x: number, y: number)' [[
---@class Person
---@field age? number
---@field foo fun(x: number, y: number)

---@param person Person
local function test(person)
if person.foo ~= nil then
local <?b?> = person.foo
end
end
]]

-- #2952
TEST 'A' [[
---@class A
---@field b {[C]:D}
local A

if A.b ~= {} then
local C = <?A?>
end
]]

TEST 'A' [[
---@class A
---@field type 'a'
Expand Down