]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.18] cmd/compile: replace Type.OrigSym with Type.OrigType
authorMatthew Dempsky <mdempsky@google.com>
Mon, 21 Mar 2022 17:06:48 +0000 (10:06 -0700)
committerCherry Mui <cherryyz@google.com>
Mon, 4 Apr 2022 20:26:50 +0000 (20:26 +0000)
First law of cmd/compile frontend development: thou shalt not rely on
types.Sym.

This CL replaces Type.OrigSym with Type.OrigType, which semantically
matches what all of the uses within the frontend actually care about,
and avoids using types.Sym, which invariably leads to mistakes because
symbol scoping in the frontend doesn't work how anyone intuitively
expects it to.

Fixes #51855.

Change-Id: I4affe6ee0718103ce5006ab68aa7e1bb0cac6881
Reviewed-on: https://go-review.googlesource.com/c/go/+/394274
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit adae6ec542c3287ffe643093a0f61c9871f4e238)
Reviewed-on: https://go-review.googlesource.com/c/go/+/394296

src/cmd/compile/internal/noder/decl.go
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/noder/types.go
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/typecheck/crawler.go
src/cmd/compile/internal/typecheck/iexport.go
src/cmd/compile/internal/typecheck/iimport.go
src/cmd/compile/internal/typecheck/subr.go
src/cmd/compile/internal/types/type.go
test/typeparam/issue51765.go [new file with mode: 0644]

index a9522d09af52982218a0e1206e75885727cd1e28..f985648c667b75f6c69fca3e2feaf4d12cbd6691 100644 (file)
@@ -114,11 +114,11 @@ func (g *irgen) funcDecl(out *ir.Nodes, decl *syntax.FuncDecl) {
                // 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)
index c78a169d3106d6278c935ea3ea3814feb9d5c26d..4ba69469a63286b6c50d8e4bec10cf056cbaa988 100644 (file)
@@ -193,8 +193,7 @@ func (g *genInst) scanForGenCalls(decl ir.Node) {
                        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 {
@@ -348,7 +347,7 @@ func (g *genInst) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
                        // 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 {
@@ -543,8 +542,7 @@ func (g *genInst) instantiateMethods() {
                        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)
@@ -644,7 +642,7 @@ func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMe
                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 {
@@ -1628,7 +1626,7 @@ func (g *genInst) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool
                                        // 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 {
@@ -1707,7 +1705,7 @@ func (g *genInst) getSymForMethodCall(se *ir.SelectorExpr, subst *typecheck.Tsub
        // 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))
index e7ce4c1089ff2f96018f89c62beb656a7febd634..ff3a4d982d069217002d06b17c5cdb1715b64ede 100644 (file)
@@ -166,7 +166,7 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
                        //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
index a4ddb1a3128ee968c0dbb04c59926b6915af5b6a..822a1dacc354c63b8bbf5a4e174a6a4bc98476fd 100644 (file)
@@ -1921,7 +1921,7 @@ func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSy
 
                        // 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])
                        }
index 4394c6e698af1fbb23472665d306a5d79214ab25..40b518983a87054760473565e2a63ba1f16f0d3c 100644 (file)
@@ -66,9 +66,9 @@ func (p *crawler) markObject(n *ir.Name) {
 // 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
@@ -154,9 +154,9 @@ func (p *crawler) markEmbed(t *types.Type) {
                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] {
@@ -194,9 +194,9 @@ func (p *crawler) markGeneric(t *types.Type) {
        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
@@ -229,7 +229,7 @@ func (p *crawler) checkForFullyInst(t *types.Type) {
                // 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])
index b7a251c71ffec1d520857d3bca45d4007b087d1f..18b5fc7f80f862b7a5fbfaeae8b8d3979d92f1d2 100644 (file)
@@ -953,7 +953,7 @@ func (w *exportWriter) startType(k itag) {
 
 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].
@@ -970,7 +970,7 @@ func (w *exportWriter) doTyp(t *types.Type) {
                // 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
        }
index 28a50605aab444f8ef4c85eb3f155ac42a751271..654aff899dda1bb5e8a902e759af6982c2e06416 100644 (file)
@@ -761,7 +761,7 @@ func (p *iimporter) typAt(off uint64) *types.Type {
                // 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
@@ -1482,7 +1482,7 @@ func (r *importReader) node() ir.Node {
                                        } 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)
                                        }
@@ -1913,7 +1913,7 @@ func Instantiate(pos src.XPos, baseType *types.Type, targs []*types.Type) *types
 
        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
@@ -1938,7 +1938,7 @@ func resumeDoInst() {
                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--
@@ -1950,7 +1950,7 @@ func resumeDoInst() {
 // 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
index 0d43855c4422a662788d84307327da8a32628974..a41a3d62fbf696571407bdceb992bcf165851e8c 100644 (file)
@@ -1120,10 +1120,10 @@ func (ts *Tsubster) typ1(t *types.Type) *types.Type {
                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
index fe352e0b6e03ebb1d904b54414f498d0feeb8dbe..bfcb8d215e34a3e1bd84f288e59440109fb234cf 100644 (file)
@@ -202,10 +202,10 @@ type Type struct {
        // 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() {}
@@ -250,10 +250,10 @@ func (t *Type) Kind() Kind { return t.kind }
 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 }
diff --git a/test/typeparam/issue51765.go b/test/typeparam/issue51765.go
new file mode 100644 (file)
index 0000000..0f8de14
--- /dev/null
@@ -0,0 +1,15 @@
+// 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]{}