]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: allow any printf verb with any interface
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 7 Jul 2016 23:09:08 +0000 (16:09 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 18 Aug 2016 02:01:25 +0000 (02:01 +0000)
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>
src/cmd/vet/testdata/print.go
src/cmd/vet/types.go

index ab97256c0882986253ff27e5271aae7496d1280a..6805b0ec604742688d04453e1883f581cf7ef410 100644 (file)
@@ -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"
index 4d0e6154b84fdce282171a3db2ec7ac633979984..35ee19c85b899b14d962f16e13de3147a1c165be 100644 (file)
@@ -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() {