aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-07-09 16:27:22 -0700
committerDan Scales <danscales@google.com>2021-07-19 05:02:24 +0000
commit9b85985d36a7cc7117e9c14bc1d2632844a5a818 (patch)
tree7c7bb5da384fca45fbc1b2d9f37bc660629725b5 /src/cmd/compile/internal/noder
parentdf778e6fd9a8ad4f50f734f08b8d07d4ce597c02 (diff)
downloadgo-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.go28
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