Skip to content

Commit ef0f4a4

Browse files
committed
gopls/internal/analysis/unusedfunc: skip std
Too many false positives. Also, modify the test so that its package has a go.mod and does not appear to be part of std. Updates golang/go#71686 Updates golang/go#74130 Change-Id: I471a28d263769d85a46fb90483486845d96d0ea3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/691496 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent a985a6c commit ef0f4a4

File tree

7 files changed

+93
-71
lines changed

7 files changed

+93
-71
lines changed

gopls/doc/analyzers.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4434,7 +4434,7 @@ package.
44344434
The tool may report false positives in some situations, for
44354435
example:
44364436

4437-
- For a declaration of an unexported function that is referenced
4437+
- for a declaration of an unexported function that is referenced
44384438
from another package using the go:linkname mechanism, if the
44394439
declaration's doc comment does not also have a go:linkname
44404440
comment.
@@ -4443,17 +4443,19 @@ example:
44434443
annotations, if they must be used at all, should be used on both
44444444
the declaration and the alias.)
44454445

4446-
- For compiler intrinsics in the "runtime" package that, though
4446+
- for compiler intrinsics in the "runtime" package that, though
44474447
never referenced, are known to the compiler and are called
44484448
indirectly by compiled object code.
44494449

4450-
- For functions called only from assembly.
4450+
- for functions called only from assembly.
44514451

4452-
- For functions called only from files whose build tags are not
4452+
- for functions called only from files whose build tags are not
44534453
selected in the current build configuration.
44544454

4455-
See https://github.com/golang/go/issues/71686 for discussion of
4456-
these limitations.
4455+
Since these situations are relatively common in the low-level parts
4456+
of the runtime, this analyzer ignores the standard library.
4457+
See https://go.dev/issue/71686 and https://go.dev/issue/74130 for
4458+
further discussion of these limitations.
44574459

44584460
The unusedfunc algorithm is not as precise as the
44594461
golang.org/x/tools/cmd/deadcode tool, but it has the advantage that

gopls/internal/analysis/unusedfunc/doc.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
// The tool may report false positives in some situations, for
2424
// example:
2525
//
26-
// - For a declaration of an unexported function that is referenced
26+
// - for a declaration of an unexported function that is referenced
2727
// from another package using the go:linkname mechanism, if the
2828
// declaration's doc comment does not also have a go:linkname
2929
// comment.
@@ -32,17 +32,19 @@
3232
// annotations, if they must be used at all, should be used on both
3333
// the declaration and the alias.)
3434
//
35-
// - For compiler intrinsics in the "runtime" package that, though
35+
// - for compiler intrinsics in the "runtime" package that, though
3636
// never referenced, are known to the compiler and are called
3737
// indirectly by compiled object code.
3838
//
39-
// - For functions called only from assembly.
39+
// - for functions called only from assembly.
4040
//
41-
// - For functions called only from files whose build tags are not
41+
// - for functions called only from files whose build tags are not
4242
// selected in the current build configuration.
4343
//
44-
// See https://github.com/golang/go/issues/71686 for discussion of
45-
// these limitations.
44+
// Since these situations are relatively common in the low-level parts
45+
// of the runtime, this analyzer ignores the standard library.
46+
// See https://go.dev/issue/71686 and https://go.dev/issue/74130 for
47+
// further discussion of these limitations.
4648
//
4749
// The unusedfunc algorithm is not as precise as the
4850
// golang.org/x/tools/cmd/deadcode tool, but it has the advantage that

gopls/internal/analysis/unusedfunc/testdata/src/a/a.go renamed to gopls/internal/analysis/unusedfunc/testdata/basic.txtar

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
Basic test of unusedfunc.
2+
3+
-- go.mod --
4+
module example.com
5+
6+
go 1.21
7+
8+
-- a/a.go --
19
package a
210

311
func main() {
@@ -70,3 +78,60 @@ const (
7078
constOne = 1
7179
unusedConstTwo = constOne // want `const "unusedConstTwo" is unused`
7280
)
81+
82+
-- a/a.go.golden --
83+
package a
84+
85+
func main() {
86+
_ = live
87+
}
88+
89+
// -- functions --
90+
91+
func Exported() {}
92+
93+
func live() {}
94+
95+
//go:linkname foo
96+
func apparentlyDeadButHasPrecedingLinknameComment() {}
97+
98+
// -- methods --
99+
100+
type ExportedType int
101+
type unexportedType int
102+
103+
func (ExportedType) Exported() {}
104+
func (unexportedType) Exported() {}
105+
106+
func (x ExportedType) dynamic() {} // matches name of interface method => live
107+
108+
type _ interface{ dynamic() }
109+
110+
111+
// -- types without methods --
112+
113+
type ExportedType2 int
114+
115+
// want `type "unusedUnexportedType2" is unused`
116+
117+
type (
118+
one int
119+
)
120+
121+
// -- generic methods --
122+
123+
type g[T any] int
124+
125+
// want `method "method" is unused`
126+
127+
// -- constants --
128+
129+
// want `const "unusedConst" is unused`
130+
131+
const (
132+
unusedEnum = iota
133+
)
134+
135+
const (
136+
constOne = 1
137+
)

gopls/internal/analysis/unusedfunc/testdata/src/a/a.go.golden

Lines changed: 0 additions & 55 deletions
This file was deleted.

gopls/internal/analysis/unusedfunc/unusedfunc.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ var Analyzer = &analysis.Analyzer{
6767
}
6868

6969
func run(pass *analysis.Pass) (any, error) {
70+
// The standard library makes heavy use of intrinsics, linknames, etc,
71+
// that confuse this algorithm; so skip it (#74130).
72+
if analysisinternal.IsStdPackage(pass.Pkg.Path()) {
73+
return nil, nil
74+
}
75+
7076
var (
7177
inspect = pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
7278
index = pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)

gopls/internal/analysis/unusedfunc/unusedfunc_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
package unusedfunc_test
66

77
import (
8+
"path/filepath"
89
"testing"
910

1011
"golang.org/x/tools/go/analysis/analysistest"
1112
"golang.org/x/tools/gopls/internal/analysis/unusedfunc"
13+
"golang.org/x/tools/internal/testfiles"
1214
)
1315

1416
func Test(t *testing.T) {
15-
testdata := analysistest.TestData()
16-
analysistest.RunWithSuggestedFixes(t, testdata, unusedfunc.Analyzer, "a")
17+
dir := testfiles.ExtractTxtarFileToTmp(t, filepath.Join(analysistest.TestData(), "basic.txtar"))
18+
analysistest.RunWithSuggestedFixes(t, dir, unusedfunc.Analyzer, "example.com/a")
1719
}

gopls/internal/doc/api.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@
16481648
},
16491649
{
16501650
"Name": "\"unusedfunc\"",
1651-
"Doc": "check for unused functions, methods, etc\n\nThe unusedfunc analyzer reports functions and methods that are\nnever referenced outside of their own declaration.\n\nA function is considered unused if it is unexported and not\nreferenced (except within its own declaration).\n\nA method is considered unused if it is unexported, not referenced\n(except within its own declaration), and its name does not match\nthat of any method of an interface type declared within the same\npackage.\n\nThe tool may report false positives in some situations, for\nexample:\n\n - For a declaration of an unexported function that is referenced\n from another package using the go:linkname mechanism, if the\n declaration's doc comment does not also have a go:linkname\n comment.\n\n (Such code is in any case strongly discouraged: linkname\n annotations, if they must be used at all, should be used on both\n the declaration and the alias.)\n\n - For compiler intrinsics in the \"runtime\" package that, though\n never referenced, are known to the compiler and are called\n indirectly by compiled object code.\n\n - For functions called only from assembly.\n\n - For functions called only from files whose build tags are not\n selected in the current build configuration.\n\nSee https://github.com/golang/go/issues/71686 for discussion of\nthese limitations.\n\nThe unusedfunc algorithm is not as precise as the\ngolang.org/x/tools/cmd/deadcode tool, but it has the advantage that\nit runs within the modular analysis framework, enabling near\nreal-time feedback within gopls.\n\nThe unusedfunc analyzer also reports unused types, vars, and\nconstants. Enums--constants defined with iota--are ignored since\neven the unused values must remain present to preserve the logical\nordering.",
1651+
"Doc": "check for unused functions, methods, etc\n\nThe unusedfunc analyzer reports functions and methods that are\nnever referenced outside of their own declaration.\n\nA function is considered unused if it is unexported and not\nreferenced (except within its own declaration).\n\nA method is considered unused if it is unexported, not referenced\n(except within its own declaration), and its name does not match\nthat of any method of an interface type declared within the same\npackage.\n\nThe tool may report false positives in some situations, for\nexample:\n\n - for a declaration of an unexported function that is referenced\n from another package using the go:linkname mechanism, if the\n declaration's doc comment does not also have a go:linkname\n comment.\n\n (Such code is in any case strongly discouraged: linkname\n annotations, if they must be used at all, should be used on both\n the declaration and the alias.)\n\n - for compiler intrinsics in the \"runtime\" package that, though\n never referenced, are known to the compiler and are called\n indirectly by compiled object code.\n\n - for functions called only from assembly.\n\n - for functions called only from files whose build tags are not\n selected in the current build configuration.\n\nSince these situations are relatively common in the low-level parts\nof the runtime, this analyzer ignores the standard library.\nSee https://go.dev/issue/71686 and https://go.dev/issue/74130 for\nfurther discussion of these limitations.\n\nThe unusedfunc algorithm is not as precise as the\ngolang.org/x/tools/cmd/deadcode tool, but it has the advantage that\nit runs within the modular analysis framework, enabling near\nreal-time feedback within gopls.\n\nThe unusedfunc analyzer also reports unused types, vars, and\nconstants. Enums--constants defined with iota--are ignored since\neven the unused values must remain present to preserve the logical\nordering.",
16521652
"Default": "true",
16531653
"Status": ""
16541654
},
@@ -3386,7 +3386,7 @@
33863386
},
33873387
{
33883388
"Name": "unusedfunc",
3389-
"Doc": "check for unused functions, methods, etc\n\nThe unusedfunc analyzer reports functions and methods that are\nnever referenced outside of their own declaration.\n\nA function is considered unused if it is unexported and not\nreferenced (except within its own declaration).\n\nA method is considered unused if it is unexported, not referenced\n(except within its own declaration), and its name does not match\nthat of any method of an interface type declared within the same\npackage.\n\nThe tool may report false positives in some situations, for\nexample:\n\n - For a declaration of an unexported function that is referenced\n from another package using the go:linkname mechanism, if the\n declaration's doc comment does not also have a go:linkname\n comment.\n\n (Such code is in any case strongly discouraged: linkname\n annotations, if they must be used at all, should be used on both\n the declaration and the alias.)\n\n - For compiler intrinsics in the \"runtime\" package that, though\n never referenced, are known to the compiler and are called\n indirectly by compiled object code.\n\n - For functions called only from assembly.\n\n - For functions called only from files whose build tags are not\n selected in the current build configuration.\n\nSee https://github.com/golang/go/issues/71686 for discussion of\nthese limitations.\n\nThe unusedfunc algorithm is not as precise as the\ngolang.org/x/tools/cmd/deadcode tool, but it has the advantage that\nit runs within the modular analysis framework, enabling near\nreal-time feedback within gopls.\n\nThe unusedfunc analyzer also reports unused types, vars, and\nconstants. Enums--constants defined with iota--are ignored since\neven the unused values must remain present to preserve the logical\nordering.",
3389+
"Doc": "check for unused functions, methods, etc\n\nThe unusedfunc analyzer reports functions and methods that are\nnever referenced outside of their own declaration.\n\nA function is considered unused if it is unexported and not\nreferenced (except within its own declaration).\n\nA method is considered unused if it is unexported, not referenced\n(except within its own declaration), and its name does not match\nthat of any method of an interface type declared within the same\npackage.\n\nThe tool may report false positives in some situations, for\nexample:\n\n - for a declaration of an unexported function that is referenced\n from another package using the go:linkname mechanism, if the\n declaration's doc comment does not also have a go:linkname\n comment.\n\n (Such code is in any case strongly discouraged: linkname\n annotations, if they must be used at all, should be used on both\n the declaration and the alias.)\n\n - for compiler intrinsics in the \"runtime\" package that, though\n never referenced, are known to the compiler and are called\n indirectly by compiled object code.\n\n - for functions called only from assembly.\n\n - for functions called only from files whose build tags are not\n selected in the current build configuration.\n\nSince these situations are relatively common in the low-level parts\nof the runtime, this analyzer ignores the standard library.\nSee https://go.dev/issue/71686 and https://go.dev/issue/74130 for\nfurther discussion of these limitations.\n\nThe unusedfunc algorithm is not as precise as the\ngolang.org/x/tools/cmd/deadcode tool, but it has the advantage that\nit runs within the modular analysis framework, enabling near\nreal-time feedback within gopls.\n\nThe unusedfunc analyzer also reports unused types, vars, and\nconstants. Enums--constants defined with iota--are ignored since\neven the unused values must remain present to preserve the logical\nordering.",
33903390
"URL": "https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/unusedfunc",
33913391
"Default": true
33923392
},

0 commit comments

Comments
 (0)