// {`package qf14; type T[_ any] int; func ((*(T[_]))) _() {}`, `(T[_])`, `qf14.T[_]`}, // parser doesn't record parens
                // {`package qf15; type T[_ any] int; func ((*(T[_]))) _() {}`, `*(T[_])`, `*qf15.T[_]`}, // parser doesn't record parens
                // {`package qf16; type T[_ any] int; func ((*(T[_]))) _() {}`, `(*(T[_]))`, `*qf16.T[_]`}, // parser doesn't record parens
+
+               // For historic reasons, type parameters in receiver type expressions
+               // are considered both definitions and uses and thus also show up in
+               // the Info.Types map (see go.dev/issue/68670).
+               {`package t1; type T[_ any] int; func (T[P]) _() {}`, `P`, `P`},
+               {`package t2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `P`},
+               {`package t3; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `Q`},
        }
 
        for _, test := range tests {
                {`package g0; type x[T any] int`, `x`, `type g0.x[T any] int`},
                {`package g1; func f[T any]() {}`, `f`, `func g1.f[T any]()`},
                {`package g2; type x[T any] int; func (*x[_]) m() {}`, `m`, `func (*g2.x[_]).m()`},
+
+               // Type parameters in receiver type expressions are definitions.
+               {`package r0; type T[_ any] int; func (T[P]) _() {}`, `P`, `type parameter P any`},
+               {`package r1; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `type parameter P any`},
+               {`package r2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `type parameter Q any`},
        }
 
        for _, test := range tests {
                        `m`,
                        `func (m10.E[int]).m()`,
                },
+
+               // For historic reasons, type parameters in receiver type expressions
+               // are considered both definitions and uses (see go.dev/issue/68670).
+               {`package r0; type T[_ any] int; func (T[P]) _() {}`, `P`, `type parameter P any`},
+               {`package r1; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `type parameter P any`},
+               {`package r2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `type parameter Q any`},
        }
 
        for _, test := range tests {
 
                // after typechecking rbase (see go.dev/issue/52038).
                recvTParams := make([]*TypeParam, len(rtparams))
                for i, rparam := range rtparams {
-                       recvTParams[i] = check.declareTypeParam(rparam, scopePos)
+                       tpar := check.declareTypeParam(rparam, scopePos)
+                       recvTParams[i] = tpar
+                       // For historic reasons, type parameters in receiver type expressions
+                       // are considered both definitions and uses and thus must be recorded
+                       // in the Info.Uses and Info.Types maps (see go.dev/issue/68670).
+                       check.recordUse(rparam, tpar.obj)
+                       check.recordTypeAndValue(rparam, typexpr, tpar, nil)
                }
                recvTParamsList = bindTParams(recvTParams)
 
 
                {`package qf14; type T[_ any] int; func ((*(T[_]))) _() {}`, `(T[_])`, `qf14.T[_]`},
                {`package qf15; type T[_ any] int; func ((*(T[_]))) _() {}`, `*(T[_])`, `*qf15.T[_]`},
                {`package qf16; type T[_ any] int; func ((*(T[_]))) _() {}`, `(*(T[_]))`, `*qf16.T[_]`},
+
+               // For historic reasons, type parameters in receiver type expressions
+               // are considered both definitions and uses and thus also show up in
+               // the Info.Types map (see go.dev/issue/68670).
+               {`package t1; type T[_ any] int; func (T[P]) _() {}`, `P`, `P`},
+               {`package t2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `P`},
+               {`package t3; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `Q`},
        }
 
        for _, test := range tests {
                {`package g0; type x[T any] int`, `x`, `type g0.x[T any] int`},
                {`package g1; func f[T any]() {}`, `f`, `func g1.f[T any]()`},
                {`package g2; type x[T any] int; func (*x[_]) m() {}`, `m`, `func (*g2.x[_]).m()`},
+
+               // Type parameters in receiver type expressions are definitions.
+               {`package r0; type T[_ any] int; func (T[P]) _() {}`, `P`, `type parameter P any`},
+               {`package r1; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `type parameter P any`},
+               {`package r2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `type parameter Q any`},
        }
 
        for _, test := range tests {
                },
                {`package m11; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `m`, `func (m11.T[int]).m()`},
                {`package m12; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `n`, `func (m12.T[string]).n()`},
+
+               // For historic reasons, type parameters in receiver type expressions
+               // are considered both definitions and uses (see go.dev/issue/68670).
+               {`package r0; type T[_ any] int; func (T[P]) _() {}`, `P`, `type parameter P any`},
+               {`package r1; type T[_, _ any] int; func (T[P, Q]) _() {}`, `P`, `type parameter P any`},
+               {`package r2; type T[_, _ any] int; func (T[P, Q]) _() {}`, `Q`, `type parameter Q any`},
        }
 
        for _, test := range tests {
 
        // list (so we can have mutually recursive parameterized interfaces).
        scopePos := list.Pos()
        for _, f := range list.List {
-               tparams = check.declareTypeParams(tparams, f.Names, scopePos)
+               for _, name := range f.Names {
+                       tparams = append(tparams, check.declareTypeParam(name, scopePos))
+               }
        }
 
        // Set the type parameters before collecting the type constraints because
        return check.typ(x)
 }
 
-func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident, scopePos token.Pos) []*TypeParam {
+func (check *Checker) declareTypeParam(name *ast.Ident, scopePos token.Pos) *TypeParam {
        // Use Typ[Invalid] for the type constraint to ensure that a type
        // is present even if the actual constraint has not been assigned
        // yet.
        // TODO(gri) Need to systematically review all uses of type parameter
        //           constraints to make sure we don't rely on them if they
        //           are not properly set yet.
-       for _, name := range names {
-               tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
-               tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tpar as a side-effect
-               check.declare(check.scope, name, tname, scopePos)
-               tparams = append(tparams, tpar)
-       }
-
-       if check.conf._Trace && len(names) > 0 {
-               check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
-       }
-
-       return tparams
+       tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
+       tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tname as a side-effect
+       check.declare(check.scope, name, tname, scopePos)
+       return tpar
 }
 
 func (check *Checker) collectMethods(obj *TypeName) {
 
                // Checker.collectTypeParams). The scope of the type parameter T in
                // "func (r T[T]) f() {}" starts after f, not at r, so we declare it
                // after typechecking rbase (see go.dev/issue/52038).
-               recvTParams := check.declareTypeParams(nil, rtparams, scopePos)
+               recvTParams := make([]*TypeParam, len(rtparams))
+               for i, rparam := range rtparams {
+                       tpar := check.declareTypeParam(rparam, scopePos)
+                       recvTParams[i] = tpar
+                       // For historic reasons, type parameters in receiver type expressions
+                       // are considered both definitions and uses and thus must be recorded
+                       // in the Info.Uses and Info.Types maps (see go.dev/issue/68670).
+                       check.recordUse(rparam, tpar.obj)
+                       check.recordTypeAndValue(rparam, typexpr, tpar, nil)
+               }
                recvTParamsList = bindTParams(recvTParams)
 
                // Get the type parameter bounds from the receiver base type