diff options
| author | Dan Scales <danscales@google.com> | 2021-07-09 16:27:22 -0700 |
|---|---|---|
| committer | Dan Scales <danscales@google.com> | 2021-07-19 05:02:24 +0000 |
| commit | 9b85985d36a7cc7117e9c14bc1d2632844a5a818 (patch) | |
| tree | 7c7bb5da384fca45fbc1b2d9f37bc660629725b5 /src/cmd/compile/internal/noder | |
| parent | df778e6fd9a8ad4f50f734f08b8d07d4ce597c02 (diff) | |
| download | go-9b85985d36a7cc7117e9c14bc1d2632844a5a818.tar.xz | |
[dev.typeparams] Separate out gcshape types that are instantiated types
Distinguish the gcshape of all top-level instantiated type from normal
concrete types, even if they have the exact same underlying "shape",
because in a function instantiation, any method call on this type arg
will be a generic method call (requiring a dictionary), rather than a
direct method call on the underlying type (no dictionary).
So, we add the instshape prefix to the gcshape name for instantiated
types, and we make it a defined type with that name.
Change-Id: I33056269d24f3451a2632a5ce6a481108f533c9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/335169
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/stencil.go | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index f4935fe22a..7eac8573c9 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -729,11 +729,37 @@ func gcshapeType(t *types.Type) (*types.Type, string) { // Call CallSize so type sizes and field offsets are available. types.CalcSize(t) + + instType := t.Sym() != nil && t.IsFullyInstantiated() + if instType { + // We distinguish the gcshape of all top-level instantiated type from + // normal concrete types, even if they have the exact same underlying + // "shape", because in a function instantiation, any method call on + // this type arg will be a generic method call (requiring a + // dictionary), rather than a direct method call on the underlying + // type (no dictionary). So, we add the instshape prefix to the + // normal gcshape name, and will make it a defined type with that + // name below. + buf.WriteString("instshape-") + } fl = accumGcshape(fl, buf, t, nil) + // TODO: Should gcshapes be in a global package, so we don't have to // duplicate in each package? Or at least in the specified source package // of a function/method instantiation? gcshape := types.NewStruct(types.LocalPkg, fl) + gcname := buf.String() + if instType { + // Lookup or create type with name 'gcname' (with instshape prefix). + newsym := t.Sym().Pkg.Lookup(gcname) + if newsym.Def != nil { + gcshape = newsym.Def.Type() + } else { + newt := typecheck.NewIncompleteNamedType(t.Pos(), newsym) + newt.SetUnderlying(gcshape.Underlying()) + gcshape = newt + } + } assert(gcshape.Size() == t.Size()) return gcshape, buf.String() } @@ -764,7 +790,7 @@ func (g *irgen) getInstantiation(nameNode *ir.Name, targs []*types.Type, isMeth // Testing out gcshapeType() and gcshapeName() for i, t := range targs { gct, gcs := gcshapeType(t) - fmt.Printf("targ %d: %v %v\n", i, gct, gcs) + fmt.Printf("targ %d: %v %v %v\n", i, gcs, gct, gct.Underlying()) } } // If instantiation doesn't exist yet, create it and add |
