mirror of https://github.com/golang/go.git
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 <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
0ece9c4b59
commit
11e93aa24a
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue