mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
[dev.typeparams] cmd/compile: avoid adding incorrectly instantiated types to the dictionary
FUNCINST nodes aren't instantiated correctly. Skip those types when adding to the set of types considered for the dictionary. Those types include those which are uninstantiated(have tparams), and those with type parameters that aren't a parameter of the containing function (they are the type parameter of the function being called). Allow func types to be put in the dictionary. Change-Id: I26bab85d3eebc2f54d02b4bba5e31407faf7c5b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/336129 Reviewed-by: Dan Scales <danscales@google.com> Trust: Dan Scales <danscales@google.com> Trust: Keith Randall <khr@golang.org>
This commit is contained in:
parent
2fe4b14795
commit
4a97fe8c22
|
@ -1836,11 +1836,7 @@ 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 t.Kind() == types.TFUNC && n != nil &&
|
if !parameterizedBy(t, info.tparams) {
|
||||||
(n.Op() != ir.ONAME || n.Name().Class == ir.PFUNC) {
|
|
||||||
// For now, only record function types that are associate with a
|
|
||||||
// local/global variable (a name which is not a named global
|
|
||||||
// function).
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() {
|
if t.Kind() == types.TSTRUCT && t.IsFuncArgStruct() {
|
||||||
|
@ -1855,3 +1851,60 @@ func addType(info *gfInfo, n ir.Node, t *types.Type) {
|
||||||
}
|
}
|
||||||
info.derivedTypes = append(info.derivedTypes, t)
|
info.derivedTypes = append(info.derivedTypes, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parameterizedBy returns true if t is parameterized by (at most) params.
|
||||||
|
func parameterizedBy(t *types.Type, params []*types.Type) bool {
|
||||||
|
return parameterizedBy1(t, params, map[*types.Type]bool{})
|
||||||
|
}
|
||||||
|
func parameterizedBy1(t *types.Type, params []*types.Type, visited map[*types.Type]bool) bool {
|
||||||
|
if visited[t] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
visited[t] = true
|
||||||
|
switch t.Kind() {
|
||||||
|
case types.TTYPEPARAM:
|
||||||
|
for _, p := range params {
|
||||||
|
if p == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
|
||||||
|
case types.TARRAY, types.TPTR, types.TSLICE, types.TCHAN:
|
||||||
|
return parameterizedBy1(t.Elem(), params, visited)
|
||||||
|
|
||||||
|
case types.TMAP:
|
||||||
|
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)
|
||||||
|
|
||||||
|
case types.TSTRUCT:
|
||||||
|
for _, f := range t.Fields().Slice() {
|
||||||
|
if !parameterizedBy1(f.Type, params, visited) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
case types.TINTER:
|
||||||
|
for _, f := range t.Methods().Slice() {
|
||||||
|
if !parameterizedBy1(f.Type, params, visited) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
|
||||||
|
types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64,
|
||||||
|
types.TUINTPTR, types.TBOOL, types.TSTRING, types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
base.Fatalf("bad type kind %+v", t)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue