Skip to content

Commit

Permalink
unused: don't ignore fields and methods of aliased type in imported p…
Browse files Browse the repository at this point in the history
…ackage

When ignoring an alias, we don't want to ignore the fields and methods
of the aliased type if that type is in a different package. Not only
is it unnecessary, it also breaks the invariant that we only use
objects we've already seen.

Closes gh-1073

(cherry picked from commit 6c9d8ed)
  • Loading branch information
dominikh committed Nov 11, 2021
1 parent df71e5d commit 40877a4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
19 changes: 19 additions & 0 deletions unused/testdata/src/alias/alias.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package main

import "net/http"

type t1 struct{} // used
type t2 struct{} // unused
type t3 struct{} // used
Expand All @@ -13,3 +15,20 @@ func main() { // used
var _ alias1
var _ t3
}

type t4 struct { // used
x int // used
}

func (t4) foo() {} // used

//lint:ignore U1000 alias5 is ignored, which also ignores t4
type alias5 = t4 // used

//lint:ignore U1000 alias6 is ignored, and we don't incorrectly try to include http.Server's fields and methods in the graph
type alias6 = http.Server // used

//lint:ignore U1000 aliases don't have to be to named types
type alias7 = struct { // used
x int // used
}
11 changes: 11 additions & 0 deletions unused/unused.go
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,17 @@ func (g *graph) entry(pkg *pkg) {

// use methods and fields of ignored types
if obj, ok := obj.(*types.TypeName); ok {
if obj.IsAlias() {
if typ, ok := obj.Type().(*types.Named); ok && typ.Obj().Pkg() != obj.Pkg() {
// This is an alias of a named type in another package.
// Don't walk its fields or methods; we don't have to,
// and it breaks an assertion in graph.use because we're using an object that we haven't seen before.
//
// For aliases to types in the same package, we do want to ignore the fields and methods,
// because ignoring the alias should ignore the aliased type.
continue
}
}
if typ, ok := obj.Type().(*types.Named); ok {
for i := 0; i < typ.NumMethods(); i++ {
g.use(typ.Method(i), nil, edgeIgnored)
Expand Down

0 comments on commit 40877a4

Please sign in to comment.