Skip to content

Commit d8f7154

Browse files
committed
never warn on funcs used as interfaces
These often lead to false positives, as the interface value is often called via type switches, reflection, or other methods. As before, don't rely on callgraph for this. It doesn't deal well with that kind of runtime type conversion. We had a few test cases which were "correct positives", but looking at them again, they don't seem particularly useful or stable. Better to be on the safe side and not warn on those. Fixes #23.
1 parent 0f1251b commit d8f7154

File tree

2 files changed

+21
-27
lines changed

2 files changed

+21
-27
lines changed

check/check.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,6 @@ func (c *Checker) Check() ([]Issue, error) {
246246
}
247247
}
248248
case *ssa.FieldAddr:
249-
ftype := instr.Type().(*types.Pointer).Elem()
250-
if _, ok := ftype.(*types.Signature); !ok {
251-
continue
252-
}
253249
for _, ref := range *instr.Referrers() {
254250
store, ok := ref.(*ssa.Store)
255251
if !ok || store.Addr != instr {
@@ -309,7 +305,11 @@ func findFunction(value ssa.Value) *ssa.Function {
309305
case *ssa.Function:
310306
return value
311307
case *ssa.MakeClosure:
308+
// closure of a func
312309
return value.Fn.(*ssa.Function)
310+
case *ssa.MakeInterface:
311+
// wrapping a func as an interface
312+
return findFunction(value.X)
313313
}
314314
return nil
315315
}

testdata/scripts/usedas.txt

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ cmp stdout stdout.golden
66
-- go.mod --
77
module testdata.tld/foo
88
-- stdout.golden --
9-
foo.go:55:22: UsedAsArg$4 - u is unused
10-
foo.go:73:36: usedAsIfaceNothing - i is unused
9+
foo.go:9:19: oneUnused - b is unused
1110
-- foo.go --
1211
package foo
1312

@@ -17,6 +16,10 @@ type FooType int
1716

1817
var DoWork func()
1918

19+
func oneUnused(a, b int) int {
20+
return a + 123
21+
}
22+
2023
func funcAsParam(fn func(FooType) string) { fn(0) }
2124

2225
func passedAsParam(f FooType) string {
@@ -77,29 +80,8 @@ func usedAsGlobalArg(f FooType, i int8) {
7780
println(f)
7881
}
7982

80-
func paramIfaceNothing(f interface{}) {
81-
println(f)
82-
}
83-
84-
func usedAsIfaceNothing(f FooType, i int16) {
85-
DoWork()
86-
println(f)
87-
}
88-
89-
func paramIfaceAssert(f interface{}) {
90-
fn := f.(func(FooType, *rune))
91-
fn(2, nil)
92-
}
93-
94-
func usedAsIfaceAssert(f FooType, i *rune) {
95-
DoWork()
96-
println(f)
97-
}
98-
9983
func GlobArgUse() {
10084
globalParam(usedAsGlobalArg)
101-
paramIfaceNothing(usedAsIfaceNothing)
102-
paramIfaceAssert(usedAsIfaceAssert)
10385
}
10486

10587
type barIface interface {
@@ -169,3 +151,15 @@ func UsedAsGlobalParam(someBool bool) {
169151
}
170152
mux.HandleFunc("/closureVar", closure)
171153
}
154+
155+
type FuncInterfaceField struct {
156+
Func interface{}
157+
}
158+
159+
var usedAsGlobalInterfaceField = FuncInterfaceField {
160+
Func: func(i int, bs []byte) {
161+
if i == 0 {
162+
DoWork()
163+
}
164+
},
165+
}

0 commit comments

Comments
 (0)