diff --git a/go/analysis/passes/errorsas/errorsas.go b/go/analysis/passes/errorsas/errorsas.go index 8dcbaaa214..337a61d891 100644 --- a/go/analysis/passes/errorsas/errorsas.go +++ b/go/analysis/passes/errorsas/errorsas.go @@ -56,9 +56,13 @@ func run(pass *analysis.Pass) (interface{}, error) { 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 f2e4060e72..bebf267988 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 @@ type iface interface { 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`