mirror of
https://github.com/golang/go
synced 2024-11-26 11:58:07 -07:00
[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>
This commit is contained in:
parent
73162a54c2
commit
5cb84f0604
@ -22,6 +22,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Enable extra consistency checks.
|
||||||
|
const doubleCheck = true
|
||||||
|
|
||||||
func assert(p bool) {
|
func assert(p bool) {
|
||||||
base.Assert(p)
|
base.Assert(p)
|
||||||
}
|
}
|
||||||
@ -1820,7 +1823,6 @@ func (g *irgen) getGfInfo(gn *ir.Name) *gfInfo {
|
|||||||
ir.Visit(n1, visitFunc)
|
ir.Visit(n1, visitFunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addType(&info, n, n.Type())
|
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 {
|
if t.IsTypeParam() && t.Underlying() == t {
|
||||||
return
|
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
|
return
|
||||||
}
|
}
|
||||||
|
if doubleCheck && !parameterizedBy(t, info.tparams) {
|
||||||
|
base.Fatalf("adding type with invalid parameters %+v", t)
|
||||||
|
}
|
||||||
if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() {
|
if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() {
|
||||||
// Multiple return values are not a relevant new type (?).
|
// Multiple return values are not a relevant new type (?).
|
||||||
return
|
return
|
||||||
@ -1872,13 +1882,25 @@ func parameterizedBy1(t *types.Type, params []*types.Type, visited map[*types.Ty
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
visited[t] = 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() {
|
switch t.Kind() {
|
||||||
case types.TTYPEPARAM:
|
case types.TTYPEPARAM:
|
||||||
|
// Check if t is one of the allowed parameters in scope.
|
||||||
for _, p := range params {
|
for _, p := range params {
|
||||||
if p == t {
|
if p == t {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Couldn't find t in the list of allowed parameters.
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case types.TARRAY, types.TPTR, types.TSLICE, types.TCHAN:
|
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)
|
return parameterizedBy1(t.Key(), params, visited) && parameterizedBy1(t.Elem(), params, visited)
|
||||||
|
|
||||||
case types.TFUNC:
|
case types.TFUNC:
|
||||||
if t.NumTParams() > 0 {
|
return parameterizedBy1(t.TParams(), params, visited) && parameterizedBy1(t.Recvs(), params, visited) && parameterizedBy1(t.Params(), params, visited) && parameterizedBy1(t.Results(), params, visited)
|
||||||
return false
|
|
||||||
}
|
|
||||||
return parameterizedBy1(t.Recvs(), params, visited) && parameterizedBy1(t.Params(), params, visited) && parameterizedBy1(t.Results(), params, visited)
|
|
||||||
|
|
||||||
case types.TSTRUCT:
|
case types.TSTRUCT:
|
||||||
for _, f := range t.Fields().Slice() {
|
for _, f := range t.Fields().Slice() {
|
||||||
|
Loading…
Reference in New Issue
Block a user