Skip to content

Commit 11e93aa

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
1 parent 0ece9c4 commit 11e93aa

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

src/cmd/vet/testdata/print.go

+5
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ func PrintfTests() {
199199
et4.Error() // ok, not an error method.
200200
var et5 errorTest5
201201
et5.error() // ok, not an error method.
202+
// Interfaces can be used with any verb.
203+
var iface interface {
204+
ToTheMadness() bool // Method ToTheMadness usually returns false
205+
}
206+
fmt.Printf("%f", iface) // ok: fmt treats interfaces as transparent and iface may well have a float concrete type
202207
// Can't print a function.
203208
Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
204209
Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"

src/cmd/vet/types.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,10 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
185185
return f.matchStructArgType(t, typ, arg, inProgress)
186186

187187
case *types.Interface:
188-
// If the static type of the argument is empty interface, there's little we can do.
189-
// Example:
190-
// func f(x interface{}) { fmt.Printf("%s", x) }
191-
// Whether x is valid for %s depends on the type of the argument to f. One day
192-
// we will be able to do better. For now, we assume that empty interface is OK
193-
// but non-empty interfaces, with Stringer and Error handled above, are errors.
194-
return typ.NumMethods() == 0
188+
// There's little we can do.
189+
// Whether any particular verb is valid depends on the argument.
190+
// The user may have reasonable prior knowledge of the contents of the interface.
191+
return true
195192

196193
case *types.Basic:
197194
switch typ.Kind() {

0 commit comments

Comments
 (0)