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

unused: warning about unexported struct that is used only as explicit generic parameter to function in another package #1282

Closed
GottfriedHerold opened this issue May 30, 2022 · 4 comments
Labels
false-positive started Issues we've started working on

Comments

@GottfriedHerold
Copy link

GottfriedHerold commented May 30, 2022

Hi the following code snippet gives a warning (type EmptyStruct is unused (U1000)go-staticcheck
View Problem), when it should not (probably related to #1250 ):

I have an internal(i.e. under /internal/utils.go) package utils with a function TypeOfType taking a generic parameter

package utils

import "reflect"

// TypeOfType[T]() returns the reflect.Type of T.
// As opposed to reflect.TypeOf, this works with a type parameter rather than
// a value and also works for interface types T
func TypeOfType[T any]() reflect.Type {
	var t *T
	return reflect.TypeOf(t).Elem()
}

Then in some other package I do:

package foo

import (
    "testing"
   "some/path/to/internal/utils"
)

func TestFoo(t *testing.T){
    type EmptyStruct struct{} // local definition
    _ = utils.TypeOfType[EmptyStruct]()
}

Staticcheck complains about EmptyStruct being unused, when it is clearly not. This persists even if the returned value of utils.TypeOfType is actually used (The example above is just simplified) or being defined at global scope, but unexported.
Note that the issue only happens if TypeOfType is defined in another package.

I use MS Code, version is

go: /snap/go/current/bin/go: go version go1.18.2 linux/amd64

gotests:	/home/gottfried/go/bin/gotests	(version: v1.6.0 built with go: go1.18)
gomodifytags:	/home/gottfried/go/bin/gomodifytags	(version: v1.16.0 built with go: go1.18)
impl:	/home/gottfried/go/bin/impl	(version: v1.1.0 built with go: go1.18)
goplay:	/home/gottfried/go/bin/goplay	(version: v1.0.0 built with go: go1.18)
dlv:	/home/gottfried/go/bin/dlv	(version: v1.8.2 built with go: go1.18)
staticcheck:	/home/gottfried/go/bin/staticcheck	(version: v0.3.0 built with go: go1.18)
gopls:	/home/gottfried/go/bin/gopls	(version: v0.8.4 built with go: go1.18.2)

Best,
Gottfried

@GottfriedHerold GottfriedHerold added false-positive needs-triage Newly filed issue that needs triage labels May 30, 2022
@dominikh dominikh removed the needs-triage Newly filed issue that needs triage label May 30, 2022
@dominikh
Copy link
Owner

I can reproduce the issue. Interestingly, the bug only occurs if TypeOfType is defined in an imported package. If it's in the same package, it works fine.

Will investigate.

@dominikh
Copy link
Owner

This is one in a series of bugs caused by the unfortunate implementation of unused. I'll address this in the upcoming (and in-progress) rewrite of unused.

@dominikh dominikh changed the title warning about unexported struct that is used only as explicit generic parameter to function in another package unused: warning about unexported struct that is used only as explicit generic parameter to function in another package Jun 4, 2022
@dominikh dominikh added the started Issues we've started working on label Jun 4, 2022
@MichaelUrman
Copy link

This also seems to be a problem with a local type alias. In the original example if we add type S struct{} to utils, the following has a similar false positive:

package bar

import "utils"

func Use() {         //@ used(true)
    type s = utils.S //@ used(true)
    println(utils.TypeOfType[s]().String())
}

That is, type s = utils.S is reported as unused. I originally encountered a slight variant of this where the called function's use of s was inferred by being an explicit type parameter on a parameter to the called function. (Loosely speaking pkg2.Foo(..., pkg3.Bar[s]). In my case func Foo[T any](...) took a callback and func Bar[T any](...) was that callback.)

I'm assuming these all share the root cause, but I can make a full report if it would help.

@dominikh
Copy link
Owner

but I can make a full report if it would help.

No need. It's probably a different root cause, but also addressed by the (still in progress…) rewrite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive started Issues we've started working on
Projects
None yet
Development

No branches or pull requests

3 participants