From 11e93aa24a61e0c4b25600bf2a681b8779371fe8 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 7 Jul 2016 16:09:08 -0700 Subject: [PATCH] cmd/vet: allow any printf verb with any interface fmt treats interfaces as being transparent. As a result, we cannot say with confidence that any particular verb is wrong. This fixes the following vet false positives in the standard library: database/sql/sql_test.go:210: arg dep for printf verb %p of wrong type: sql.finalCloser fmt/fmt_test.go:1663: arg nil for printf verb %s of wrong type: untyped nil go/ast/commentmap.go:328: arg node for printf verb %p of wrong type: ast.Node net/http/transport_test.go:120: arg c for printf verb %p of wrong type: net.Conn net/http/httptest/server.go:198: arg c for printf verb %p of wrong type: net.Conn net/http/httputil/dump_test.go:258: arg body for printf verb %p of wrong type: io.Reader reflect/set_test.go:81: arg x for printf verb %p of wrong type: io.Writer reflect/set_test.go:141: arg bb for printf verb %p of wrong type: io.Reader Updates #11041 Updates #16314 Change-Id: I76df01abb3c34a97b6960f551bed9c1c91377cfc Reviewed-on: https://go-review.googlesource.com/27127 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- src/cmd/vet/testdata/print.go | 5 +++++ src/cmd/vet/types.go | 11 ++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cmd/vet/testdata/print.go b/src/cmd/vet/testdata/print.go index ab97256c08..6805b0ec60 100644 --- a/src/cmd/vet/testdata/print.go +++ b/src/cmd/vet/testdata/print.go @@ -199,6 +199,11 @@ func PrintfTests() { et4.Error() // ok, not an error method. var et5 errorTest5 et5.error() // ok, not an error method. + // Interfaces can be used with any verb. + var iface interface { + ToTheMadness() bool // Method ToTheMadness usually returns false + } + fmt.Printf("%f", iface) // ok: fmt treats interfaces as transparent and iface may well have a float concrete type // Can't print a function. Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call" Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call" diff --git a/src/cmd/vet/types.go b/src/cmd/vet/types.go index 4d0e6154b8..35ee19c85b 100644 --- a/src/cmd/vet/types.go +++ b/src/cmd/vet/types.go @@ -185,13 +185,10 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp return f.matchStructArgType(t, typ, arg, inProgress) case *types.Interface: - // If the static type of the argument is empty interface, there's little we can do. - // Example: - // func f(x interface{}) { fmt.Printf("%s", x) } - // Whether x is valid for %s depends on the type of the argument to f. One day - // we will be able to do better. For now, we assume that empty interface is OK - // but non-empty interfaces, with Stringer and Error handled above, are errors. - return typ.NumMethods() == 0 + // There's little we can do. + // Whether any particular verb is valid depends on the argument. + // The user may have reasonable prior knowledge of the contents of the interface. + return true case *types.Basic: switch typ.Kind() { -- 2.48.1