Globals set with `rawset` are always parsed as a table
LJSonik opened this issue ยท 1 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?
Annotations, Type Checking
Expected Behaviour
I expect x
to be parsed as an integer:
rawset(_G, "x", 42)
print(x) -- x should be parsed as integer here
Actual Behaviour
x
is parsed as integer|table
instead.
Reproduction steps
rawset(_G, "x", 42)
print(x) -- x is parsed as integer|table here
Additional Notes
No response
Log File
No response
Root cause analysis
After some debugging, I found that the table
infer type seems to be inserted by this code block ๐ค:
lua-language-server/script/vm/compiler.lua
Lines 1869 to 1879 in 1831e60
- When compiling a
rawset()
call statement, this code block will be executed. - I believe this logic is to use the return value of the call statement to set the left hand side variable if any (?),
and the return value ofrawset()
is annotated astable
type by built-in meta file:lua-language-server/meta/template/basic.lua
Lines 198 to 202 in 1831e60
- so in the following code snippet
local a = rawset() -- a: table
- But as
rawset(_G, ...)
is handled specially, the created global is treated as the (assignment) value of this call (?):lua-language-server/script/vm/global.lua
Lines 296 to 299 in 1831e60
- This explains why the injected type is always table (the return type of
rawset()
)
Proposed solution
I just tried to skip the logic if it is a rawset
statement, and it worked perfectly ๐
: case 'call'
: call(function (source)
-- ignore rawset
if source.node.special == 'rawset' then
return
end
- I originally afraid that this will break the
local a = rawset()
case, but seems not ๐
a
can still be inferred astable
- All existing tests passed, so no obvious side effects for this proposed change.
I believe this is the solution to this issue. I will try to open a PR for this, along with the proposed changes in #2862 (comment) to resolve these 2 issues together later ๐