1
0
mirror of https://github.com/golang/go synced 2024-11-24 09:30:07 -07:00

go/doc: don't treat functions returning type parameters as constructors

Functions returning type parameters were erroneously being interpreted
as 'constructors' of their type parameter, resulting in them being
excluded from documentation. Fix this by explicitly excluding type
parameters when looking for defined type names among function results.

Fixes #49477

Change-Id: I22510f655f47e192a852332df5b91740f46c51eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/362758
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Robert Findley 2021-11-10 11:21:57 -05:00
parent 8a3be15077
commit 097aaa9cd6
5 changed files with 52 additions and 0 deletions

View File

@ -425,6 +425,11 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
factoryType = t.Elt
}
if n, imp := baseTypeName(factoryType); !imp && r.isVisible(n) && !r.isPredeclared(n) {
if lookupTypeParam(n, fun.Type.TypeParams) != nil {
// Issue #49477: don't associate fun with its type parameter result.
// A type parameter is not a defined type.
continue
}
if t := r.lookupType(n); t != nil {
typ = t
numResultTypes++
@ -446,6 +451,22 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
r.funcs.set(fun, r.mode&PreserveAST != 0)
}
// lookupTypeParam searches for type parameters named name within the tparams
// field list, returning the relevant identifier if found, or nil if not.
func lookupTypeParam(name string, tparams *ast.FieldList) *ast.Ident {
if tparams == nil {
return nil
}
for _, field := range tparams.List {
for _, id := range field.Names {
if id.Name == name {
return id
}
}
}
return nil
}
var (
noteMarker = `([A-Z][A-Z]+)\(([^)]+)\):?` // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
noteMarkerRx = lazyregexp.New(`^[ \t]*` + noteMarker) // MARKER(uid) at text start

View File

@ -14,6 +14,12 @@ FUNCTIONS
// Func has an instantiated constraint.
func Func[T Constraint[string, Type[int]]]()
// Single is not a factory function.
func Single[T any]() *T
// Slice is not a factory function.
func Slice[T any]() []T
TYPES
// AFuncType demonstrates filtering of parameters and type ...

View File

@ -14,6 +14,12 @@ FUNCTIONS
// Func has an instantiated constraint.
func Func[T Constraint[string, Type[int]]]()
// Single is not a factory function.
func Single[T any]() *T
// Slice is not a factory function.
func Slice[T any]() []T
TYPES
// AFuncType demonstrates filtering of parameters and type ...

View File

@ -14,6 +14,12 @@ FUNCTIONS
// Func has an instantiated constraint.
func Func[T Constraint[string, Type[int]]]()
// Single is not a factory function.
func Single[T any]() *T
// Slice is not a factory function.
func Slice[T any]() []T
TYPES
// AFuncType demonstrates filtering of parameters and type ...

View File

@ -59,3 +59,16 @@ func AnotherFunc[T ~struct{ f int }](_ struct{ f int }) {}
// don't filter type parameters (to be consistent with function declarations),
// but DO filter the RHS.
type AFuncType[T ~struct{ f int }] func(_ struct{ f int })
// See issue #49477: type parameters should not be interpreted as named types
// for the purpose of determining whether a function is a factory function.
// Slice is not a factory function.
func Slice[T any]() []T {
return nil
}
// Single is not a factory function.
func Single[T any]() *T {
return nil
}