]> Cypherpunks repositories - gostls13.git/commitdiff
go/doc: don't treat functions returning type parameters as constructors
authorRobert Findley <rfindley@google.com>
Wed, 10 Nov 2021 16:21:57 +0000 (11:21 -0500)
committerRobert Findley <rfindley@google.com>
Wed, 10 Nov 2021 18:06:32 +0000 (18:06 +0000)
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>

src/go/doc/reader.go
src/go/doc/testdata/generics.0.golden
src/go/doc/testdata/generics.1.golden
src/go/doc/testdata/generics.2.golden
src/go/doc/testdata/generics.go

index 348b9b59a02dd1ac9d46f39bd00e59d10a311fb2..7ff868f0627cc8927f05b04571f94048b3231e82 100644 (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
index a6dbcf673ce0a1f9b15a488e27cddb12e21f41e5..91c874c84d69eb58329bd144453864c0f7b44b90 100644 (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 ...
index c0548b5e966d4f350d2a35af8340d174224d4e1a..923a4ce5d9ae65cdf5c361cca40669e6fdcfa886 100644 (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 ...
index a6dbcf673ce0a1f9b15a488e27cddb12e21f41e5..91c874c84d69eb58329bd144453864c0f7b44b90 100644 (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 ...
index b5debba43734ee81006cf1d3d2fb31b87de4cd70..ba7187e4dd9f9d8f4dc04b401be57b474ad5d878 100644 (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
+}