LuaLS / LuaLS/lua-language-server

Request: Limit "Fields cannot be injected" to exact classes

Open
#3,361 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Lua
Stars
4.4k
Forks
442
PR merge metrics
No merged PRs in 30d

Description

### How are you using the lua-language-server?

NeoVim

### Which OS are you using?

Windows

### What is the issue affecting?

Annotations

### Expected Behaviour

The [docs say](https://luals.github.io/wiki/annotations/#class):

> Marking the class as (exact) means fields cannot be injected after the definition.

So when I use `@class`, I expect to not get any injection warnings unless I use `(exact)`. I see this came up before in #2710, so I'd add: I should be able to get a warning for injections in exact classes while silencing warnings in non-exact classes.

### Actual Behaviour

Any time I add a field outside of the constructor (and sometimes even ones that are defined in my class constructor), I get this warning:

> Fields cannot be injected into the reference of `ClassX` for `field_y`. To do so, use `---@class` for `instance_z`.

The `@class` annotation makes lua too strict. I'm using lua because I _want_ to be able to inject fields.

Using annotations has multiple effects:
1. It improves completion.
1. It improves symbol lookups like goto definition.
1. It does type checking.

But it's not great that adding annotations to get 1+2 results in tons of warnings from 3.

I understand that people may not want to add `(exact)` all over their codebase, but I don't want to add `---@field [any] any` to all of mine.

I'd propose a change to diagnostic flags to allow independently controlling these two cases:
* `inject-field`: suppress inject field diagnostic for non-exact classes.
* `inject-field-exact`: suppress inject field diagnostic for exact classes.

### Reproduction steps

Using neovim and installed luals with Mason. Version: `pkg:github/luals/lua-language-server@3.17.1`

```lua
-- Stripped-down version of https://github.com/rxi/classic/blob/master/classic.lua with an annotation added to be close to real-world class usage.
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.

--- @class Object
local Object = {}
Object.__index = Object

function Object:new()
end

function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end

function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
end

-- /end classic

--- @class Item : Object
local Item = Object:extend()

function Item:new(id, category)
self.id = id
self.category = category
self.count = 0
end

function Item:Print()
print("Item", self.id, self.category, self.count)
end

--- @param item Item
function FlagDebugItem(item)
item:Print() -- with the annotation, this completes. Yay!
item.is_cheater = true -- Warning :( "Fields cannot be injected into the reference of `Item` for `is_cheater`."
end
```

If I configure luals to add `inject-field` to the `Lua.diagnostics.disable` list, then the warning goes away. But the warning doesn't come back when I make Item an exact class with this annotation: `--- @class (exact) Item : Object`

**Workaround:** Add a fake field of any type:
```lua
--- @class Item : Object
--- @field [any] any
local Item = Object:extend()
```

### Additional Notes

_No response_

### Log File

```
[WARN][2026-02-23 11:41:41] ...lsp/handlers.lua:564 "More than 100000 files have been scanned. The current scanned directory is `D:\\code\\project\\br`. Please see the [FAQ](https://luals.github.io/wiki/faq/#how-can-i-improve-startup-speeds) to see how you can include fewer files. It is also possible that your [configuration is incorrect](https://luals.github.io/wiki/faq#why-is-the-server-scanning-the-wrong-folder)."
[WARN][2026-02-23 14:32:31] .../lua/vim/lsp.lua:52 "method textDocument/typeDefinition is not supported by any of the servers registered for the current buffer"
[START][2026-02-23 15:29:24] LSP logging initiated
[ERROR][2026-02-23 15:29:24] ...m/lsp/client.lua:620 "LSP[lua_ls]" "Cannot find request with id 125 whilst attempting to cancel"
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided NeoVim reproduction with LuaLS 3.17.1 and compare `@class` with `@class (exact)`. Then trace how the `inject-field` diagnostic is applied; done means non-exact and exact classes can be controlled independently as proposed, while the documented completion and lookup behavior remains available.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.