errorsas: ignore empty interface target
No longer report a problem if target's type is interface{}.
This avoids false positives like
```
var e error
var i interface{} = &e
... errors.As(..., i) ...
```
Change-Id: Ibf6e7163147248305130a5e650f92b80e34a44de
Reviewed-on: https://go-review.googlesource.com/c/tools/+/175717
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/go/analysis/passes/errorsas/errorsas.go b/go/analysis/passes/errorsas/errorsas.go
index 8dcbaaa..337a61d 100644
--- a/go/analysis/passes/errorsas/errorsas.go
+++ b/go/analysis/passes/errorsas/errorsas.go
@@ -56,9 +56,13 @@
var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
-// pointerToInterfaceOrError reports whether the type of e is a pointer to an interface or a type implementing error.
+// pointerToInterfaceOrError reports whether the type of e is a pointer to an interface or a type implementing error,
+// or is the empty interface.
func pointerToInterfaceOrError(pass *analysis.Pass, e ast.Expr) bool {
t := pass.TypesInfo.Types[e].Type
+ if it, ok := t.Underlying().(*types.Interface); ok && it.NumMethods() == 0 {
+ return true
+ }
pt, ok := t.Underlying().(*types.Pointer)
if !ok {
return false
diff --git a/go/analysis/passes/errorsas/testdata/src/a/a.go b/go/analysis/passes/errorsas/testdata/src/a/a.go
index f2e4060..bebf267 100644
--- a/go/analysis/passes/errorsas/testdata/src/a/a.go
+++ b/go/analysis/passes/errorsas/testdata/src/a/a.go
@@ -20,15 +20,17 @@
func _() {
var (
- e error
- m myError
- i int
- f iface
+ e error
+ m myError
+ i int
+ f iface
+ ei interface{}
)
- errors.As(nil, &e)
- errors.As(nil, &m)
- errors.As(nil, &f)
- errors.As(nil, perr())
+ errors.As(nil, &e) // *error
+ errors.As(nil, &m) // *T where T implemements error
+ errors.As(nil, &f) // *interface
+ errors.As(nil, perr()) // *error, via a call
+ errors.As(nil, ei) // empty interface
errors.As(nil, nil) // want `second argument to errors.As must be a pointer to an interface or a type implementing error`
errors.As(nil, e) // want `second argument to errors.As must be a pointer to an interface or a type implementing error`