@@ -32,7 +32,13 @@ import (
3232)
3333
3434var MaxGoRoutines int
35- var typeParamParent map [* types.TypeParam ]types.Object = make (map [* types.TypeParam ]types.Object )
35+
36+ type typeParamParentEntry struct {
37+ parent types.Object
38+ isFromReceiver bool
39+ }
40+
41+ var typeParamParent map [* types.TypeParam ]typeParamParentEntry = make (map [* types.TypeParam ]typeParamParentEntry )
3642
3743func init () {
3844 // this sets the number of threads that the Go runtime will spawn; this is separate
@@ -530,8 +536,7 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
530536 // do not appear as objects in any scope, so they have to be dealt
531537 // with separately in extractMethods.
532538 if funcObj , ok := obj .(* types.Func ); ok {
533- populateTypeParamParents (funcObj .Type ().(* types.Signature ).TypeParams (), obj )
534- populateTypeParamParents (funcObj .Type ().(* types.Signature ).RecvTypeParams (), obj )
539+ populateTypeParamParentsFromFunction (funcObj )
535540 }
536541 // Populate type parameter parents for defined types and alias types.
537542 if typeNameObj , ok := obj .(* types.TypeName ); ok {
@@ -542,9 +547,9 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label)
542547 // careful with alias types because before Go 1.24 they would
543548 // return the underlying type.
544549 if tp , ok := typeNameObj .Type ().(* types.Named ); ok && ! typeNameObj .IsAlias () {
545- populateTypeParamParents (tp .TypeParams (), obj )
550+ populateTypeParamParents (tp .TypeParams (), obj , false )
546551 } else if tp , ok := typeNameObj .Type ().(* types.Alias ); ok {
547- populateTypeParamParents (tp .TypeParams (), obj )
552+ populateTypeParamParents (tp .TypeParams (), obj , false )
548553 }
549554 }
550555 extractObject (tw , obj , lbl )
@@ -570,8 +575,7 @@ func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label {
570575 if ! exists {
571576 // Populate type parameter parents for methods. They do not appear as
572577 // objects in any scope, so they have to be dealt with separately here.
573- populateTypeParamParents (meth .Type ().(* types.Signature ).TypeParams (), meth )
574- populateTypeParamParents (meth .Type ().(* types.Signature ).RecvTypeParams (), meth )
578+ populateTypeParamParentsFromFunction (meth )
575579 extractObject (tw , meth , methlbl )
576580 }
577581
@@ -1677,9 +1681,9 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
16771681 }
16781682 case * types.TypeParam :
16791683 kind = dbscheme .TypeParamType .Index ()
1680- parentlbl := getTypeParamParentLabel (tw , tp )
1684+ parentlbl , isReceiverChild := getTypeParamParentLabel (tw , tp )
16811685 constraintLabel := extractType (tw , tp .Constraint ())
1682- dbscheme .TypeParamTable .Emit (tw , lbl , tp .Obj ().Name (), constraintLabel , parentlbl , tp .Index ())
1686+ dbscheme .TypeParamTable .Emit (tw , lbl , tp .Obj ().Name (), constraintLabel , parentlbl , tp .Index (), isReceiverChild )
16831687 case * types.Union :
16841688 kind = dbscheme .TypeSetLiteral .Index ()
16851689 for i := 0 ; i < tp .Len (); i ++ {
@@ -1819,9 +1823,9 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) {
18191823 }
18201824 lbl = tw .Labeler .GlobalID (fmt .Sprintf ("{%s};definedtype" , entitylbl ))
18211825 case * types.TypeParam :
1822- parentlbl := getTypeParamParentLabel (tw , tp )
1826+ parentlbl , isReceiverChild := getTypeParamParentLabel (tw , tp )
18231827 idx := tp .Index ()
1824- lbl = tw .Labeler .GlobalID (fmt .Sprintf ("{%v},%d,%s;typeparamtype" , parentlbl , idx , tp .Obj ().Name ()))
1828+ lbl = tw .Labeler .GlobalID (fmt .Sprintf ("{%v},%d,%t,% s;typeparamtype" , parentlbl , idx , isReceiverChild , tp .Obj ().Name ()))
18251829 case * types.Union :
18261830 var b strings.Builder
18271831 for i := 0 ; i < tp .Len (); i ++ {
@@ -2005,11 +2009,18 @@ func extractTypeParamDecls(tw *trap.Writer, fields *ast.FieldList, parent trap.L
20052009 }
20062010}
20072011
2012+ func populateTypeParamParentsFromFunction (funcObj * types.Func ) {
2013+ signature := funcObj .Type ().(* types.Signature )
2014+ populateTypeParamParents (signature .RecvTypeParams (), funcObj , true )
2015+ populateTypeParamParents (signature .TypeParams (), funcObj , false )
2016+ }
2017+
20082018// populateTypeParamParents sets `parent` as the parent of the elements of `typeparams`
2009- func populateTypeParamParents (typeparams * types.TypeParamList , parent types.Object ) {
2019+ // and records whether elements are defined in a receiver.
2020+ func populateTypeParamParents (typeparams * types.TypeParamList , parent types.Object , isFromReceiver bool ) {
20102021 if typeparams != nil {
2011- for idx := 0 ; idx < typeparams .Len (); idx ++ {
2012- setTypeParamParent (typeparams . At ( idx ) , parent )
2022+ for tparam := range typeparams .TypeParams () {
2023+ setTypeParamParent (tparam , parent , isFromReceiver )
20132024 }
20142025 }
20152026}
@@ -2028,24 +2039,26 @@ func getObjectBeingUsed(tw *trap.Writer, ident *ast.Ident) types.Object {
20282039 }
20292040}
20302041
2031- func getTypeParamParentLabel (tw * trap.Writer , tp * types.TypeParam ) trap.Label {
2032- parent , exists := typeParamParent [tp ]
2042+ func getTypeParamParentLabel (tw * trap.Writer , tp * types.TypeParam ) ( trap.Label , bool ) {
2043+ entry , exists := typeParamParent [tp ]
20332044 if ! exists {
20342045 log .Fatalf ("Parent of type parameter does not exist: %s %s" , tp .String (), tp .Constraint ().String ())
20352046 }
2036- parentlbl , _ := tw .Labeler .ScopedObjectID (parent , func () trap.Label {
2047+ parentlbl , _ := tw .Labeler .ScopedObjectID (entry . parent , func () trap.Label {
20372048 log .Fatalf ("getTypeLabel() called for parent of type parameter %s" , tp .String ())
20382049 return trap .InvalidLabel
20392050 })
2040- return parentlbl
2051+ return parentlbl , entry . isFromReceiver
20412052}
20422053
2043- func setTypeParamParent (tp * types.TypeParam , newobj types.Object ) {
2044- obj , exists := typeParamParent [tp ]
2054+ func setTypeParamParent (tp * types.TypeParam , parent types.Object , isFromReceiver bool ) {
2055+ entry , exists := typeParamParent [tp ]
2056+ newEntry := typeParamParentEntry {parent , isFromReceiver }
20452057 if ! exists {
2046- typeParamParent [tp ] = newobj
2047- } else if newobj != obj {
2048- log .Fatalf ("Parent of type parameter '%s %s' being set to a different value: '%s' vs '%s'" , tp .String (), tp .Constraint ().String (), obj , newobj )
2058+ typeParamParent [tp ] = newEntry
2059+ } else if entry != newEntry {
2060+ log .Fatalf ("Parent of type parameter '%s %s' being set to a different value: {'%s', %t}' vs {'%s', %t}" ,
2061+ tp .String (), tp .Constraint ().String (), entry .parent , entry .isFromReceiver , parent , isFromReceiver )
20492062 }
20502063}
20512064
0 commit comments