typeRecur
typeHasTParam // there is a typeparam somewhere in the type (generic function or type)
typeIsShape // represents a set of closely related types, for generics
+ typeHasShape // there is a shape somewhere in the type
)
func (t *Type) NotInHeap() bool { return t.flags&typeNotInHeap != 0 }
func (t *Type) Recur() bool { return t.flags&typeRecur != 0 }
func (t *Type) HasTParam() bool { return t.flags&typeHasTParam != 0 }
func (t *Type) IsShape() bool { return t.flags&typeIsShape != 0 }
+func (t *Type) HasShape() bool { return t.flags&typeHasShape != 0 }
func (t *Type) SetNotInHeap(b bool) { t.flags.set(typeNotInHeap, b) }
func (t *Type) SetBroke(b bool) { t.flags.set(typeBroke, b) }
func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) }
func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) }
-func (t *Type) SetIsShape(b bool) { t.flags.set(typeIsShape, b) }
// Generic types should never have alg functions.
func (t *Type) SetHasTParam(b bool) { t.flags.set(typeHasTParam, b); t.flags.set(typeNoalg, b) }
+// Should always do SetHasShape(true) when doing SeIsShape(true).
+func (t *Type) SetIsShape(b bool) { t.flags.set(typeIsShape, b) }
+func (t *Type) SetHasShape(b bool) { t.flags.set(typeHasShape, b) }
+
// Kind returns the kind of type t.
func (t *Type) Kind() Kind { return t.kind }
base.Fatalf("Setting nil or zero-length rparams")
}
t.rparams = &rparams
- if t.HasTParam() {
- return
- }
// HasTParam should be set if any rparam is or has a type param. This is
// to handle the case of a generic type which doesn't reference any of its
// type params (e.g. most commonly, an empty struct).
t.SetHasTParam(true)
break
}
+ if rparam.HasShape() {
+ t.SetHasShape(true)
+ break
+ }
}
}
if elem.HasTParam() {
t.SetHasTParam(true)
}
+ if elem.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if elem.HasTParam() {
t.SetHasTParam(true)
}
+ if elem.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if elem.HasTParam() {
t.SetHasTParam(true)
}
+ if elem.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if t1.HasTParam() || t2.HasTParam() {
t.SetHasTParam(true)
}
+ if t1.HasShape() || t2.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if k.HasTParam() || v.HasTParam() {
t.SetHasTParam(true)
}
+ if k.HasShape() || v.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
// when this entry was cached.
t.SetHasTParam(true)
}
+ if elem.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if elem.HasTParam() {
t.SetHasTParam(true)
}
+ if elem.HasShape() {
+ t.SetHasShape(true)
+ }
return t
}
if underlying.HasTParam() {
t.SetHasTParam(true)
}
+ if underlying.HasShape() {
+ t.SetHasShape(true)
+ }
// spec: "The declared type does not inherit any methods bound
// to the existing type, but the method set of an interface
return false
}
+func fieldsHasShape(fields []*Field) bool {
+ for _, f := range fields {
+ if f.Type != nil && f.Type.HasShape() {
+ return true
+ }
+ }
+ return false
+}
+
// NewBasic returns a new basic type of the given kind.
func NewBasic(kind Kind, obj Object) *Type {
t := New(kind)
t.SetHasTParam(true)
break
}
+ if f.Type != nil && f.Type.HasShape() {
+ t.SetHasShape(true)
+ break
+ }
}
if anyBroke(methods) {
t.SetBroke(true)
fieldsHasTParam(results) {
t.SetHasTParam(true)
}
+ if fieldsHasShape(recvs) || fieldsHasShape(params) || fieldsHasShape(results) {
+ t.SetHasShape(true)
+ }
return t
}
if fieldsHasTParam(fields) {
t.SetHasTParam(true)
}
+ if fieldsHasShape(fields) {
+ t.SetHasShape(true)
+ }
return t
}
)
var SimType [NTYPE]Kind
-
-// Reports whether t has a shape type anywere.
-func (t *Type) HasShape() bool {
- return t.HasShape1(map[*Type]bool{})
-}
-func (t *Type) HasShape1(visited map[*Type]bool) bool {
- if t.IsShape() {
- return true
- }
- if visited[t] {
- return false
- }
- visited[t] = true
- if t.Sym() != nil {
- for _, u := range t.RParams() {
- if u.HasShape1(visited) {
- return true
- }
- }
- }
- switch t.Kind() {
- case TPTR, TARRAY, TSLICE, TCHAN:
- return t.Elem().HasShape1(visited)
- case TMAP:
- return t.Elem().HasShape1(visited) || t.Key().HasShape1(visited)
- case TSTRUCT:
- for _, f := range t.FieldSlice() {
- if f.Type.HasShape1(visited) {
- return true
- }
- }
- case TFUNC:
- for _, a := range RecvsParamsResults {
- for _, f := range a(t).FieldSlice() {
- if f.Type.HasShape1(visited) {
- return true
- }
- }
- }
- case TINTER:
- for _, f := range t.Methods().Slice() {
- if f.Type.HasShape1(visited) {
- return true
- }
- }
- return false
- }
- return false
-}