1
0
mirror of https://github.com/golang/go synced 2024-11-23 00:30:07 -07:00

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 <matloob@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
Michael Matloob 2023-06-08 16:20:17 -04:00
parent 5e9b76fe2a
commit 82dc37c0d0
2 changed files with 75 additions and 0 deletions

View File

@ -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
})

View File

@ -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"