diff options
| author | Keith Randall <khr@golang.org> | 2021-07-21 19:17:20 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2021-07-22 18:09:49 +0000 |
| commit | 5cb84f0604797df436d8fde548d4f797b3a6c245 (patch) | |
| tree | 97668005f08609ed9984c1c264f6de2d43b69333 /src/cmd/compile/internal/noder | |
| parent | 73162a54c2885d32d40067d2e4fbe26bbe5c7d65 (diff) | |
| download | go-5cb84f0604797df436d8fde548d4f797b3a6c245.tar.xz | |
[dev.typeparams] cmd/compile: make sure types added to the dictionary are instantiated correctly
Make sure the instantiating types are the type parameters of the containing
function (or types derived from those).
The one exception is the argument of a OFUNCINST, whose type
parameters are those of the declaration site of the function or method
being instantiated. We skip those types.
Change-Id: I4b3ff22eb8a81a76476930cf8ed2a7dd6489d8b8
Reviewed-on: https://go-review.googlesource.com/c/go/+/336352
Trust: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/stencil.go | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index 71edc82dea..59f11bbe23 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -22,6 +22,9 @@ import ( "strconv" ) +// Enable extra consistency checks. +const doubleCheck = true + func assert(p bool) { base.Assert(p) } @@ -1820,7 +1823,6 @@ func (g *irgen) getGfInfo(gn *ir.Name) *gfInfo { ir.Visit(n1, visitFunc) } } - addType(&info, n, n.Type()) } @@ -1847,9 +1849,17 @@ func addType(info *gfInfo, n ir.Node, t *types.Type) { if t.IsTypeParam() && t.Underlying() == t { return } - if !parameterizedBy(t, info.tparams) { + if t.Kind() == types.TFUNC && n != nil && + (t.Recv() != nil || + n.Op() == ir.ONAME && n.Name().Class == ir.PFUNC) { + // Don't use the type of a named generic function or method, + // since that is parameterized by other typeparams. + // (They all come from arguments of a FUNCINST node.) return } + if doubleCheck && !parameterizedBy(t, info.tparams) { + base.Fatalf("adding type with invalid parameters %+v", t) + } if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() { // Multiple return values are not a relevant new type (?). return @@ -1872,13 +1882,25 @@ func parameterizedBy1(t *types.Type, params []*types.Type, visited map[*types.Ty return true } visited[t] = true + + if t.Sym() != nil && len(t.RParams()) > 0 { + // This defined type is instantiated. Check the instantiating types. + for _, r := range t.RParams() { + if !parameterizedBy1(r, params, visited) { + return false + } + } + return true + } switch t.Kind() { case types.TTYPEPARAM: + // Check if t is one of the allowed parameters in scope. for _, p := range params { if p == t { return true } } + // Couldn't find t in the list of allowed parameters. return false case types.TARRAY, types.TPTR, types.TSLICE, types.TCHAN: @@ -1888,10 +1910,7 @@ func parameterizedBy1(t *types.Type, params []*types.Type, visited map[*types.Ty return parameterizedBy1(t.Key(), params, visited) && parameterizedBy1(t.Elem(), params, visited) case types.TFUNC: - if t.NumTParams() > 0 { - return false - } - return parameterizedBy1(t.Recvs(), params, visited) && parameterizedBy1(t.Params(), params, visited) && parameterizedBy1(t.Results(), params, visited) + return parameterizedBy1(t.TParams(), params, visited) && parameterizedBy1(t.Recvs(), params, visited) && parameterizedBy1(t.Params(), params, visited) && parameterizedBy1(t.Results(), params, visited) case types.TSTRUCT: for _, f := range t.Fields().Slice() { |
