Skip to content

nil type not being added/removed properly in nested class usage situation #1320

@muppet9010

Description

@muppet9010

I have found that in a specific case the nil type isn't being correctly removed and re-added to a variables type list.

See the comments below in an abstracted example of the issue:

---@class data
---@field things table<integer, thing>

---@class thing
---@field child child

---@class child
---@field test test

---@class test
---@field valid boolean
---@field value number

---@type data
local data = {
    things = {
        {
            child = {
                test = {
                    value = 0.1,
                    valid = false
                }
            }
        },
        {
            child = {
                test = {
                    value = 2,
                    valid = false
                }
            }
        }
    }
}

local x  ---@type thing|nil
local index  ---@type integer|nil
while x == nil do
    index = next(data.things)
    x = data.things[index]

    if x == nil then
        -- no new data found
        return
    end

    if not x.child.test.valid then -- x should not have nil as a possible type here. In my live code this gives a "need-check-nil" warning.
        -- not valid so discard it from the list
        data.things[index] = nil
        x = nil
    end

    local checkXType = x -- This should have x as: thing|nil
end

local textToPrint = x.child.test.value -- x should not have nil as a possible type here. In my live code this gives a "need-nil-check" warning.

In my live code the incorrect nil being on the type causes the need-nil-check warnings. But in the test it doesn't despite the class structure being equivalent for some reason. However, when you hover on the variables at the commented points it does show the incorrect nil type listed.

I tried adding a ---@cast - nil to remove the nil state, but then it didn't get added back after I set x = nil again in the if block. And when I used a ---@cast + nil there to try and correct this it cancelled out the - nil done earlier.

While trying to reproduce this outside of my code I found with a much simplier data structure the issue didn't occur, so nt sure if its caused by the nested classes confusing it somehow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions