@@ -21,7 +21,6 @@ import (
2121 "sync"
2222 "unicode"
2323
24- "golang.org/x/tools/go/internal/packagesdriver"
2524 "golang.org/x/tools/internal/gocommand"
2625 "golang.org/x/tools/internal/packagesinternal"
2726)
@@ -149,7 +148,7 @@ func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error
149148 if cfg .Mode & NeedTypesSizes != 0 || cfg .Mode & NeedTypes != 0 {
150149 errCh := make (chan error )
151150 go func () {
152- compiler , arch , err := packagesdriver . GetSizesForArgsGolist (ctx , state .cfgInvocation (), cfg .gocmdRunner )
151+ compiler , arch , err := getSizesForArgs (ctx , state .cfgInvocation (), cfg .gocmdRunner )
153152 response .dr .Compiler = compiler
154153 response .dr .Arch = arch
155154 errCh <- err
@@ -1024,3 +1023,44 @@ func cmdDebugStr(cmd *exec.Cmd) string {
10241023 }
10251024 return fmt .Sprintf ("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v" , env ["GOROOT" ], env ["GOPATH" ], env ["GO111MODULE" ], env ["GOPROXY" ], env ["PWD" ], strings .Join (args , " " ))
10261025}
1026+
1027+ // getSizesForArgs queries 'go list' for the appropriate
1028+ // Compiler and GOARCH arguments to pass to [types.SizesFor].
1029+ func getSizesForArgs (ctx context.Context , inv gocommand.Invocation , gocmdRunner * gocommand.Runner ) (string , string , error ) {
1030+ inv .Verb = "list"
1031+ inv .Args = []string {"-f" , "{{context.GOARCH}} {{context.Compiler}}" , "--" , "unsafe" }
1032+ stdout , stderr , friendlyErr , rawErr := gocmdRunner .RunRaw (ctx , inv )
1033+ var goarch , compiler string
1034+ if rawErr != nil {
1035+ rawErrMsg := rawErr .Error ()
1036+ if strings .Contains (rawErrMsg , "cannot find main module" ) ||
1037+ strings .Contains (rawErrMsg , "go.mod file not found" ) {
1038+ // User's running outside of a module.
1039+ // All bets are off. Get GOARCH and guess compiler is gc.
1040+ // TODO(matloob): Is this a problem in practice?
1041+ inv .Verb = "env"
1042+ inv .Args = []string {"GOARCH" }
1043+ envout , enverr := gocmdRunner .Run (ctx , inv )
1044+ if enverr != nil {
1045+ return "" , "" , enverr
1046+ }
1047+ goarch = strings .TrimSpace (envout .String ())
1048+ compiler = "gc"
1049+ } else if friendlyErr != nil {
1050+ return "" , "" , friendlyErr
1051+ } else {
1052+ // This should be unreachable, but be defensive
1053+ // in case RunRaw's error results are inconsistent.
1054+ return "" , "" , rawErr
1055+ }
1056+ } else {
1057+ fields := strings .Fields (stdout .String ())
1058+ if len (fields ) < 2 {
1059+ return "" , "" , fmt .Errorf ("could not parse GOARCH and Go compiler in format \" <GOARCH> <compiler>\" :\n stdout: <<%s>>\n stderr: <<%s>>" ,
1060+ stdout .String (), stderr .String ())
1061+ }
1062+ goarch = fields [0 ]
1063+ compiler = fields [1 ]
1064+ }
1065+ return compiler , goarch , nil
1066+ }
0 commit comments