vet: Broaden suppression of recursive stringer warning.
Updates golang/go#6212. LGTM=r, gri R=r, gri CC=golang-codereviews https://golang.org/cl/75130043
This commit is contained in:
parent
1a2b7a26cc
commit
d4c8d5dae3
|
|
@ -408,6 +408,15 @@ func (f *File) recursiveStringer(e ast.Expr) bool {
|
||||||
obj = id.Obj
|
obj = id.Obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's unlikely to be a recursive stringer if it has a Format method.
|
||||||
|
if typ := f.pkg.types[e].Type; typ != nil {
|
||||||
|
// Not a perfect match; see issue 6259.
|
||||||
|
if f.hasMethod(typ, "Format") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We compare the underlying Object, which checks that the identifier
|
// We compare the underlying Object, which checks that the identifier
|
||||||
// is the one we declared as the receiver for the String method in
|
// is the one we declared as the receiver for the String method in
|
||||||
// which this printf appears.
|
// which this printf appears.
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ func PrintfTests() {
|
||||||
fmt.Printf("%t", stringerarrayv) // ERROR "arg stringerarrayv for printf verb %t of wrong type"
|
fmt.Printf("%t", stringerarrayv) // ERROR "arg stringerarrayv for printf verb %t of wrong type"
|
||||||
fmt.Printf("%t", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %t of wrong type"
|
fmt.Printf("%t", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %t of wrong type"
|
||||||
fmt.Printf("%q", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %q of wrong type"
|
fmt.Printf("%q", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %q of wrong type"
|
||||||
fmt.Printf("%d", Formatter(true)) // ERROR "arg Formatter\(true\) for printf verb %d of wrong type"
|
fmt.Printf("%d", Formatter(true)) // correct (the type is responsible for formatting)
|
||||||
fmt.Printf("%s", nonemptyinterface) // correct (the dynamic type of nonemptyinterface may be a stringer)
|
fmt.Printf("%s", nonemptyinterface) // correct (the dynamic type of nonemptyinterface may be a stringer)
|
||||||
fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type"
|
fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type"
|
||||||
fmt.Println() // not an error
|
fmt.Println() // not an error
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
|
||||||
// if its method set contains a Format function. We could do better,
|
// if its method set contains a Format function. We could do better,
|
||||||
// even now, but we don't need to be 100% accurate. Wait for 6259 to
|
// even now, but we don't need to be 100% accurate. Wait for 6259 to
|
||||||
// be fixed instead. TODO.
|
// be fixed instead. TODO.
|
||||||
if hasMethod(typ, "Format") {
|
if f.hasMethod(typ, "Format") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
|
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
|
||||||
|
|
@ -313,13 +313,10 @@ func (f *File) isErrorMethodCall(call *ast.CallExpr) bool {
|
||||||
|
|
||||||
// hasMethod reports whether the type contains a method with the given name.
|
// hasMethod reports whether the type contains a method with the given name.
|
||||||
// It is part of the workaround for Formatters and should be deleted when
|
// It is part of the workaround for Formatters and should be deleted when
|
||||||
// that workaround is no longer necessary. TODO: delete when fixed.
|
// that workaround is no longer necessary.
|
||||||
func hasMethod(typ types.Type, name string) bool {
|
// TODO: This could be better once issue 6259 is fixed.
|
||||||
set := types.NewMethodSet(typ)
|
func (f *File) hasMethod(typ types.Type, name string) bool {
|
||||||
for i := 0; i < set.Len(); i++ {
|
obj, _, _ := types.LookupFieldOrMethod(typ, f.pkg.typesPkg, name)
|
||||||
if set.At(i).Obj().Name() == name {
|
_, ok := obj.(*types.Func)
|
||||||
return true
|
return ok
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue