lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

`need-check-nil` when nil check is done in a function

Open Rathoz opened this issue 3 years ago • 3 comments

How are you using the lua-language-server?

Visual Studio Code Extension (sumneko.lua)

Which OS are you using?

Windows

What is the issue affecting?

Type Checking

Expected Behaviour

No type checking errors

Actual Behaviour

Need check nil.Lua Diagnostics.(need-check-nil) on the :lower()

Reproduction steps

Simplified case with the issue

---@param str string?
---@return boolean
local function isEmpty(str)
	return str == nil or str == ''
end

---@param input string?
---@return string?
local function myFunc(input)
	if isEmpty(input) then
		return
	end
	return input:lower()
end

Additional Notes

No response

Log File

No response

Rathoz avatar Aug 02 '22 13:08 Rathoz

I also often use this feature and do not want to give it up.

--- - **string** == "" -> **`true`**
--- - **number** -> **`false`**
--- - **boolean** -> **`false`**
--- - **nil** -> **`true`**
--- - **function** -> **`false`**
--- - **#table == 0** or **table:count() == 0** -> **`true`**
---@overload fun(value: string) : boolean
---@overload fun(value: number) : boolean
---@overload fun(value: nil) : boolean
---@overload fun(value: boolean) : boolean
---@overload fun(value: function) : boolean
---@overload fun(value: table) : boolean
function Core.IsEmpty(value) end

RomanSpector avatar Aug 02 '22 22:08 RomanSpector

Add ---@cast input -nil above return input:lower() and the type checking will work as desired:

Fix
---@param str string?
---@return boolean
local function isEmpty(str)
	return str == nil or str == ''
end

---@param input string?
---@return string?
local function myFunc(input)
	if isEmpty(input) then
		return
	end
    ---@cast input -nil
	return input:lower()
end

The server is not able to follow the function and confirm that input is not nil.

carsakiller avatar Aug 02 '22 23:08 carsakiller

If the isEmpty annotations are changed from

---@param str string?
---@return boolean
local function isEmpty(str)
	return str == nil or str == ''
end

to

---@param str string
---@return boolean
---@overload fun(str: nil) : true
local function isEmpty(str)
	return str == nil or str == ''
end

Would that make it easier to add the functionality to the LSP? Adding a cast after every call to an isEmpty would uglify the code quite a lot. image

Rathoz avatar Aug 03 '22 09:08 Rathoz