From: Michael Matloob Date: Thu, 8 Jun 2023 20:20:17 +0000 (-0400) Subject: cmd/go: don't assume ImportStack always set on PackageError X-Git-Tag: go1.21rc1~43 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=82dc37c0d05c33c00b585664cba1c647bf8ac99e;p=gostls13.git cmd/go: don't assume ImportStack always set on PackageError When determining DepsErrors for packages, we were trying to sort errors by the top package on their ImportStack (which would likely be the package the error was generated for) to get a deterministic error order. The problem is that some PackageErrors don't have ImportStacks set on them. Fall back to sorting the errors by the error text (instead of making things more complicated by tracking the packages that produced the errors more closely). Fixes #59905 Change-Id: Id305e1e70801f8909fd6463383b8eda193559787 Reviewed-on: https://go-review.googlesource.com/c/go/+/501978 Run-TryBot: Michael Matloob Reviewed-by: David Chase TryBot-Result: Gopher Robot Reviewed-by: Bryan Mills --- diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go index 2427b022a1..1addadfea0 100644 --- a/src/cmd/go/internal/list/list.go +++ b/src/cmd/go/internal/list/list.go @@ -949,6 +949,15 @@ func collectDepsErrors(p *load.Package) { // one error set on it. sort.Slice(p.DepsErrors, func(i, j int) bool { stki, stkj := p.DepsErrors[i].ImportStack, p.DepsErrors[j].ImportStack + // Some packages are missing import stacks. To ensure deterministic + // sort order compare two errors that are missing import stacks by + // their errors' error texts. + if len(stki) == 0 { + if len(stkj) != 0 { + return true + } + return p.DepsErrors[i].Err.Error() < p.DepsErrors[j].Err.Error() + } pathi, pathj := stki[len(stki)-1], stkj[len(stkj)-1] return pathi < pathj }) diff --git a/src/cmd/go/testdata/script/list_issue_59905.txt b/src/cmd/go/testdata/script/list_issue_59905.txt new file mode 100644 index 0000000000..7480462599 --- /dev/null +++ b/src/cmd/go/testdata/script/list_issue_59905.txt @@ -0,0 +1,66 @@ +# Expect no panic +go list -f '{{if .DepsErrors}}{{.DepsErrors}}{{end}}' -export -e -deps +cmpenv stdout wanterr + +-- wanterr -- +[# test/main/level1a +level1a${/}pkg.go:5:2: level2x redeclared in this block + level1a${/}pkg.go:4:2: other declaration of level2x +level1a${/}pkg.go:5:2: "test/main/level1a/level2y" imported as level2x and not used +level1a${/}pkg.go:8:39: undefined: level2y + # test/main/level1b +level1b${/}pkg.go:5:2: level2x redeclared in this block + level1b${/}pkg.go:4:2: other declaration of level2x +level1b${/}pkg.go:5:2: "test/main/level1b/level2y" imported as level2x and not used +level1b${/}pkg.go:8:39: undefined: level2y +] +-- go.mod -- +module test/main + +go 1.20 +-- main.go -- +package main + +import ( + "test/main/level1a" + "test/main/level1b" +) + +func main() { + level1a.Print() + level1b.Print() +} +-- level1a/pkg.go -- +package level1a + +import ( + "test/main/level1a/level2x" + "test/main/level1a/level2y" +) + +func Print() { println(level2x.Value, level2y.Value) } +-- level1a/level2x/pkg.go -- +package level2x + +var Value = "1a/2x" +-- level1a/level2y/pkg.go -- +package level2x + +var Value = "1a/2y" +-- level1b/pkg.go -- +package level1b + +import ( + "test/main/level1b/level2x" + "test/main/level1b/level2y" +) + +func Print() { println(level2x.Value, level2y.Value) } +-- level1b/level2x/pkg.go -- +package level2x + +var Value = "1b/2x" +-- level1b/level2y/pkg.go -- +package level2x + +var Value = "1b/2y" \ No newline at end of file