mirror of https://github.com/golang/go.git
go/analysis/passes/printf: update logic now that type parameters are
interfaces Now that the underlying of type parameters is their constraint interface, a couple places in the printf analyzer need to be updated: - We need to explicitly exclude type parameters when looking at interfaces in isFormatter. - We need to consider at the element type, not its underlying, when looking at pointers to type parameters Change-Id: I8c6843e001a98d45ff0f30df305e3536335f567e Reviewed-on: https://go-review.googlesource.com/c/tools/+/364678 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
771dabf433
commit
43b469a3a9
|
|
@ -25,6 +25,7 @@ import (
|
|||
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
|
||||
"golang.org/x/tools/go/ast/inspector"
|
||||
"golang.org/x/tools/go/types/typeutil"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -520,7 +521,12 @@ func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func,
|
|||
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
|
||||
// Don't assume type parameters could be formatters. With the greater
|
||||
// expressiveness of constraint interface syntax we expect more type safety
|
||||
// when using type parameters.
|
||||
if !typeparams.IsTypeParam(typ) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format")
|
||||
fn, ok := obj.(*types.Func)
|
||||
|
|
|
|||
|
|
@ -178,10 +178,12 @@ func (m *argMatcher) match(typ types.Type, topLevel bool) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if typeparams.IsTypeParam(typ.Elem()) {
|
||||
return true // We don't know whether the logic below applies. Give up.
|
||||
}
|
||||
|
||||
under := typ.Elem().Underlying()
|
||||
switch under.(type) {
|
||||
case *typeparams.TypeParam:
|
||||
return true // We don't know whether the logic below applies. Give up.
|
||||
case *types.Struct: // see below
|
||||
case *types.Array: // see below
|
||||
case *types.Slice: // see below
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ package typeparams
|
|||
import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// A IndexExprData holds data from both ast.IndexExpr and the new
|
||||
|
|
@ -23,3 +24,9 @@ type IndexExprData struct {
|
|||
Indices []ast.Expr // index expressions
|
||||
Rbrack token.Pos // position of "]"
|
||||
}
|
||||
|
||||
// IsTypeParam reports whether t is a type parameter.
|
||||
func IsTypeParam(t types.Type) bool {
|
||||
_, ok := t.(*TypeParam)
|
||||
return ok
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue