title: go/types finding if struct implements interface
body: <p>OK so looking at using go/types, go/parser... an so forth to generate some code; but need to identify all structs that implement a specific interface which I have figured out, however, if the struct definition on the struct function it does not match using types.Implements.</p>
  
  <p>OK the code examples:</p>
  
  <p><strong>Getting the interface</strong></p>
  
  <pre><code>package ifacepkg
  
  const interfacePkg = `package ifacepkg
  
  type MyInterface interface {
      MyFunction() error
  }
  `
  
  func getIface() *types.Interface {
  
  fset := token.NewFileSet()
  
  f, err := parser.ParseFile(fset, "iface.go", interfacePkg, 0)
  if err != nil {
      panic(err)
  }
  
  config := &amp;types.Config{
      Error: func(e error) {
          fmt.Println(e)
      },
      Importer: importer.Default(),
  }
  
  info := types.Info{
      Types: make(map[ast.Expr]types.TypeAndValue),
      Defs:  make(map[*ast.Ident]types.Object),
      Uses:  make(map[*ast.Ident]types.Object),
  }
  
  pkg, e := config.Check("genval", fset, []*ast.File{f}, &amp;info)
  if e != nil {
      fmt.Println(e)
  }
  
  return pkg.Scope().Lookup("MyInterface").Type().Underlying().(*types.Interface)
  }
  </code></pre>
  
  <p><strong>Test File</strong></p>
  
  <pre><code>package test
  
  import "ifacepkg"
  
  // User struct
  type User struct {
      FirstName string
      LastName  string
  }
  
  func (u User) MyFunction() error {
      return nil
  }
  
  var _ ifacepkg.MyInterface = &amp;User{}
  </code></pre>
  
  <p><strong>Loading Test File &amp; trying to see if User implements MyInterface</strong></p>
  
  <pre><code>fset := token.NewFileSet()
  
  pkgs, e := parser.ParseDir(fset, "./test", nil, 0)
  if e != nil {
      log.Fatal(e)
      // return
  }
  
  var astf []*ast.File
  
  for _, pkg := range pkgs {
      fmt.Printf("package %v\n", pkg.Name)
      for fn, f := range pkg.Files {
          fmt.Printf("file %v\n", fn)
          astf = append(astf, f)
      }
  }
  
  config := &amp;types.Config{
      Error: func(e error) {
          fmt.Println(e)
      },
      Importer: importer.Default(),
  }
  
  info := types.Info{
      Types: make(map[ast.Expr]types.TypeAndValue),
      Defs:  make(map[*ast.Ident]types.Object),
      Uses:  make(map[*ast.Ident]types.Object),
  }
  
  pkg, e := config.Check(path, fset, astf, &amp;info)
  if e != nil {
      fmt.Println(e)
  }
  
  vIface := getIface()
  fmt.Println(vIface)
  
  scope := pkg.Scope()
  
      for _, name := range scope.Names() {
  
          obj := scope.Lookup(name)
  
          _, ok := obj.Type().Underlying().(*types.Struct)
          imp := types.Implements(obj.Type(), vIface)
  
          fmt.Println(obj.Name(), ok, imp)
      }
  </code></pre>
  
  <p>OK so fmt.Println(obj.Name(), ok, imp) prints User true true all good! however if I change the source file function from</p>
  
  <pre><code>func (u User) MyFunction() error {
  </code></pre>
  
  <p>to</p>
  
  <pre><code>func (u *User) MyFunction() error {
  </code></pre>
  
  <p>it now prints User true false</p>
  
  <p>so the function types.Implements is reporting that User does not implement MyInterface, which is not true.</p>
  
  <p>So my question is: Is there an issue with the type.Implements method or is there something I have to do to my object prior to calling that function.</p>
  
  <p><strong>Answer</strong></p>
  
  <p>ok to solve my own issue changing final portion of code to</p>
  
  <pre><code>scope := pkg.Scope()
  
  for _, name := range scope.Names() {
  
      obj := scope.Lookup(name)
  
      _, ok := obj.Type().Underlying().(*types.Struct)
      ptr := types.NewPointer(obj.Type())
      imp := types.Implements(ptr.Underlying(), vIface)
  
      fmt.Println(obj.Name(), ok, imp)
  }
  </code></pre>
  
  <p>which works with both Pointer and non-pointer recievers</p>