Remove remaining underIs methods and call underIs function instead.
Change-Id: Ic98430d3a56b85f6f4b35c4508c4c67dafbfa3f2
Reviewed-on: https://go-review.googlesource.com/c/go/+/614240
Reviewed-by: Tim King <taking@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>
if !isTypeParam(x.typ) {
break
}
- if t.typeSet().underIs(func(t Type) bool {
- switch t := arrayPtrDeref(t).(type) {
+ if underIs(x.typ, func(u Type) bool {
+ switch t := arrayPtrDeref(u).(type) {
case *Basic:
if isString(t) && id == _Len {
return true
// If T's type set is empty, or if it doesn't
// have specific types, constant x cannot be
// converted.
- ok = Unalias(T).(*TypeParam).underIs(func(u Type) bool {
+ ok = underIs(T, func(u Type) bool {
// u is nil if there are no specific type terms
if u == nil {
cause = check.sprintf("%s does not contain specific types", T)
}
case *Interface:
if isTypeParam(target) {
- if !u.typeSet().underIs(func(u Type) bool {
+ if !underIs(target, func(u Type) bool {
if u == nil {
return false
}
var key, elem Type // key != nil: we must have all maps
mode := variable // non-maps result mode
// TODO(gri) factor out closure and use it for non-typeparam cases as well
- if typ.typeSet().underIs(func(u Type) bool {
+ if underIs(x.typ, func(u Type) bool {
l := int64(-1) // valid if >= 0
var k, e Type // k is only set for maps
switch t := u.(type) {
case *Slice, *Pointer, *Signature, *Map, *Chan:
return true
case *Interface:
- return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool {
+ return !isTypeParam(t) || underIs(t, func(u Type) bool {
return u != nil && hasNil(u)
})
}
return t.iface().typeSet().is(f)
}
-// underIs calls f with the underlying types of the specific type terms
-// of t's constraint and reports whether all calls to f returned true.
-// If there are no specific terms, underIs returns the result of f(nil).
-func (t *TypeParam) underIs(f func(Type) bool) bool {
- return t.iface().typeSet().underIs(f)
-}
-
// typeset is an iterator over the (type/underlying type) pairs of the
// specific type terms of t's constraint.
// If there are no specific terms, typeset calls yield with (nil, nil).
return true
}
-// underIs calls f with the underlying types of the specific type terms
-// of s and reports whether all calls to f returned true. If there are
-// no specific terms, underIs returns the result of f(nil).
-func (s *_TypeSet) underIs(f func(Type) bool) bool {
- if !s.hasTerms() {
- return f(nil)
- }
- for _, t := range s.terms {
- assert(t.typ != nil)
- // Unalias(x) == under(x) for ~x terms
- u := Unalias(t.typ)
- if !t.tilde {
- u = under(u)
- }
- if debug {
- assert(Identical(u, under(u)))
- }
- if !f(u) {
- return false
- }
- }
- return true
-}
-
// topTypeSet may be used as type set for the empty interface.
var topTypeSet = _TypeSet{terms: allTermlist}
// If typ is a type parameter, underIs returns the result of typ.underIs(f).
// Otherwise, underIs returns the result of f(under(typ)).
func underIs(typ Type, f func(Type) bool) bool {
- typ = Unalias(typ)
- if tpar, _ := typ.(*TypeParam); tpar != nil {
- return tpar.underIs(f)
- }
- return f(under(typ))
+ var ok bool
+ typeset(typ, func(_, u Type) bool {
+ ok = f(u)
+ return ok
+ })
+ return ok
}
// typeset is an iterator over the (type/underlying type) pairs of the
// identical element types), the single underlying type is the restricted
// channel type if the restrictions are always the same, or nil otherwise.
func coreType(t Type) Type {
- t = Unalias(t)
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t)
- }
-
var su Type
- if tpar.underIs(func(u Type) bool {
+ typeset(t, func(_, u Type) bool {
if u == nil {
return false
}
if su != nil {
u = match(su, u)
if u == nil {
+ su = nil
return false
}
}
// su == nil || match(su, u) != nil
su = u
return true
- }) {
- return su
- }
- return nil
+ })
+ return su
}
// coreString is like coreType but also considers []byte
// and strings as identical. In this case, if successful and we saw
// a string, the result is of type (possibly untyped) string.
func coreString(t Type) Type {
- t = Unalias(t)
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t) // string or untyped string
+ // This explicit case is needed because otherwise the
+ // result would be string if t is an untyped string.
+ if !isTypeParam(t) {
+ return under(t) // untyped string remains untyped
}
var su Type
hasString := false
- if tpar.underIs(func(u Type) bool {
+ typeset(t, func(_, u Type) bool {
if u == nil {
return false
}
if su != nil {
u = match(su, u)
if u == nil {
+ su = nil
+ hasString = false
return false
}
}
// su == nil || match(su, u) != nil
su = u
return true
- }) {
- if hasString {
- return Typ[String]
- }
- return su
+ })
+ if hasString {
+ return Typ[String]
}
- return nil
+ return su
}
// If x and y are identical, match returns x.
if !isTypeParam(x.typ) {
break
}
- if t.typeSet().underIs(func(t Type) bool {
- switch t := arrayPtrDeref(t).(type) {
+ if underIs(x.typ, func(u Type) bool {
+ switch t := arrayPtrDeref(u).(type) {
case *Basic:
if isString(t) && id == _Len {
return true
// If T's type set is empty, or if it doesn't
// have specific types, constant x cannot be
// converted.
- ok = Unalias(T).(*TypeParam).underIs(func(u Type) bool {
+ ok = underIs(T, func(u Type) bool {
// u is nil if there are no specific type terms
if u == nil {
cause = check.sprintf("%s does not contain specific types", T)
}
case *Interface:
if isTypeParam(target) {
- if !u.typeSet().underIs(func(u Type) bool {
+ if !underIs(target, func(u Type) bool {
if u == nil {
return false
}
var key, elem Type // key != nil: we must have all maps
mode := variable // non-maps result mode
// TODO(gri) factor out closure and use it for non-typeparam cases as well
- if typ.typeSet().underIs(func(u Type) bool {
+ if underIs(x.typ, func(u Type) bool {
l := int64(-1) // valid if >= 0
var k, e Type // k is only set for maps
switch t := u.(type) {
case *Slice, *Pointer, *Signature, *Map, *Chan:
return true
case *Interface:
- return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool {
+ return !isTypeParam(t) || underIs(t, func(u Type) bool {
return u != nil && hasNil(u)
})
}
return t.iface().typeSet().is(f)
}
-// underIs calls f with the underlying types of the specific type terms
-// of t's constraint and reports whether all calls to f returned true.
-// If there are no specific terms, underIs returns the result of f(nil).
-func (t *TypeParam) underIs(f func(Type) bool) bool {
- return t.iface().typeSet().underIs(f)
-}
-
// typeset is an iterator over the (type/underlying type) pairs of the
// specific type terms of t's constraint.
// If there are no specific terms, typeset calls yield with (nil, nil).
return true
}
-// underIs calls f with the underlying types of the specific type terms
-// of s and reports whether all calls to f returned true. If there are
-// no specific terms, underIs returns the result of f(nil).
-func (s *_TypeSet) underIs(f func(Type) bool) bool {
- if !s.hasTerms() {
- return f(nil)
- }
- for _, t := range s.terms {
- assert(t.typ != nil)
- // Unalias(x) == under(x) for ~x terms
- u := Unalias(t.typ)
- if !t.tilde {
- u = under(u)
- }
- if debug {
- assert(Identical(u, under(u)))
- }
- if !f(u) {
- return false
- }
- }
- return true
-}
-
// topTypeSet may be used as type set for the empty interface.
var topTypeSet = _TypeSet{terms: allTermlist}
// If typ is a type parameter, underIs returns the result of typ.underIs(f).
// Otherwise, underIs returns the result of f(under(typ)).
func underIs(typ Type, f func(Type) bool) bool {
- typ = Unalias(typ)
- if tpar, _ := typ.(*TypeParam); tpar != nil {
- return tpar.underIs(f)
- }
- return f(under(typ))
+ var ok bool
+ typeset(typ, func(_, u Type) bool {
+ ok = f(u)
+ return ok
+ })
+ return ok
}
// typeset is an iterator over the (type/underlying type) pairs of the
// identical element types), the single underlying type is the restricted
// channel type if the restrictions are always the same, or nil otherwise.
func coreType(t Type) Type {
- t = Unalias(t)
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t)
- }
-
var su Type
- if tpar.underIs(func(u Type) bool {
+ typeset(t, func(_, u Type) bool {
if u == nil {
return false
}
if su != nil {
u = match(su, u)
if u == nil {
+ su = nil
return false
}
}
// su == nil || match(su, u) != nil
su = u
return true
- }) {
- return su
- }
- return nil
+ })
+ return su
}
// coreString is like coreType but also considers []byte
// and strings as identical. In this case, if successful and we saw
// a string, the result is of type (possibly untyped) string.
func coreString(t Type) Type {
- t = Unalias(t)
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t) // string or untyped string
+ // This explicit case is needed because otherwise the
+ // result would be string if t is an untyped string.
+ if !isTypeParam(t) {
+ return under(t) // untyped string remains untyped
}
var su Type
hasString := false
- if tpar.underIs(func(u Type) bool {
+ typeset(t, func(_, u Type) bool {
if u == nil {
return false
}
if su != nil {
u = match(su, u)
if u == nil {
+ su = nil
+ hasString = false
return false
}
}
// su == nil || match(su, u) != nil
su = u
return true
- }) {
- if hasString {
- return Typ[String]
- }
- return su
+ })
+ if hasString {
+ return Typ[String]
}
- return nil
+ return su
}
// If x and y are identical, match returns x.