LuaLS / lua-language-server

A language server that offers Lua language support - programmed in Lua
https://luals.github.io
MIT License
3.14k stars 290 forks source link

Type is "lost" of variable within For Loop #2374

Open muppet9010 opened 9 months ago

muppet9010 commented 9 months ago

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

A variable shouldn't loose its type when being set in a For Loop to another string. The variable is initialised outside of the For Loop.

Actual Behaviour

The variable seems to have lost its type after the For Loop when being set in a For Loop to another string.

Reproduction steps

Paste the sample code below.

--- Pad a number with leading 0's up to the required length and return as a string.
---@param number double
---@param requiredLength uint
---@return string paddedNumber
StringUtils.PadNumberToMinimumDigits = function(number, requiredLength)
    local negativeNumber = false
    if number < 0 then
        negativeNumber = true
        number = 0 - number
    end
    local numberString = tostring(number)
    local shortBy = requiredLength - string_len(numberString)
    for _ = 1, shortBy do
        numberString = "0" .. numberString
    end
    if negativeNumber then
-- ISSUE: `numberString` has lost its type here.
        numberString = "-" .. numberString
    end
    return numberString
end

By the end of the function the variable numberString will have lost its type and be unknown. But in all the places we set the variables value it's being set to a string.

image

Additional Notes

No response

Log File

[23:51:57.944][warn] [#0:script\plugin.lua:101]: plugin not found: C:\Home\Projects\Factorio Modding\Factorio-Zombie-Engineer [23:52:02.194][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/prototypes/entity/entities.lua] takes [0.118] sec, size [466.802] kb. [23:52:02.663][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/prototypes/entity/trees.lua] takes [0.108] sec, size [185.481] kb. [23:52:03.538][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/scenarios/team-production/map_sets.lua] takes [0.112] sec, size [221.774] kb. [23:52:04.319][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/core/lualib/collision-mask-util.lua] takes [0.109] sec, size [12.290] kb. [23:52:05.022][warn] [#0:script\files.lua:558]: Parse LuaDoc of [file:///c%3A/Users/mikeh/AppData/Roaming/Code/User/workspaceStorage/34445a4340c7b2315555c5d263edbf99/justarandomgeek.factoriomod-debug/sumneko-3rd/factorio/library/runtime-api-events.lua] takes [0.153] sec, size [203.992] kb. [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/didOpen] takes [9.109]sec. { jsonrpc = "2.0", method = "textDocument/didOpen", params = { textDocument = { languageId = "lua", text = '"***"', uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua", version = 1 } } } [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/codeAction] takes [9.108]sec. { id = 2, jsonrpc = "2.0", method = "textDocument/codeAction", params = { context = { diagnostics = {}, triggerKind = 2 }, range = { end = { character = 11, line = 15 }, start = { character = 11, line = 15 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentColor] takes [9.107]sec. { id = 3, jsonrpc = "2.0", method = "textDocument/documentColor", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/foldingRange] takes [8.893]sec. { id = 6, jsonrpc = "2.0", method = "textDocument/foldingRange", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentSymbol] takes [9.108]sec. { id = 1, jsonrpc = "2.0", method = "textDocument/documentSymbol", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:52:06.694][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [9.000]sec. { id = 5, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 0, line = 17 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:52:08.429][warn] [#0:script\core\diagnostics\init.lua:136]: Diagnostics [assign-type-mismatch] @ [file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/emmyLua/math-uint.lua] takes [1.697] sec! [23:53:31.413][warn] [#0:script\provider\provider.lua:625]: Completion takes 0.107 sec. [23:55:16.163][warn] [#0:script\core\diagnostics\init.lua:136]: Diagnostics [redundant-value] @ [file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua] takes [0.656] sec! [23:55:16.429][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/codeAction] takes [0.913]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 442, jsonrpc = "2.0", method = "textDocument/codeAction", params = { context = { diagnostics = {}, triggerKind = 2 }, range = { end = { character = 16, line = 38 }, start = { character = 16, line = 38 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:20.522][warn] [#0:script\plugin.lua:37]: Call plugin event [OnSetText] takes [0.113] sec [23:55:20.647][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/prototypes/entity/entities.lua] takes [0.123] sec, size [466.802] kb. [23:55:21.522][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/prototypes/entity/trees.lua] takes [0.123] sec, size [185.481] kb. [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/foldingRange] takes [5.995]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 443, jsonrpc = "2.0", method = "textDocument/foldingRange", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentHighlight] takes [6.292]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 439, jsonrpc = "2.0", method = "textDocument/documentHighlight", params = { position = { character = 16, line = 38 }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [6.142]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 441, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 35, line = 73 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [3.719]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 449, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 56, line = 67 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [3.373]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 452, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 66, line = 62 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [3.030]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 454, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 59, line = 57 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [2.792]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 456, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 69, line = 52 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [2.025]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 458, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 32, line = 63 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [1.433]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 461, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 35, line = 73 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentColor] takes [6.295]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 437, jsonrpc = "2.0", method = "textDocument/documentColor", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:21.554][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/codeAction] takes [4.869]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 446, jsonrpc = "2.0", method = "textDocument/codeAction", params = { context = { diagnostics = {}, triggerKind = 2 }, range = { end = { character = 16, line = 38 }, start = { character = 16, line = 38 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:22.007][warn] [#0:script\plugin.lua:37]: Call plugin event [OnSetText] takes [0.133] sec [23:55:22.522][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [0.931]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 465, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 4, line = 3 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:22.522][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/foldingRange] takes [0.760]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 466, jsonrpc = "2.0", method = "textDocument/foldingRange", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:22.694][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/prototypes/tile/tiles.lua] takes [0.109] sec, size [137.804] kb. [23:55:23.288][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/base/scenarios/team-production/map_sets.lua] takes [0.120] sec, size [221.774] kb. [23:55:23.991][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/FactorioModding/data/core/lualib/noise.lua] takes [0.143] sec, size [12.994] kb. [23:55:24.460][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [1.760]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 470, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 0, line = 0 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:24.460][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/foldingRange] takes [1.648]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 471, jsonrpc = "2.0", method = "textDocument/foldingRange", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:24.476][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentSymbol] takes [1.437]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 473, jsonrpc = "2.0", method = "textDocument/documentSymbol", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:25.163][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/Users/mikeh/AppData/Roaming/Code/User/workspaceStorage/34445a4340c7b2315555c5d263edbf99/justarandomgeek.factoriomod-debug/sumneko-3rd/factorio/library/runtime-api-LuaEntityPrototype.lua] takes [0.157] sec, size [67.400] kb. [23:55:25.788][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/codeAction] takes [1.025]sec. { _closeMessage = "Request cancelled.", _closeReason = -32800, id = 480, jsonrpc = "2.0", method = "textDocument/codeAction", params = { context = { diagnostics = {}, triggerKind = 2 }, range = { end = { character = 16, line = 38 }, start = { character = 16, line = 38 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:25.913][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentColor] takes [4.361]sec. { id = 462, jsonrpc = "2.0", method = "textDocument/documentColor", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/test.lua" } } } [23:55:25.913][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/documentColor] takes [1.293]sec. { id = 476, jsonrpc = "2.0", method = "textDocument/documentColor", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:26.038][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/semanticTokens/range] takes [1.274]sec. { id = 479, jsonrpc = "2.0", method = "textDocument/semanticTokens/range", params = { range = { end = { character = 35, line = 73 }, start = { character = 0, line = 0 } }, textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:55:26.679][warn] [#0:script\proto\proto.lua:187]: Method [textDocument/foldingRange] takes [1.868]sec. { id = 481, jsonrpc = "2.0", method = "textDocument/foldingRange", params = { textDocument = { uri = "file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua" } } } [23:57:25.413][warn] [#0:script\files.lua:695]: Compile [file:///c%3A/Home/Projects/Factorio%20Modding/Factorio-Zombie-Engineer/utility/functions/player-weapon.lua] takes [0.368] sec, size [19.117] kb. [00:04:16.304][warn] [#0:script\await.lua:191]: Await step takes [0.569] sec. [00:06:55.538][warn] [#0:script\await.lua:191]: Await step takes [0.501] sec. [00:10:43.444][warn] [#0:script\await.lua:191]: Await step takes [0.524] sec. [00:13:37.335][warn] [#0:script\await.lua:191]: Await step takes [0.504] sec. [00:16:23.804][warn] [#0:script\await.lua:191]: Await step takes [0.512] sec.

ZenkakuHiragana commented 8 months ago

I guess probably assigning upvalue inside for-loop causes this issue.
I got a similar problem with the following code (which seems simpler):

local upvalue = 0
for i = 1, 1 do
    upvalue = upvalue + i
    print(upvalue) -- Type of "upvalue" is lost here
end
print(upvalue) -- Type is lost here, too

Possible workaround for now is adding @type at the end of assigning:

local upvalue = 0
for i = 1, 1 do
    upvalue = upvalue + i ---@type integer
    print(upvalue) -- Type of "upvalue" is kept here
end
print(upvalue) -- Type is kept here, too
d-enk commented 3 months ago

another example with if

---@type integer
local c = 0
c = c + 1
if true then
    c = c + 1 -- local c: integer

    if c == 2 then -- local c: unknown
        _ = c -- local c: integer
    end

    _ = c -- local c: integer|unknown
end