diff --git a/changelog.md b/changelog.md index 11725d30c..30b57dfff 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,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) * `FIX` correct lua version of `math.ult` and `math.type` * `FIX` incorrect links for `pattern` in `string` methods * `FIX` fix type annotations for bit module diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua index 90be14625..ee76da2ac 100644 --- a/script/vm/tracer.lua +++ b/script/vm/tracer.lua @@ -268,6 +268,11 @@ local function getNodeTypesWithLiteralField(uri, source, fieldName, literal) return end + -- Literal must has a value + if literal[1] == nil then + return + end + local tys for _, c in ipairs(vm.compileNode(loc)) do @@ -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 diff --git a/test/diagnostics/need-check-nil.lua b/test/diagnostics/need-check-nil.lua index c4e3bba65..3580d7cbb 100644 --- a/test/diagnostics/need-check-nil.lua +++ b/test/diagnostics/need-check-nil.lua @@ -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 .b == "string1" then end +if .b == "string" then end +]] diff --git a/test/type_inference/common.lua b/test/type_inference/common.lua index 268f492b4..8376396ac 100644 --- a/test/type_inference/common.lua +++ b/test/type_inference/common.lua @@ -4606,6 +4606,31 @@ local a = {} function a:func() 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 = person.foo + end +end +]] + +-- #2952 +TEST 'A' [[ +---@class A +---@field b {[C]:D} +local A + +if A.b ~= {} then + local C = +end +]] + TEST 'A' [[ ---@class A ---@field type 'a'