aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2020-08-04 13:24:37 -0400
committerMichael Matloob <matloob@golang.org>2020-08-05 18:24:52 +0000
commit6f08e89ec3280bf6577c2bdb01243cbeeb1a259d (patch)
tree191fb7f22875be7e127baf6cb871fba64f6b1e20
parentf235275097eb68b36d171908cea6a0be23351a94 (diff)
downloadgo-6f08e89ec3280bf6577c2bdb01243cbeeb1a259d.tar.gz
go-6f08e89ec3280bf6577c2bdb01243cbeeb1a259d.zip
cmd/go: fix error stacks when there are scanner errors
After golang.org/cl/228784 setLoadPackageDataError tries to decide whether an error is caused by an imported package or an importing package by examining the error itself to decide. Ideally, the errors themselves would belong to a specific interface or some other property to make it unambiguous that they were import errors. Since they don't, setLoadPackageDataError just checked for nogoerrors and classified all other errors as import errors. But it missed scanner errors which are also "caused" by the imported package. Fixes #40544 Change-Id: I39159bfdc286bee73697decd07b8aa9451f2db06 Reviewed-on: https://go-review.googlesource.com/c/go/+/246717 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
-rw-r--r--src/cmd/go/internal/load/pkg.go29
-rw-r--r--src/cmd/go/testdata/script/list_err_stack.txt27
2 files changed, 43 insertions, 13 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index fcc47bd9c5..2b5fbb1c5b 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -239,11 +239,25 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
err = &NoGoError{Package: p}
}
+ // Take only the first error from a scanner.ErrorList. PackageError only
+ // has room for one position, so we report the first error with a position
+ // instead of all of the errors without a position.
+ var pos string
+ var isScanErr bool
+ if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
+ isScanErr = true // For stack push/pop below.
+
+ scanPos := scanErr[0].Pos
+ scanPos.Filename = base.ShortPath(scanPos.Filename)
+ pos = scanPos.String()
+ err = errors.New(scanErr[0].Msg)
+ }
+
// Report the error on the importing package if the problem is with the import declaration
// for example, if the package doesn't exist or if the import path is malformed.
// On the other hand, don't include a position if the problem is with the imported package,
// for example there are no Go files (NoGoError), or there's a problem in the imported
- // package's source files themselves.
+ // package's source files themselves (scanner errors).
//
// TODO(matloob): Perhaps make each of those the errors in the first group
// (including modload.ImportMissingError, and the corresponding
@@ -254,22 +268,11 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
// to make it easier to check for them? That would save us from having to
// move the modload errors into this package to avoid a package import cycle,
// and from having to export an error type for the errors produced in build.
- if !isMatchErr && nogoErr != nil {
+ if !isMatchErr && (nogoErr != nil || isScanErr) {
stk.Push(path)
defer stk.Pop()
}
- // Take only the first error from a scanner.ErrorList. PackageError only
- // has room for one position, so we report the first error with a position
- // instead of all of the errors without a position.
- var pos string
- if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
- scanPos := scanErr[0].Pos
- scanPos.Filename = base.ShortPath(scanPos.Filename)
- pos = scanPos.String()
- err = errors.New(scanErr[0].Msg)
- }
-
p.Error = &PackageError{
ImportStack: stk.Copy(),
Pos: pos,
diff --git a/src/cmd/go/testdata/script/list_err_stack.txt b/src/cmd/go/testdata/script/list_err_stack.txt
new file mode 100644
index 0000000000..a7be9fde6d
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_err_stack.txt
@@ -0,0 +1,27 @@
+
+# golang.org/issue/40544: regression in error stacks for parse errors
+
+env GO111MODULE=off
+cd sandbox/foo
+go list -e -json .
+stdout '"sandbox/foo"'
+stdout '"sandbox/bar"'
+stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"'
+stdout '"Err": "expected ''package'', found ackage"'
+
+env GO111MODULE=on
+go list -e -json .
+stdout '"sandbox/foo"'
+stdout '"sandbox/bar"'
+stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"'
+stdout '"Err": "expected ''package'', found ackage"'
+
+-- sandbox/go.mod --
+module sandbox
+
+-- sandbox/foo/foo.go --
+package pkg
+
+import "sandbox/bar"
+-- sandbox/bar/bar.go --
+ackage bar \ No newline at end of file