Repository: go
Issue: cmd/go, x/tools/go/packages: confusing go list repeated package with different values error
Labels: NeedsInvestigation

On go 1.12

Reproducible repo at https://github.com/nhooyr/gomod

I'm importing a main package as a side effect import which is an error. I'm aware this is wrong, but the error message should be clearer. If you try and load the mod with `x/tools/go/packages`, it will fail with

`go list repeated package golang.org/x/tools/cmd/goimports with different values`

Which is a very confusing error.

I debugged this a bit and it looks like `go list` is returning two different entries for `goimports` 

If you run

```
$ go list -deps=true all | grep goimports
```

You'll see

```
$ go list -deps=true all | grep goimports
golang.org/x/tools/cmd/goimports
golang.org/x/tools/cmd/goimports
```

Thing is, these two listing are actually different. If you run with the `json` option.

```
{
	"Dir": "/Users/nhooyr/Programming/gopath/pkg/mod/golang.org/x/tools@v0.0.0-20190228203856-589c23e65e65/cmd/goimports",
	"ImportPath": "golang.org/x/tools/cmd/goimports",
	"Name": "main",
	"Doc": "Command goimports updates your Go import lines, adding missing ones and removing unreferenced ones.",
	"Target": "/Users/nhooyr/Programming/gopath/bin/goimports",
	"Module": {
		"Path": "golang.org/x/tools",
		"Version": "v0.0.0-20190228203856-589c23e65e65",
		"Time": "2019-02-28T20:38:56Z",
		"Dir": "/Users/nhooyr/Programming/gopath/pkg/mod/golang.org/x/tools@v0.0.0-20190228203856-589c23e65e65",
		"GoMod": "/Users/nhooyr/Programming/gopath/pkg/mod/cache/download/golang.org/x/tools/@v/v0.0.0-20190228203856-589c23e65e65.mod"
	},
	"DepOnly": true,
	"Stale": true,
	"StaleReason": "stale dependency: golang.org/x/tools/internal/semver",
	"GoFiles": [
		"doc.go",
		"goimports.go",
		"goimports_gc.go"
	],
	"IgnoredGoFiles": [
		"goimports_not_gc.go"
	],
	"Imports": [
		"bufio",
		"bytes",
		"errors",
		"flag",
		"fmt",
		"go/scanner",
		"golang.org/x/tools/imports",
		"io",
		"io/ioutil",
		"log",
		"os",
		"os/exec",
		"path/filepath",
		"runtime",
		"runtime/pprof",
		"runtime/trace",
		"strings"
	],
	"Deps": [
		"bufio",
		"bytes",
		"compress/flate",
		"compress/gzip",
		"container/heap",
		"context",
		"encoding",
		"encoding/base64",
		"encoding/binary",
		"encoding/json",
		"errors",
		"flag",
		"fmt",
		"go/ast",
		"go/build",
		"go/constant",
		"go/doc",
		"go/format",
		"go/parser",
		"go/printer",
		"go/scanner",
		"go/token",
		"go/types",
		"golang.org/x/tools/go/ast/astutil",
		"golang.org/x/tools/go/gcexportdata",
		"golang.org/x/tools/go/internal/cgo",
		"golang.org/x/tools/go/internal/gcimporter",
		"golang.org/x/tools/go/internal/packagesdriver",
		"golang.org/x/tools/go/packages",
		"golang.org/x/tools/imports",
		"golang.org/x/tools/internal/fastwalk",
		"golang.org/x/tools/internal/gopathwalk",
		"golang.org/x/tools/internal/module",
		"golang.org/x/tools/internal/semver",
		"hash",
		"hash/crc32",
		"internal/bytealg",
		"internal/cpu",
		"internal/fmtsort",
		"internal/goroot",
		"internal/poll",
		"internal/race",
		"internal/syscall/unix",
		"internal/testlog",
		"io",
		"io/ioutil",
		"log",
		"math",
		"math/big",
		"math/bits",
		"math/rand",
		"net/url",
		"os",
		"os/exec",
		"path",
		"path/filepath",
		"reflect",
		"regexp",
		"regexp/syntax",
		"runtime",
		"runtime/internal/atomic",
		"runtime/internal/math",
		"runtime/internal/sys",
		"runtime/pprof",
		"runtime/trace",
		"sort",
		"strconv",
		"strings",
		"sync",
		"sync/atomic",
		"syscall",
		"text/scanner",
		"text/tabwriter",
		"text/template",
		"text/template/parse",
		"time",
		"unicode",
		"unicode/utf16",
		"unicode/utf8",
		"unsafe"
	],
	"Error": {
		"ImportStack": [
			"example.com/mymod",
			"golang.org/x/tools/cmd/goimports"
		],
		"Pos": "doc.go:4:5",
		"Err": "import \"golang.org/x/tools/cmd/goimports\" is a program, not an importable package"
	}
}
```

```
{
	"Dir": "/Users/nhooyr/Programming/gopath/pkg/mod/golang.org/x/tools@v0.0.0-20190228203856-589c23e65e65/cmd/goimports",
	"ImportPath": "golang.org/x/tools/cmd/goimports",
	"Name": "main",
	"Doc": "Command goimports updates your Go import lines, adding missing ones and removing unreferenced ones.",
	"Target": "/Users/nhooyr/Programming/gopath/bin/goimports",
	"Module": {
		"Path": "golang.org/x/tools",
		"Version": "v0.0.0-20190228203856-589c23e65e65",
		"Time": "2019-02-28T20:38:56Z",
		"Dir": "/Users/nhooyr/Programming/gopath/pkg/mod/golang.org/x/tools@v0.0.0-20190228203856-589c23e65e65",
		"GoMod": "/Users/nhooyr/Programming/gopath/pkg/mod/cache/download/golang.org/x/tools/@v/v0.0.0-20190228203856-589c23e65e65.mod"
	},
	"Match": [
		"all"
	],
	"Stale": true,
	"StaleReason": "stale dependency: golang.org/x/tools/internal/semver",
	"GoFiles": [
		"doc.go",
		"goimports.go",
		"goimports_gc.go"
	],
	"IgnoredGoFiles": [
		"goimports_not_gc.go"
	],
	"Imports": [
		"bufio",
		"bytes",
		"errors",
		"flag",
		"fmt",
		"go/scanner",
		"golang.org/x/tools/imports",
		"io",
		"io/ioutil",
		"log",
		"os",
		"os/exec",
		"path/filepath",
		"runtime",
		"runtime/pprof",
		"runtime/trace",
		"strings"
	],
	"Deps": [
		"bufio",
		"bytes",
		"compress/flate",
		"compress/gzip",
		"container/heap",
		"context",
		"encoding",
		"encoding/base64",
		"encoding/binary",
		"encoding/json",
		"errors",
		"flag",
		"fmt",
		"go/ast",
		"go/build",
		"go/constant",
		"go/doc",
		"go/format",
		"go/parser",
		"go/printer",
		"go/scanner",
		"go/token",
		"go/types",
		"golang.org/x/tools/go/ast/astutil",
		"golang.org/x/tools/go/gcexportdata",
		"golang.org/x/tools/go/internal/cgo",
		"golang.org/x/tools/go/internal/gcimporter",
		"golang.org/x/tools/go/internal/packagesdriver",
		"golang.org/x/tools/go/packages",
		"golang.org/x/tools/imports",
		"golang.org/x/tools/internal/fastwalk",
		"golang.org/x/tools/internal/gopathwalk",
		"golang.org/x/tools/internal/module",
		"golang.org/x/tools/internal/semver",
		"hash",
		"hash/crc32",
		"internal/bytealg",
		"internal/cpu",
		"internal/fmtsort",
		"internal/goroot",
		"internal/poll",
		"internal/race",
		"internal/syscall/unix",
		"internal/testlog",
		"io",
		"io/ioutil",
		"log",
		"math",
		"math/big",
		"math/bits",
		"math/rand",
		"net/url",
		"os",
		"os/exec",
		"path",
		"path/filepath",
		"reflect",
		"regexp",
		"regexp/syntax",
		"runtime",
		"runtime/internal/atomic",
		"runtime/internal/math",
		"runtime/internal/sys",
		"runtime/pprof",
		"runtime/trace",
		"sort",
		"strconv",
		"strings",
		"sync",
		"sync/atomic",
		"syscall",
		"text/scanner",
		"text/tabwriter",
		"text/template",
		"text/template/parse",
		"time",
		"unicode",
		"unicode/utf16",
		"unicode/utf8",
		"unsafe"
	]
}
```

Not sure what's causing this difference between the two listings.

# Diff

```
14c14,16
< 	"DepOnly": true,
---
> 	"Match": [
> 		"all"
> 	],
125,133c127
< 	],
< 	"Error": {
< 		"ImportStack": [
< 			"example.com/mymod",
< 			"golang.org/x/tools/cmd/goimports"
< 		],
< 		"Pos": "doc.go:4:5",
< 		"Err": "import \"golang.org/x/tools/cmd/goimports\" is a program, not an importable package"
< 	}
---
> 	]
```

Furthermore, this goes away if you use `./...`.

```
$ go list -deps=true ./... | grep goimports
golang.org/x/tools/cmd/goimports
```

I can reproduce this in other cases  as well e.g. when using an internal package where it isn't accessible (in this case both all and ./... produce the same output).

To summarize, the `x/tools/go/packages` error should be clearer, `go list` should not produce different listings of the same package and `./...` and `all` should produce the same output.