From 663bb6d3533dc62cc0b49176a889fe4efddae191 Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Sun, 30 Jun 2024 04:11:05 +0200 Subject: [PATCH] unused: implement all known instances of generic interface types --- .../generic-interfaces/generic-interfaces.go | 15 +++++++++++++++ unused/unused.go | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/unused/testdata/src/example.com/generic-interfaces/generic-interfaces.go b/unused/testdata/src/example.com/generic-interfaces/generic-interfaces.go index 0b2c46b7c..d6ccfab1c 100644 --- a/unused/testdata/src/example.com/generic-interfaces/generic-interfaces.go +++ b/unused/testdata/src/example.com/generic-interfaces/generic-interfaces.go @@ -176,3 +176,18 @@ type S8_1 struct{} //@ used("S8_1", true) func (s *S8_1) m8() []io.Reader { //@ quiet("s"), used("m8", false) return nil } + +type S8 struct{} //@ used("S8", true) +type I9[T any] interface { //@ used("I9", true), used("T", true) + make() *T //@ used("make", true) +} + +type S9 struct{} //@ used("S9", true) + +func (S9) make() *S8 { return nil } //@ used("make", true) + +func i9use(i I9[S8]) { i.make() } //@ used("i9use", true), used("i", true) + +func init() { //@ used("init", true) + i9use(S9{}) +} diff --git a/unused/unused.go b/unused/unused.go index 602670485..46c147e1a 100644 --- a/unused/unused.go +++ b/unused/unused.go @@ -534,6 +534,19 @@ func (g *graph) entry() { } } + // We use a normal map instead of a typeutil.Map because we deduplicate + // these on a best effort basis, as an optimization. + allInterfaces := make(map[*types.Interface]struct{}) + for _, typ := range g.interfaceTypes { + allInterfaces[typ] = struct{}{} + } + for _, ins := range g.info.Instances { + if typ, ok := ins.Type.(*types.Named); ok && typ.Obj().Pkg() == g.pkg { + if iface, ok := typ.Underlying().(*types.Interface); ok { + allInterfaces[iface] = struct{}{} + } + } + } processMethodSet := func(named *types.TypeName, ms *types.MethodSet) { if g.opts.ExportedIsUsed { for i := 0; i < ms.Len(); i++ { @@ -552,7 +565,7 @@ func (g *graph) entry() { // (8.0) handle interfaces // // We don't care about interfaces implementing interfaces; all their methods are already used, anyway - for _, iface := range g.interfaceTypes { + for iface := range allInterfaces { if sels, ok := implements(named.Type(), iface, ms); ok { for _, sel := range sels { // (8.2) any concrete type implements all known interfaces