return newsym.Def.Type()
}
- // In order to deal with recursive generic types, create a TFORW type
- // initially and set its Def field, so it can be found if this type
- // appears recursively within the type.
- forw = types.New(types.TFORW)
- forw.SetSym(newsym)
- newsym.Def = ir.TypeNode(forw)
+ // In order to deal with recursive generic types, create a TFORW
+ // type initially and set the Def field of its sym, so it can be
+ // found if this type appears recursively within the type.
+ forw = newNamedTypeWithSym(t.Pos(), newsym)
//println("Creating new type by sub", newsym.Name, forw.HasTParam())
forw.SetRParams(neededTargs)
}
}
return t
}
+
+// newNamedTypeWithSym returns a TFORW type t with name specified by sym, such
+// that t.nod and sym.Def are set correctly.
+func newNamedTypeWithSym(pos src.XPos, sym *types.Sym) *types.Type {
+ name := ir.NewDeclNameAt(pos, ir.OTYPE, sym)
+ forw := types.NewNamed(name)
+ name.SetType(forw)
+ sym.Def = name
+ return forw
+}
// which may set HasTParam) before translating the
// underlying type itself, so we handle recursion
// correctly, including via method signatures.
- ntyp := types.New(types.TFORW)
+ ntyp := newNamedTypeWithSym(g.pos(typ.Obj().Pos()), s)
g.typs[typ] = ntyp
- ntyp.SetSym(s)
- s.Def = ir.TypeNode(ntyp)
// If ntyp still has type params, then we must be
// referencing something like 'value[T2]', as when
methods Fields
allMethods Fields
- nod Object // canonical OTYPE node
- underlying *Type // original type (type literal or predefined type)
+ // canonical OTYPE node for a named type (should be an ir.Name node with same sym)
+ nod Object
+ underlying *Type // original type (type literal or predefined type)
// Cache of composite types, with this type being the element type.
cache struct {
TypeResultMem = newResults([]*Type{TypeMem})
)
-// NewNamed returns a new named type for the given type name.
+// NewNamed returns a new named type for the given type name. obj should be an ir.Name.
func NewNamed(obj Object) *Type {
t := New(TFORW)
t.sym = obj.Sym()
return t
}
-// Obj returns the type name for the named type t.
+// Obj returns the canonical type name node for a named type t, nil for an unnamed type.
func (t *Type) Obj() Object {
if t.sym != nil {
return t.nod
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type I interface{}
+
+type _S[T any] struct {
+ *T
+}
+
+// F is a non-generic function, but has a type _S[I] which is instantiated from a
+// generic type. Test that _S[I] is successfully exported.
+func F() {
+ v := _S[I]{}
+ if v.T != nil {
+ panic(v)
+ }
+}
+
+// Testing the various combinations of method expressions.
+type S1 struct{}
+func (*S1) M() {}
+
+type S2 struct{}
+func (S2) M() {}
+
+func _F1[T interface{ M() }](t T) {
+ _ = T.M
+}
+
+func F2() {
+ _F1(&S1{})
+ _F1(S2{})
+ _F1(&S2{})
+}
+
+func main() {
+ F()
+ F2()
+}