mirror of https://github.com/golang/go.git
go/analysis/passes/printf: check for nil scope of instance methods
Fixes golang/go#55350 Change-Id: I28784b42de72e9d489e40d546e171af23b9e5c13 Reviewed-on: https://go-review.googlesource.com/c/tools/+/433755 gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Tim King <taking@google.com> Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
3db607bf98
commit
199742a5a6
|
|
@ -945,11 +945,16 @@ func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) {
|
|||
return "", false
|
||||
}
|
||||
|
||||
// inScope returns true if e is in the scope of f.
|
||||
inScope := func(e ast.Expr, f *types.Func) bool {
|
||||
return f.Scope() != nil && f.Scope().Contains(e.Pos())
|
||||
}
|
||||
|
||||
// Is the expression e within the body of that String or Error method?
|
||||
var method *types.Func
|
||||
if strOk && strMethod.Pkg() == pass.Pkg && strMethod.Scope().Contains(e.Pos()) {
|
||||
if strOk && strMethod.Pkg() == pass.Pkg && inScope(e, strMethod) {
|
||||
method = strMethod
|
||||
} else if errOk && errMethod.Pkg() == pass.Pkg && errMethod.Scope().Contains(e.Pos()) {
|
||||
} else if errOk && errMethod.Pkg() == pass.Pkg && inScope(e, errMethod) {
|
||||
method = errMethod
|
||||
} else {
|
||||
return "", false
|
||||
|
|
|
|||
|
|
@ -121,3 +121,25 @@ func TestTermReduction[T1 interface{ ~int | string }, T2 interface {
|
|||
fmt.Printf("%d", t2)
|
||||
fmt.Printf("%s", t2) // want "wrong type.*contains typeparams.myInt"
|
||||
}
|
||||
|
||||
type U[T any] struct{}
|
||||
|
||||
func (u U[T]) String() string {
|
||||
fmt.Println(u) // want `fmt.Println arg u causes recursive call to \(typeparams.U\[T\]\).String method`
|
||||
return ""
|
||||
}
|
||||
|
||||
type S[T comparable] struct {
|
||||
t T
|
||||
}
|
||||
|
||||
func (s S[T]) String() T {
|
||||
fmt.Println(s) // Not flagged. We currently do not consider String() T to implement fmt.Stringer (see #55928).
|
||||
return s.t
|
||||
}
|
||||
|
||||
func TestInstanceStringer() {
|
||||
// Tests String method with nil Scope (#55350)
|
||||
fmt.Println(&S[string]{})
|
||||
fmt.Println(&U[string]{})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue