mirror of
https://github.com/golang/go
synced 2024-11-24 09:50:17 -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:
parent
8a3be15077
commit
097aaa9cd6
@ -425,6 +425,11 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
|
|||||||
factoryType = t.Elt
|
factoryType = t.Elt
|
||||||
}
|
}
|
||||||
if n, imp := baseTypeName(factoryType); !imp && r.isVisible(n) && !r.isPredeclared(n) {
|
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 {
|
if t := r.lookupType(n); t != nil {
|
||||||
typ = t
|
typ = t
|
||||||
numResultTypes++
|
numResultTypes++
|
||||||
@ -446,6 +451,22 @@ func (r *reader) readFunc(fun *ast.FuncDecl) {
|
|||||||
r.funcs.set(fun, r.mode&PreserveAST != 0)
|
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 (
|
var (
|
||||||
noteMarker = `([A-Z][A-Z]+)\(([^)]+)\):?` // MARKER(uid), MARKER at least 2 chars, uid at least 1 char
|
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
|
noteMarkerRx = lazyregexp.New(`^[ \t]*` + noteMarker) // MARKER(uid) at text start
|
||||||
|
6
src/go/doc/testdata/generics.0.golden
vendored
6
src/go/doc/testdata/generics.0.golden
vendored
@ -14,6 +14,12 @@ FUNCTIONS
|
|||||||
// Func has an instantiated constraint.
|
// Func has an instantiated constraint.
|
||||||
func Func[T Constraint[string, Type[int]]]()
|
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
|
TYPES
|
||||||
// AFuncType demonstrates filtering of parameters and type ...
|
// AFuncType demonstrates filtering of parameters and type ...
|
||||||
|
6
src/go/doc/testdata/generics.1.golden
vendored
6
src/go/doc/testdata/generics.1.golden
vendored
@ -14,6 +14,12 @@ FUNCTIONS
|
|||||||
// Func has an instantiated constraint.
|
// Func has an instantiated constraint.
|
||||||
func Func[T Constraint[string, Type[int]]]()
|
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
|
TYPES
|
||||||
// AFuncType demonstrates filtering of parameters and type ...
|
// AFuncType demonstrates filtering of parameters and type ...
|
||||||
|
6
src/go/doc/testdata/generics.2.golden
vendored
6
src/go/doc/testdata/generics.2.golden
vendored
@ -14,6 +14,12 @@ FUNCTIONS
|
|||||||
// Func has an instantiated constraint.
|
// Func has an instantiated constraint.
|
||||||
func Func[T Constraint[string, Type[int]]]()
|
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
|
TYPES
|
||||||
// AFuncType demonstrates filtering of parameters and type ...
|
// AFuncType demonstrates filtering of parameters and type ...
|
||||||
|
13
src/go/doc/testdata/generics.go
vendored
13
src/go/doc/testdata/generics.go
vendored
@ -59,3 +59,16 @@ func AnotherFunc[T ~struct{ f int }](_ struct{ f int }) {}
|
|||||||
// don't filter type parameters (to be consistent with function declarations),
|
// don't filter type parameters (to be consistent with function declarations),
|
||||||
// but DO filter the RHS.
|
// but DO filter the RHS.
|
||||||
type AFuncType[T ~struct{ f int }] func(_ struct{ f int })
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user