Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect function params' type infer when there is only @overload #2838

Merged
merged 4 commits into from
Sep 9, 2024

Conversation

tomlau10
Copy link
Contributor

@tomlau10 tomlau10 commented Sep 6, 2024

fix #2509, fix #2708, fix #2709
(this logic has to be based on #2822, otherwise might cause other issues in type narrow behavior)

Promblem

When a function only has @overload annotation, the function itself will auto infer its params' type by using only the 1st overload type, combined with the return type of the function body logic, thus create an incorrect base function when doing function match.

Minimal Example

---@overload fun(a: 1): string
---@overload fun(a: 2): number
local function f(a) end --> fun(a: 1): nil

-- here the `a` in `f()` are inferred by the 1st `@overload` -> `a: 1`
-- and then it combines the return type `nil` due to the empty function body
-- => overall gives an incorrect `fun(a: 1): nil` as the base function signature

local r = f(1)  --> string|nil, bad
-- because it matches both the overload and the "baseline" function

Proposed Solution

Just ignore the baseline function type when it is annotated with only @overload.
In case the function has at least one @param or @return, then keep the existing behavior.

Expected Result

---@overload fun(a: 1): string
---@overload fun(a: 2): number
local function f(a) end --> fun(a: 1|2): nil, but we don't care about this anymore

local r = f(1)  --> string, good
-- now the "baseline" function type is ignored, will only found the overload one

中文版

這個其實是 #2822 的延續,上次說怕一次改太多會出 bug,所以拆分 PR

當前在一個 function 只有 @overload 的情況下,這 function 的 type 會直接從 第一個 overload 獲取
更甚者是還會結合 function body logic 自身的 return type (在寫 @meta 時很大可能是 nil,因為是 empty function body)

  • 結果就會得出一個錯誤的 baseline function type
  • 在後續做 matching 時就會出問題,比如說把這個 baseline function type 的 return nil 也當成一種 union return type
  • 具體例子見上邊

這裡解決方式是當 function 只有 @overload 時,就忽略這個 baseline function type,只從 overload 中做 match
有如當 function 是單純 local f(...) 全 vararg 時就直接忽略
反過來說如果 function 有至少1個 @param@return => 維持現有 behavior

應該也是需要 @sumneko 來 review

@sumneko sumneko merged commit d1320ae into LuaLS:master Sep 9, 2024
11 checks passed
@tomlau10 tomlau10 deleted the fix/func_type_union_overload branch September 11, 2024 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants