]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: use go/printer to pretty-print expressions in printf messages
authorRob Pike <r@golang.org>
Fri, 1 Mar 2013 20:30:09 +0000 (12:30 -0800)
committerRob Pike <r@golang.org>
Fri, 1 Mar 2013 20:30:09 +0000 (12:30 -0800)
Fixes #4945.
Most examples in this issue now better, but #10 is incomplete and I'm not
certain how to reproduce it. It actually looks like a go/types problem, since
the type being reported is coming directly from that package.
Please reopen the issue if you disagree.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7448046

src/cmd/vet/main.go
src/cmd/vet/print.go
src/cmd/vet/test_print.go

index 8d575e20b253de979c5b802cc269ffffa09f9fc0..20f6cca1abafcd806aecf69c4c2aa66aed3c02ed 100644 (file)
@@ -392,7 +392,7 @@ func (f *File) walkRangeStmt(n *ast.RangeStmt) {
        checkRangeLoop(f, n)
 }
 
-// goFmt returns a string representation of the expression
+// gofmt returns a string representation of the expression.
 func (f *File) gofmt(x ast.Expr) string {
        f.b.Reset()
        printer.Fprint(&f.b, f.fset, x)
index 70ece02bf532151d2e3df32be705394c73f8b56a..fb0fb9f9b7a116a7c64e36b9831cded7fca0c27a 100644 (file)
@@ -280,7 +280,7 @@ func (f *File) checkPrintfArg(call *ast.CallExpr, verb rune, flags []byte, argNu
                        // arg must be integer.
                        for i := 0; i < nargs-1; i++ {
                                if !f.matchArgType(argInt, call.Args[argNum+i]) {
-                                       f.Badf(call.Pos(), "arg %s for * in printf format not of type int", call.Args[argNum+i])
+                                       f.Badf(call.Pos(), "arg %s for * in printf format not of type int", f.gofmt(call.Args[argNum+i]))
                                }
                        }
                        for _, v := range printVerbs {
@@ -291,7 +291,7 @@ func (f *File) checkPrintfArg(call *ast.CallExpr, verb rune, flags []byte, argNu
                                                if typ := f.pkg.types[arg]; typ != nil {
                                                        typeString = typ.String()
                                                }
-                                               f.Badf(call.Pos(), "arg %s for printf verb %%%c of wrong type: %s", arg, verb, typeString)
+                                               f.Badf(call.Pos(), "arg %s for printf verb %%%c of wrong type: %s", f.gofmt(arg), verb, typeString)
                                        }
                                        break
                                }
@@ -339,7 +339,7 @@ func (f *File) matchArgType(t printfArgType, arg ast.Expr) bool {
                }
                return t&argFloat != 0
        case types.UntypedInt:
-               return t&(argInt|argFloat) != 0 // You might say Printf("%g", 1234)
+               return t&argInt != 0
        case types.UntypedRune:
                return t&(argInt|argRune) != 0
        case types.UntypedString:
index bd06f25963e51d559251fdfca290592e0b8d7995..8b41e6c69b9bd7d75f7a63e60efd86f3bf2f74bc 100644 (file)
@@ -59,12 +59,12 @@ func PrintfTests() {
        fmt.Printf("%b %b", 3, i)
        fmt.Printf("%c %c %c %c", 3, i, 'x', r)
        fmt.Printf("%d %d", 3, i)
-       fmt.Printf("%e %e %e", 3, 3e9, x)
-       fmt.Printf("%E %E %E", 3, 3e9, x)
-       fmt.Printf("%f %f %f", 3, 3e9, x)
-       fmt.Printf("%F %F %F", 3, 3e9, x)
-       fmt.Printf("%g %g %g", 3, 3e9, x)
-       fmt.Printf("%G %G %G", 3, 3e9, x)
+       fmt.Printf("%e %e", 3e9, x)
+       fmt.Printf("%E %E", 3e9, x)
+       fmt.Printf("%f %f", 3e9, x)
+       fmt.Printf("%F %F", 3e9, x)
+       fmt.Printf("%g %g", 3e9, x)
+       fmt.Printf("%G %G", 3e9, x)
        fmt.Printf("%o %o", 3, i)
        fmt.Printf("%p %p", p, nil)
        fmt.Printf("%q %q %q %q", 3, i, 'x', r)
@@ -77,24 +77,24 @@ func PrintfTests() {
        fmt.Printf("%X %X %X %X", 3, i, "hi", s)
        fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3)
        // Some bad format/argTypes
-       fmt.Printf("%b", 2.3)                      // ERROR "arg for printf verb %b of wrong type"
-       fmt.Printf("%c", 2.3)                      // ERROR "arg for printf verb %c of wrong type"
-       fmt.Printf("%d", 2.3)                      // ERROR "arg for printf verb %d of wrong type"
-       fmt.Printf("%e", "hi")                     // ERROR "arg for printf verb %e of wrong type"
-       fmt.Printf("%E", true)                     // ERROR "arg for printf verb %E of wrong type"
-       fmt.Printf("%f", "hi")                     // ERROR "arg for printf verb %f of wrong type"
-       fmt.Printf("%F", 'x')                      // ERROR "arg for printf verb %F of wrong type"
-       fmt.Printf("%g", "hi")                     // ERROR "arg for printf verb %g of wrong type"
-       fmt.Printf("%G", i)                        // ERROR "arg for printf verb %G of wrong type"
-       fmt.Printf("%o", x)                        // ERROR "arg for printf verb %o of wrong type"
-       fmt.Printf("%p", 23)                       // ERROR "arg for printf verb %p of wrong type"
-       fmt.Printf("%q", x)                        // ERROR "arg for printf verb %q of wrong type"
-       fmt.Printf("%s", b)                        // ERROR "arg for printf verb %s of wrong type"
-       fmt.Printf("%t", 23)                       // ERROR "arg for printf verb %t of wrong type"
-       fmt.Printf("%U", x)                        // ERROR "arg for printf verb %U of wrong type"
-       fmt.Printf("%x", nil)                      // ERROR "arg for printf verb %x of wrong type"
-       fmt.Printf("%X", 2.3)                      // ERROR "arg for printf verb %X of wrong type"
-       fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg for printf verb %g of wrong type"
+       fmt.Printf("%b", "hi")                     // ERROR "arg .hi. for printf verb %b of wrong type"
+       fmt.Printf("%c", 2.3)                      // ERROR "arg 2.3 for printf verb %c of wrong type"
+       fmt.Printf("%d", 2.3)                      // ERROR "arg 2.3 for printf verb %d of wrong type"
+       fmt.Printf("%e", "hi")                     // ERROR "arg .hi. for printf verb %e of wrong type"
+       fmt.Printf("%E", true)                     // ERROR "arg true for printf verb %E of wrong type"
+       fmt.Printf("%f", "hi")                     // ERROR "arg .hi. for printf verb %f of wrong type"
+       fmt.Printf("%F", 'x')                      // ERROR "arg 'x' for printf verb %F of wrong type"
+       fmt.Printf("%g", "hi")                     // ERROR "arg .hi. for printf verb %g of wrong type"
+       fmt.Printf("%G", i)                        // ERROR "arg for printf verb %G of wrong type"
+       fmt.Printf("%o", x)                        // ERROR "arg for printf verb %o of wrong type"
+       fmt.Printf("%p", 23)                       // ERROR "arg 23 for printf verb %p of wrong type"
+       fmt.Printf("%q", x)                        // ERROR "arg for printf verb %q of wrong type"
+       fmt.Printf("%s", b)                        // ERROR "arg for printf verb %s of wrong type"
+       fmt.Printf("%t", 23)                       // ERROR "arg 23 for printf verb %t of wrong type"
+       fmt.Printf("%U", x)                        // ERROR "arg for printf verb %U of wrong type"
+       fmt.Printf("%x", nil)                      // ERROR "arg nil for printf verb %x of wrong type"
+       fmt.Printf("%X", 2.3)                      // ERROR "arg 2.3 for printf verb %X of wrong type"
+       fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type"
        // TODO
        fmt.Println()                      // not an error
        fmt.Println("%s", "hi")            // ERROR "possible formatting directive in Println call"
@@ -105,9 +105,9 @@ func PrintfTests() {
        fmt.Printf("% 8s", "woo")          // correct
        fmt.Printf("%.*d", 3, 3)           // correct
        fmt.Printf("%.*d", 3, 3, 3)        // ERROR "wrong number of args for format in Printf call"
-       fmt.Printf("%.*d", "hi", 3)        // ERROR "arg for \* in printf format not of type int"
+       fmt.Printf("%.*d", "hi", 3)        // ERROR "arg .hi. for \* in printf format not of type int"
        fmt.Printf("%.*d", i, 3)           // correct
-       fmt.Printf("%.*d", s, 3)           // ERROR "arg for \* in printf format not of type int"
+       fmt.Printf("%.*d", s, 3)           // ERROR "arg for \* in printf format not of type int"
        fmt.Printf("%q %q", multi()...)    // ok
        fmt.Printf("%#q", `blah`)          // ok
        printf("now is the time", "buddy") // ERROR "no formatting directive"