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

Detect functions that never return (and @noreturn annotation)

Open CelticMinstrel opened this issue 2 years ago • 4 comments

Some functions, such as error, never return control to the caller. This can be used to prove that a value is not nil, for example:

function my_function(input)
  local value = input.value or error('Missing value')
  -- The following line would currently raise a "Needs nil check" warning
  -- However, if it was nil at runtime, an error would have been raised and it would never get this far.
  return value:sub(1, 3)
end

It's not just error that can cause this, however. A custom function could be written that never returns as well (the most obvious way is that the function unconditionally calls error, but there may be other ways involving coroutines or functions implemented in C). A @noreturn annotation could be used to indicate this, similar to @nodiscard.

CelticMinstrel avatar Feb 05 '23 23:02 CelticMinstrel

At present, I specially deal with the name error. Otherwise, finding the function definition and checking the annotation may significantly increase the cost.

sumneko avatar Feb 06 '23 06:02 sumneko

Would also love a @noreturn or some other way to have functions other than error treated this way. Currently I'm using local error = util.err to get around this issue but this only works once :) Still better than littering my code with ---@cast [...] -?.

ghost avatar Mar 10 '23 03:03 ghost

I also think @NoReturn annotation would be very useful. In the meantime you can setup your workspace so that custom error/exit functions are recognized as such:

  {
    "Lua.runtime.special": {
      "my_error": "error",
      "my_app.quit": "os.exit"
    }
  }

This matches literally, you can't use aliases here.

kmarius avatar Oct 02 '23 10:10 kmarius

I would really like a type hint such as ---@return never or something to that effect. In an instance where we are doing nil checks such as:

---@return string
function my_custom_function()
  local variable_y = some_method() ---@type string|nil
  if not variable_y then
    logger.error('some error') -- Eventually calls error('some error')
  end
  return variable_y
end

In this instance when attempting to return, the linter still says that I cannot return string|nil because of my original ---@return string. Which is not factually correct. There is no way in my logger.error() method to give a type hint of ---@return never

iamt4nk avatar Jul 18 '25 16:07 iamt4nk