This is a clean port of CL 362994 from types2 to go/types.
Change-Id: I51b38c35ec3306274ef0355516e2d5557e7d8b46
Reviewed-on: https://go-review.googlesource.com/c/go/+/363988
Trust: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
// of S and the respective parameter passing rules apply."
S := x.typ
var T Type
- if s, _ := structure(S).(*Slice); s != nil {
+ if s, _ := structuralType(S).(*Slice); s != nil {
T = s.elem
} else {
check.invalidArg(x, _InvalidAppend, "%s is not a slice", x)
case _Copy:
// copy(x, y []T) int
- dst, _ := structure(x.typ).(*Slice)
+ dst, _ := structuralType(x.typ).(*Slice)
var y operand
arg(&y, 1)
if y.mode == invalid {
return
}
- src, _ := structureString(y.typ).(*Slice)
+ src, _ := structuralString(y.typ).(*Slice)
if dst == nil || src == nil {
check.invalidArg(x, _InvalidCopy, "copy expects slice arguments; found %s and %s", x, &y)
}
var min int // minimum number of arguments
- switch structure(T).(type) {
+ switch structuralType(T).(type) {
case *Slice:
min = 2
case *Map, *Chan:
return true
}
-// If typ is a type parameter, structure returns the single underlying
-// type of all types in the corresponding type constraint if it exists,
-// or nil otherwise. If typ is not a type parameter, structure returns
+// If typ is a type parameter, structuralType returns the single underlying
+// type of all types in the corresponding type constraint if it exists, or
+// nil otherwise. If typ is not a type parameter, structuralType returns
// the underlying type.
-func structure(typ Type) Type {
+func structuralType(typ Type) Type {
var su Type
if underIs(typ, func(u Type) bool {
if su != nil && !Identical(su, u) {
return nil
}
-// structureString is like structure but also considers []byte and
-// string as "identical". In this case, if successful, the result
+// structuralString is like structuralType but also considers []byte
+// and string as "identical". In this case, if successful, the result
// is always []byte.
-func structureString(typ Type) Type {
+func structuralString(typ Type) Type {
var su Type
if underIs(typ, func(u Type) bool {
if isString(u) {
cgocall := x.mode == cgofunc
// a type parameter may be "called" if all types have the same signature
- sig, _ := structure(x.typ).(*Signature)
+ sig, _ := structuralType(x.typ).(*Signature)
if sig == nil {
check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
x.mode = invalid
goto Error
}
- switch utyp := structure(base).(type) {
+ switch utyp := structuralType(base).(type) {
case *Struct:
// Prevent crash if the struct referred to is not yet set up.
// See analogous comment for *Array.
valid := false
length := int64(-1) // valid if >= 0
- switch u := structure(x.typ).(type) {
+ switch u := structuralType(x.typ).(type) {
case nil:
check.errorf(x, _NonSliceableOperand, "cannot slice %s: type set has no single underlying type", x)
x.mode = invalid
// If a constraint has a structural type, unify the corresponding type parameter with it.
for _, tpar := range tparams {
- sbound := structure(tpar)
+ sbound := structuralType(tpar)
if sbound != nil {
// If the structural type is the underlying type of a single
// defined type in the constraint, use that defined type instead.
// The allX predicates below report whether t is an X.
// If t is a type parameter the result is true if isX is true
// for all specified types of the type parameter's type set.
-// allX is an optimized version of isX(structure(t)) (which
+// allX is an optimized version of isX(structuralType(t)) (which
// is the same as underIs(t, isX)).
func allBoolean(typ Type) bool { return allBasic(typ, IsBoolean) }
// allBasic reports whether under(t) is a basic type with the specified info.
// If t is a type parameter, the result is true if isBasic(t, info) is true
// for all specific types of the type parameter's type set.
-// allBasic(t, info) is an optimized version of isBasic(structure(t), info).
+// allBasic(t, info) is an optimized version of isBasic(structuralType(t), info).
func allBasic(t Type, info BasicInfo) bool {
switch u := under(t).(type) {
case *Basic:
if x.mode != invalid {
// Ranging over a type parameter is permitted if it has a single underlying type.
var cause string
- u := structure(x.typ)
+ u := structuralType(x.typ)
switch t := u.(type) {
case nil:
cause = "type set has no single underlying type"