I am trying to write a custom linter that operates on a specific type. But it seems I am misunderstanding something about Go types. In the example below, I am parsing this example code which declares a var Foo
of type time.Time
. However, when I compare Foo
's type to time.Time
using types.Identical()
, it returns false
. Why is this? If my goal is to find expressions which involve the type time.Time
, should I identify them using a different method than types.Identical()
?
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"golang.org/x/tools/go/packages"
)
const example = `package main
import "time"
var Foo time.Time
func main() {
}`
// Based on https://github.com/golang/example/tree/master/gotypes#an-example
func ParseExamplePackage() *types.Package {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "example.go", example, 0)
if err != nil {
panic(err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("example", fset, []*ast.File{f}, nil)
if err != nil {
panic(err)
}
return pkg
}
func ParseTimePackage() *packages.Package {
cfg := &packages.Config{
Mode: packages.LoadAllSyntax,
}
loadedPackages, err := packages.Load(cfg, "time")
if err != nil {
panic(err)
}
return loadedPackages[0]
}
func main() {
timePkg := ParseTimePackage()
timeObject := timePkg.Types.Scope().Lookup("Time")
examplePkg := ParseExamplePackage()
fooObject := examplePkg.Scope().Lookup("Foo")
fmt.Printf("time type: %s\n", timeObject.Type().String()) // time.Time
fmt.Printf("foo type: %s\n", fooObject.Type().String()) // time.Time
fmt.Printf("identical: %t\n", types.Identical(timeObject.Type(), fooObject.Type())) // false
}