mirror of https://github.com/golang/go.git
go/analysis/passes/printf: give leeway for fmt.Formatter satisfaction
We have no way of knowing the concrete type of an interface value; it might be a fmt.Formatter. To avoid false positives, assume that all interface values are fmt.Formatters. Updates golang/go#36564 Change-Id: Iaf18ba2794e4d3095d0018502c1c6c459a360b42 Reviewed-on: https://go-review.googlesource.com/c/tools/+/217180 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
43e3193a9b
commit
aafaee8bce
|
|
@ -508,9 +508,13 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func,
|
|||
return fn, KindNone
|
||||
}
|
||||
|
||||
// isFormatter reports whether t satisfies fmt.Formatter.
|
||||
// isFormatter reports whether t could satisfy fmt.Formatter.
|
||||
// The only interface method to look for is "Format(State, rune)".
|
||||
func isFormatter(typ types.Type) bool {
|
||||
// If the type is an interface, the value it holds might satisfy fmt.Formatter.
|
||||
if _, ok := typ.Underlying().(*types.Interface); ok {
|
||||
return true
|
||||
}
|
||||
obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
|
||||
fn, ok := obj.(*types.Func)
|
||||
if !ok {
|
||||
|
|
@ -827,7 +831,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
|||
}
|
||||
}
|
||||
|
||||
// Does current arg implement fmt.Formatter?
|
||||
// Could current arg implement fmt.Formatter?
|
||||
formatter := false
|
||||
if state.argNum < len(call.Args) {
|
||||
if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok {
|
||||
|
|
|
|||
|
|
@ -101,8 +101,9 @@ func PrintfTests() {
|
|||
fmt.Printf("%v", notstringerarrayv)
|
||||
fmt.Printf("%T", notstringerarrayv)
|
||||
fmt.Printf("%d", new(fmt.Formatter))
|
||||
fmt.Printf("%*%", 2) // Ridiculous but allowed.
|
||||
fmt.Printf("%s", interface{}(nil)) // Nothing useful we can say.
|
||||
fmt.Printf("%*%", 2) // Ridiculous but allowed.
|
||||
fmt.Printf("%s", interface{}(nil)) // Nothing useful we can say.
|
||||
fmt.Printf("%a", interface{}(new(BoolFormatter))) // Could be a fmt.Formatter.
|
||||
|
||||
fmt.Printf("%g", 1+2i)
|
||||
fmt.Printf("%#e %#E %#f %#F %#g %#G", 1.2, 1.2, 1.2, 1.2, 1.2, 1.2) // OK since Go 1.9
|
||||
|
|
|
|||
Loading…
Reference in New Issue