golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.11k stars 17.68k forks source link

go/packages: gotypesalias=1 does not seem to get used correctly for deps on Go 1.23 #70394

Open mvdan opened 3 hours ago

mvdan commented 3 hours ago
$ go version
go version go1.23.3 linux/amd64
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/mvdan/.cache/go-build'
GOENV='/home/mvdan/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/mvdan/go/pkg/mod'
GONOPROXY='github.com/cue-unity'
GONOSUMDB='github.com/cue-unity'
GOOS='linux'
GOPATH='/home/mvdan/go'
GOPRIVATE='github.com/cue-unity'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.3'
GODEBUG=''
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/mvdan/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build977617588=/tmp/go-build -gno-record-gcc-switches'

Take the testscript below:

go run .

go run . -godebug

go run . -godebug -needsyntax

go run . -needsyntax
-- go.mod --
module test

go 1.23

require golang.org/x/tools v0.27.0

require (
    golang.org/x/mod v0.22.0 // indirect
    golang.org/x/sync v0.9.0 // indirect
)
-- go.sum --
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
-- main.go --
package main

import (
    "flag"
    "fmt"
    "os"

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

var (
    godebug    = flag.Bool("godebug", false, "")
    needsyntax = flag.Bool("needsyntax", false, "")
)

func main() {
    flag.Parse()
    if *godebug {
        os.Setenv("GODEBUG", "gotypesalias=1")
    }
    mode := packages.NeedTypes
    if *needsyntax {
        mode |= packages.NeedSyntax
    }
    cfg := &packages.Config{Mode: mode}
    pkgs, err := packages.Load(cfg, "./pkg1")
    if err != nil {
        panic(err)
    }
    if packages.PrintErrors(pkgs) > 0 {
        os.Exit(1)
    }

    pkg := pkgs[0]
    scope := pkg.Types.Scope()
    fmt.Println(scope.Lookup("Var1"))
    fmt.Println(scope.Lookup("Var2"))
}
-- pkg1/pkg1.go --
package pkg1

import "test/pkg2"

type Alias1 = int32

var Var1 Alias1

var Var2 pkg2.Alias2

-- pkg2/pkg2.go --
package pkg2

type Alias2 = int64

With https://pkg.go.dev/github.com/rogpeppe/go-internal/cmd/testscript, I see:

> go run .
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 int64

> go run . -godebug
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 int64

> go run . -godebug -needsyntax
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2

> go run . -needsyntax
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2

The first two results seem wrong; alias tracking is lost for the transitive dependency, given that we see the alias target int64 rather than the alias declared in the transitive dependency, pkg2.Alias2. This happens whether or not I set the GODEBUG flag, which should already be on by default in Go 1.23.

The issue only goes away once I set NeedSyntax, which presumably forces the current process to parse and typecheck all packages directly, rather than relying on the Go toolchain to typecheck transitive dependencies and store the results in GOCACHE, for the current process to load from a warm cache.

This bug seems to go away as of go version devel go1.24-493edb2973 2024-11-16 15:10:05 +0000 linux/amd64:

> go run .
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2

> go run . -godebug
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2

> go run . -godebug -needsyntax
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2

> go run . -needsyntax
[stdout]
var test/pkg1.Var1 test/pkg1.Alias1
var test/pkg1.Var2 test/pkg2.Alias2
gabyhelp commented 3 hours ago

Related Issues

Related Code Changes

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)