lua-language-server
                                
                                 lua-language-server copied to clipboard
                                
                                    lua-language-server copied to clipboard
                            
                            
                            
                        Type checking does not work at all with `` (backtick) literals
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 = 1
B = 2
---@type `A`
local foo = A -- this should be fine
---@type `A`
local bar = B -- but this should give a type error
---@type `A`
local baz = 1 -- ideally, so should this (because you didn't use the literal name "A")
---@type `A`|string
local var = A -- this should be fine
Actual Behaviour
A = 1
B = 2
---@type `A`
local foo = -- A is correctly the only autocomplete suggestion
---@type `A`
local bar = 3 -- but this does not give any type error
---@param a `A`
function f(a) end
local baz = f("Hello") -- nor does this
---@type `A`|string
local var = A --[[Cannot assign `integer` to `string|`A``.
- `integer` cannot match `string|`A``
- Type `integer` cannot match `string`
- Type `number` cannot match `string`
Lua Diagnostics.(assign-type-mismatch)
]]
Reproduction steps
- Extension version v3.9.3
Additional Notes
This is important for things like
A = 1
B = 2
---@alias Enum `A`|`B`
("enums" without tables) to be type checked, like in the "Literal Custom Type" example of https://luals.github.io/wiki/annotations/#alias
I experimented for a bit trying to fix the problem, but I can't quite find where the problem lies. All I know is that the backtick literals aren't being interpreted as types for the purposes of type checking.
In any case, here are some tests for test/diagnostics/assign-type-mismatch.lua to make sure it's fixed:
TEST [[
local A = "Hello"
local B = 2
---@type `A`
local x = A
---@type `B`
local y = B
]]
TEST [[
local A = "Hello"
---@alias myLiteralAliases `A` | integer
---@type myLiteralAliases
local x = A
---@type myLiteralAliases
local y = 3
]]
TEST [[
local B = 2
---@alias myLiteralAliases `B` | string
---@type myLiteralAliases
local x = B
---@type myLiteralAliases
local y = "Hello"
]]
TEST [[
local A = "Hello"
local B = 2
---@alias myLiteralAliases `A`|`B`
---@type myLiteralAliases
--local x = A
---@type myLiteralAliases
--local y = B
]]
TEST [[
local A = "Hello"
local B = "World"
---@alias myLiteralAliases `A`|`B`
---@type myLiteralAliases
--local <!x!> = 1
---@type myLiteralAliases
--local <!y!> = "A"
]]
TEST [[
local A = 1
local B = 2
---@alias myLiteralAliases `A`|`B`
---@type myLiteralAliases
--local <!x!> = "A"
]]
and if we want to disallow the value (only allowing the actual symbol):
TEST [[
local A = "Hello"
---@type `A`
local <!x!> = "Hello"
]]
TEST [[
local A = "Hello"
---@alias myLiteralAliases `A` | integer
---@type myLiteralAliases
local <!x!> = "Hello"
]]
TEST [[
local A = "Hello"
local B = "World"
---@alias myLiteralAliases `A`|`B`
---@type myLiteralAliases
local <!x!> = "Hello"
]]