Original post

I am trying to write a custom linter that operates on a specific type. But it seems I am misunderstanding something about 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"

    ".org/x/tools/go/packages"
)

const example = `package main

import "time"

var Foo time.Time

func main() {
}`

// Based on https://github.com//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: %sn", timeObject.Type().String()) // time.Time
    fmt.Printf("foo type: %sn", fooObject.Type().String()) // time.Time
    fmt.Printf("identical: %tn", types.Identical(timeObject.Type(), fooObject.Type())) // false
}