refactor/rename: don't stop because of "soft" errors
Because go/types is slightly more strict than gc about certain "soft"
errors (ones that aren't necessary to interpret a Go program), gorename
rejects programs that compile under gc. This change relaxes gorename's
error checks so that they are weaker than gc's.
This is a workaround for issue golang/go#14596 in gorename,
whose underlying problem is issue golang/go#8560 in gc.
Fixes golang/go#14596
Change-Id: Ica5006c2376c0564a575224269093c1497348ee6
Reviewed-on: https://go-review.googlesource.com/29853
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/refactor/rename/rename.go b/refactor/rename/rename.go
index 766bbc2..40ca480 100644
--- a/refactor/rename/rename.go
+++ b/refactor/rename/rename.go
@@ -384,7 +384,41 @@
for pkg := range pkgs {
conf.ImportWithTests(pkg)
}
- return conf.Load()
+
+ // Ideally we would just return conf.Load() here, but go/types
+ // reports certain "soft" errors that gc does not (Go issue 14596).
+ // As a workaround, we set AllowErrors=true and then duplicate
+ // the loader's error checking but allow soft errors.
+ // It would be nice if the loader API permitted "AllowErrors: soft".
+ conf.AllowErrors = true
+ prog, err := conf.Load()
+ var errpkgs []string
+ // Report hard errors in indirectly imported packages.
+ for _, info := range prog.AllPackages {
+ if containsHardErrors(info.Errors) {
+ errpkgs = append(errpkgs, info.Pkg.Path())
+ }
+ }
+ if errpkgs != nil {
+ var more string
+ if len(errpkgs) > 3 {
+ more = fmt.Sprintf(" and %d more", len(errpkgs)-3)
+ errpkgs = errpkgs[:3]
+ }
+ return nil, fmt.Errorf("couldn't load packages due to errors: %s%s",
+ strings.Join(errpkgs, ", "), more)
+ }
+ return prog, err
+}
+
+func containsHardErrors(errors []error) bool {
+ for _, err := range errors {
+ if err, ok := err.(types.Error); ok && err.Soft {
+ continue
+ }
+ return true
+ }
+ return false
}
// requiresGlobalRename reports whether this renaming could potentially
diff --git a/refactor/rename/rename_test.go b/refactor/rename/rename_test.go
index 0b3aad6..04931a9 100644
--- a/refactor/rename/rename_test.go
+++ b/refactor/rename/rename_test.go
@@ -1061,6 +1061,29 @@
`,
},
},
+ // Progress after "soft" type errors (Go issue 14596).
+ {
+ ctxt: fakeContext(map[string][]string{
+ "main": {`package main
+
+func main() {
+ var unused, x int
+ print(x)
+}
+`,
+ },
+ }),
+ offset: "/go/src/main/0.go:#54", to: "y", // var x
+ want: map[string]string{
+ "/go/src/main/0.go": `package main
+
+func main() {
+ var unused, y int
+ print(y)
+}
+`,
+ },
+ },
} {
if test.ctxt != nil {
ctxt = test.ctxt