golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.91k stars 17.65k forks source link

x/tools/gopls: inconsistent semantic token types for function #57469

Open rink-grey opened 1 year ago

rink-grey commented 1 year ago

As example, a function has 3 function type parameter: fn1, fn2, fns. fn1 is defined by normal function type. fn2 is defined by an alias type for function. fns is defined by variable number of arguments for an alias function type.

iShot_2022-12-27_10 34 49

it check "fn1" as function, that is correct.

iShot_2022-12-27_10 35 10

it check "fn2" as variable but not function.

iShot_2022-12-27_10 35 37

it check the element of "fns" as normal variable but not function.

iShot_2022-12-27_10 35 55

So there is inconsistent.

findleyr commented 1 year ago

CC @pjweinb

pjweinb commented 1 year ago

In package whatever type B func() type C = func() func Run(a func(), b B, c C, bb ...B) { a() // a is called a function b() // b is called a parameter, but it looks like a function c() // c is called a function for _, f := range bb { f() // f is called a variable, but it looks like a function } } bi is called a parameter, even though it is used like a function, because its type is B. It can be used as a function because its core type is func(), a function type. The Go type checker identifies a and c as functions, and b as an identifier.

So the question is what 'semantic' in 'semanticToken' means. Here it could mean 'used like a function so call it a function' or it could mean whatever the Go type checker thinks [which for b, is that it is an identifier that was a parameter, and for bb, that it is a variable]

I'm inclined to leave it the way it is. The user can see (even without semantic tokens) that these identifiers are all being used to call. The semantic tokens give some information about the types: b and c have different types, even though their underlying types are both func().

rink-grey commented 1 year ago

By @pjweinb talk, I think the main point is "a function type-alias is not identified as function by Go type checker". So it looks like the issue is not about semantic token.