// the Fields to represent the receiver's method set.
if recv := fn.Type().Recv(); recv != nil {
typ := types.ReceiverBaseType(recv.Type)
- if typ.OrigSym() != nil {
+ if orig := typ.OrigType(); orig != nil {
// For a generic method, we mark the methods on the
// base generic type, since those are the methods
// that will be stenciled.
- typ = typ.OrigSym().Def.Type()
+ typ = orig
}
meth := typecheck.Lookdot1(fn, typecheck.Lookup(decl.Name.Value), typ, typ.Methods(), 0)
meth.SetNointerface(true)
targs := deref(meth.Type().Recv().Type).RParams()
t := meth.X.Type()
- baseSym := deref(t).OrigSym()
- baseType := baseSym.Def.(*ir.Name).Type()
+ baseType := deref(t).OrigType()
var gf *ir.Name
for _, m := range baseType.Methods().Slice() {
if meth.Sel == m.Sym {
// actually generic, so no need to build a closure.
return x
}
- baseType := recv.OrigSym().Def.Type()
+ baseType := recv.OrigType()
var gf *ir.Name
for _, m := range baseType.Methods().Slice() {
if se.Sel == m.Sym {
typecheck.NeedRuntimeType(typ)
// Lookup the method on the base generic type, since methods may
// not be set on imported instantiated types.
- baseSym := typ.OrigSym()
- baseType := baseSym.Def.(*ir.Name).Type()
+ baseType := typ.OrigType()
for j, _ := range typ.Methods().Slice() {
if baseType.Methods().Slice()[j].Nointerface() {
typ.Methods().Slice()[j].SetNointerface(true)
if recvType.IsFullyInstantiated() {
// Get the type of the base generic type, so we get
// its original typeparams.
- recvType = recvType.OrigSym().Def.(*ir.Name).Type()
+ recvType = recvType.OrigType()
}
tparams = recvType.RParams()
} else {
// instantiated type, so we need a
// sub-dictionary.
targs := recvType.RParams()
- genRecvType := recvType.OrigSym().Def.Type()
+ genRecvType := recvType.OrigType()
nameNode = typecheck.Lookdot1(call.X, se.Sel, genRecvType, genRecvType.Methods(), 1).Nname.(*ir.Name)
sym = g.getDictionarySym(nameNode, targs, true)
} else {
// also give the receiver type. For method expressions with embedded types, we
// need to look at the type of the selection to get the final receiver type.
recvType := deref(se.Selection.Type.Recv().Type)
- genRecvType := recvType.OrigSym().Def.Type()
+ genRecvType := recvType.OrigType()
nameNode := typecheck.Lookdot1(se, se.Sel, genRecvType, genRecvType.Methods(), 1).Nname.(*ir.Name)
subtargs := recvType.RParams()
s2targs := make([]*types.Type, len(subtargs))
//fmt.Printf("Saw new type %v %v\n", instName, ntyp.HasTParam())
// Save the symbol for the base generic type.
- ntyp.SetOrigSym(g.pkg(typ.Obj().Pkg()).Lookup(typ.Obj().Name()))
+ ntyp.SetOrigType(base.Type())
ntyp.SetUnderlying(g.typ1(typ.Underlying()))
if typ.NumMethods() != 0 {
// Save a delayed call to g.fillinMethods() (once
// Target method uses shaped names.
targs2 := make([]*types.Type, len(targs))
- origRParams := deref(orig).OrigSym().Def.(*ir.Name).Type().RParams()
+ origRParams := deref(orig).OrigType().RParams()
for i, t := range targs {
targs2[i] = typecheck.Shapify(t, i, origRParams[i])
}
// inline bodies may be needed. For instantiated generic types, it visits the base
// generic type, which has the relevant methods.
func (p *crawler) markType(t *types.Type) {
- if t.OrigSym() != nil {
+ if orig := t.OrigType(); orig != nil {
// Convert to the base generic type.
- t = t.OrigSym().Def.Type()
+ t = orig
}
if p.marked[t] {
return
t = t.Elem()
}
- if t.OrigSym() != nil {
+ if orig := t.OrigType(); orig != nil {
// Convert to the base generic type.
- t = t.OrigSym().Def.Type()
+ t = orig
}
if p.embedded[t] {
if t.IsPtr() {
t = t.Elem()
}
- if t.OrigSym() != nil {
+ if orig := t.OrigType(); orig != nil {
// Convert to the base generic type.
- t = t.OrigSym().Def.Type()
+ t = orig
}
if p.generic[t] {
return
// them available for import, and so will not need
// another round of method and dictionary
// instantiation after inlining.
- baseType := t.OrigSym().Def.(*ir.Name).Type()
+ baseType := t.OrigType()
shapes := make([]*types.Type, len(t.RParams()))
for i, t1 := range t.RParams() {
shapes[i] = Shapify(t1, i, baseType.RParams()[i])
func (w *exportWriter) doTyp(t *types.Type) {
s := t.Sym()
- if s != nil && t.OrigSym() != nil {
+ if s != nil && t.OrigType() != nil {
assert(base.Flag.G > 0)
// This is an instantiated type - could be a re-instantiation like
// Value[T2] or a full instantiation like Value[int].
// types or existing typeparams from the function/method header.
w.typeList(t.RParams())
// Export a reference to the base type.
- baseType := t.OrigSym().Def.(*ir.Name).Type()
+ baseType := t.OrigType()
w.typ(baseType)
return
}
// No need to calc sizes for re-instantiated generic types, and
// they are not necessarily resolved until the top-level type is
// defined (because of recursive types).
- if t.OrigSym() == nil || !t.HasTParam() {
+ if t.OrigType() == nil || !t.HasTParam() {
types.CheckSize(t)
}
p.typCache[off] = t
} else {
genType := types.ReceiverBaseType(n1.X.Type())
if genType.IsInstantiatedGeneric() {
- genType = genType.OrigSym().Def.Type()
+ genType = genType.OrigType()
}
m = Lookdot1(n1, sel, genType, genType.Methods(), 1)
}
t := NewIncompleteNamedType(baseType.Pos(), instSym)
t.SetRParams(targs)
- t.SetOrigSym(baseSym)
+ t.SetOrigType(baseType)
// baseType may still be TFORW or its methods may not be fully filled in
// (since we are in the middle of importing it). So, delay call to
for len(deferredInstStack) > 0 {
t := deferredInstStack[0]
deferredInstStack = deferredInstStack[1:]
- substInstType(t, t.OrigSym().Def.(*ir.Name).Type(), t.RParams())
+ substInstType(t, t.OrigType(), t.RParams())
}
}
deferInst--
// instantiations of mutually recursive types.
func doInst(t *types.Type) *types.Type {
assert(t.Kind() == types.TFORW)
- return Instantiate(t.Pos(), t.OrigSym().Def.(*ir.Name).Type(), t.RParams())
+ return Instantiate(t.Pos(), t.OrigType(), t.RParams())
}
// substInstType completes the instantiation of a generic type by doing a
forw = NewIncompleteNamedType(t.Pos(), newsym)
//println("Creating new type by sub", newsym.Name, forw.HasTParam())
forw.SetRParams(neededTargs)
- // Copy the OrigSym from the re-instantiated type (which is the sym of
+ // Copy the OrigType from the re-instantiated type (which is the sym of
// the base generic type).
- assert(t.OrigSym() != nil)
- forw.SetOrigSym(t.OrigSym())
+ assert(t.OrigType() != nil)
+ forw.SetOrigType(t.OrigType())
}
var newt *types.Type
// TODO(danscales): choose a better name.
rparams *[]*Type
- // For an instantiated generic type, the symbol for the base generic type.
+ // For an instantiated generic type, the base generic type.
// This backpointer is useful, because the base type is the type that has
// the method bodies.
- origSym *Sym
+ origType *Type
}
func (*Type) CanBeAnSSAAux() {}
func (t *Type) Sym() *Sym { return t.sym }
func (t *Type) SetSym(sym *Sym) { t.sym = sym }
-// OrigSym returns the name of the original generic type that t is an
+// OrigType returns the original generic type that t is an
// instantiation of, if any.
-func (t *Type) OrigSym() *Sym { return t.origSym }
-func (t *Type) SetOrigSym(sym *Sym) { t.origSym = sym }
+func (t *Type) OrigType() *Type { return t.origType }
+func (t *Type) SetOrigType(orig *Type) { t.origType = orig }
// Underlying returns the underlying type of type t.
func (t *Type) Underlying() *Type { return t.underlying }
--- /dev/null
+// compile -G=3
+
+// Copyright 2022 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 p
+
+type empty[T any] struct{}
+
+func (this *empty[T]) Next() (empty T, _ error) {
+ return empty, nil
+}
+
+var _ = &empty[string]{}