Skip to content

x/tools/gopls: add analyzer for finding unnecessary any type constraints #51792

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

Closed
arkuchy opened this issue Mar 18, 2022 · 4 comments
Closed
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@arkuchy
Copy link

arkuchy commented Mar 18, 2022

Go1.18 is released and we can now use generics.
We need to have an analyzer to find unnecessary any, because I think there are many people that use any for type constraints without thinking.
I developed an analyzer called gencon for finding the any and give some hints of type constraints here.

gencon reports as follows:

func e[T any](t T) {} // want "should not use 'any'. hint: string|~int"

func f[T, U any, V int](t T, u U, v V) {} // want "should not use 'any'. hint: bool|int" "should not use 'any'. hint: string|~int"

func g(s string) {} // OK

func h[T any](t T) {} // want "should not use 'any'"

func invoke() { // OK
	e("gopher")
	e(1)
	type MyInt int
	e(MyInt(18))

	f(3, "gopher", 100)
	f(true, MyInt(3), 100)

	g("gopher")
}

Would you consider introducing the analyzer to gopls?

@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Mar 18, 2022
@gopherbot gopherbot added this to the Unreleased milestone Mar 18, 2022
@findleyr
Copy link
Member

Hi, I'm not sure I understand this analyzer. In your documentation, you have the following example:

func f[T any](t T) {} // want "should not use 'any'. hint: string|~int"

func invoke() { // OK
	f("gopher")
	f(1)
	type MyInt int
	f(MyInt(18))
}

Why would the user want to restrict this function to to string|~int when it's not necessary? If any is sufficient for the algorithms implemented by a generic type/function, then the user should use any to make their code as "generic" as possible.

@arkuchy
Copy link
Author

arkuchy commented Mar 18, 2022

Hi, it is true that there is no way to determine whether the any is intentional or not now.

How about adding the following option to determine if the any is necessary?

  • not exported
  • not comment like // no gencon lint

If this option is added, users can choose any intentionally.

My idea:

func e[T any](t T) {} // want "should not use 'any'. hint: string|~int"

// no gencon lint
func f[T, U any, V int](t T, u U, v V) {} // OK(because there is the comment)

func g(s string) {} // OK

func H[T any](t T) {} // OK(because this is exported)

func invoke() { // OK
	e("gopher")
	e(1)
	type MyInt int
	e(MyInt(18))

	f(3, "gopher", 100)
	f(true, MyInt(3), 100)

	g("gopher")
}

@findleyr
Copy link
Member

Typically, constraints should specify the minimum number of restrictions required for the function body.

Consider the equivalent logic for interfaces

func f(x interface{m()}) {
  m()
}

func _(x interface{ a(); m() ) {
  f(x)
} 

Just because f is only called with values that have a() doesn't mean we should add a() to the type of x. Doing so does not add value: it only restricts the places in which f could be called.

In your example, what advantage does changing the constraint to string|~int add? As far as I can tell this only restricts the function so that in the future if one wanted to call it with, say []byte, one would have to modify the definition of f.

@arkuchy
Copy link
Author

arkuchy commented Mar 19, 2022

So if we can choose any for type constraints, we should use any to make the function most generic , right?
I somehow thought we should avoid using any.
Thanks for your explanation!!

@arkuchy arkuchy closed this as completed Mar 21, 2022
@golang golang locked and limited conversation to collaborators Mar 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants