mirror of https://github.com/golang/go.git
go/types, types2: implement adjCoreType using TypeParam.is
TypeParam.is also provides ~ (tilde) information which is needed to fix #51229. Delete all code related to singleType as it's not used anymore. Also, remove TypeParam.hasTerms as it was not used. For #51229. Change-Id: Ie49b19d157230beecb17a444d1f17cf24aa4f6ba Reviewed-on: https://go-review.googlesource.com/c/go/+/387774 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
5a9fc946b4
commit
c15527f0b0
|
|
@ -591,15 +591,24 @@ func (check *Checker) inferB(pos syntax.Pos, tparams []*TypeParam, targs []Type)
|
|||
return
|
||||
}
|
||||
|
||||
// adjCoreType returns the core type of tpar unless the
|
||||
// type parameter embeds a single, possibly named type,
|
||||
// in which case it returns that single type instead.
|
||||
// (The core type is always the underlying type of that
|
||||
// single type.)
|
||||
func adjCoreType(tpar *TypeParam) Type {
|
||||
// If the type parameter embeds a single, possibly named
|
||||
// type, use that one instead of the core type (which is
|
||||
// always the underlying type of that single type).
|
||||
if single := tpar.singleType(); single != nil {
|
||||
if debug {
|
||||
assert(under(single) == coreType(tpar))
|
||||
var single *term
|
||||
if tpar.is(func(t *term) bool {
|
||||
if single == nil && t != nil {
|
||||
single = t
|
||||
return true
|
||||
}
|
||||
return single
|
||||
return false // zero or more than one terms
|
||||
}) {
|
||||
if debug {
|
||||
assert(under(single.typ) == coreType(tpar))
|
||||
}
|
||||
return single.typ
|
||||
}
|
||||
return coreType(tpar)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,15 +92,6 @@ func (xl termlist) norm() termlist {
|
|||
return rl
|
||||
}
|
||||
|
||||
// If the type set represented by xl is specified by a single (non-𝓤) term,
|
||||
// singleType returns that type. Otherwise it returns nil.
|
||||
func (xl termlist) singleType() Type {
|
||||
if nl := xl.norm(); len(nl) == 1 {
|
||||
return nl[0].typ // if nl.isAll() then typ is nil, which is ok
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// union returns the union xl ∪ yl.
|
||||
func (xl termlist) union(yl termlist) termlist {
|
||||
return append(xl, yl...).norm()
|
||||
|
|
|
|||
|
|
@ -106,35 +106,6 @@ func TestTermlistNorm(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTermlistSingleType(t *testing.T) {
|
||||
// helper to deal with nil types
|
||||
tstring := func(typ Type) string {
|
||||
if typ == nil {
|
||||
return "nil"
|
||||
}
|
||||
return typ.String()
|
||||
}
|
||||
|
||||
for test, want := range map[string]string{
|
||||
"∅": "nil",
|
||||
"𝓤": "nil",
|
||||
"int": "int",
|
||||
"myInt": "myInt",
|
||||
"~int": "int",
|
||||
"~int ∪ string": "nil",
|
||||
"~int ∪ myInt": "int",
|
||||
"∅ ∪ int": "int",
|
||||
"∅ ∪ ~int": "int",
|
||||
"∅ ∪ ~int ∪ string": "nil",
|
||||
} {
|
||||
xl := maketl(test)
|
||||
got := tstring(xl.singleType())
|
||||
if got != want {
|
||||
t.Errorf("(%v).singleType() == %v; want %v", test, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTermlistUnion(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
xl, yl, want string
|
||||
|
|
|
|||
|
|
@ -138,16 +138,6 @@ func (t *TypeParam) iface() *Interface {
|
|||
return ityp
|
||||
}
|
||||
|
||||
// singleType returns the single type of the type parameter constraint; or nil.
|
||||
func (t *TypeParam) singleType() Type {
|
||||
return t.iface().typeSet().singleType()
|
||||
}
|
||||
|
||||
// hasTerms reports whether the type parameter constraint has specific type terms.
|
||||
func (t *TypeParam) hasTerms() bool {
|
||||
return t.iface().typeSet().hasTerms()
|
||||
}
|
||||
|
||||
// is calls f with the specific type terms of t's constraint and reports whether
|
||||
// all calls to f returned true. If there are no specific terms, is
|
||||
// returns the result of f(nil).
|
||||
|
|
|
|||
|
|
@ -103,9 +103,6 @@ func (s *_TypeSet) String() string {
|
|||
// hasTerms reports whether the type set has specific type terms.
|
||||
func (s *_TypeSet) hasTerms() bool { return !s.terms.isEmpty() && !s.terms.isAll() }
|
||||
|
||||
// singleType returns the single type in s if there is exactly one; otherwise the result is nil.
|
||||
func (s *_TypeSet) singleType() Type { return s.terms.singleType() }
|
||||
|
||||
// subsetOf reports whether s1 ⊆ s2.
|
||||
func (s1 *_TypeSet) subsetOf(s2 *_TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
|
||||
|
||||
|
|
|
|||
|
|
@ -590,15 +590,24 @@ func (check *Checker) inferB(posn positioner, tparams []*TypeParam, targs []Type
|
|||
return
|
||||
}
|
||||
|
||||
// adjCoreType returns the core type of tpar unless the
|
||||
// type parameter embeds a single, possibly named type,
|
||||
// in which case it returns that single type instead.
|
||||
// (The core type is always the underlying type of that
|
||||
// single type.)
|
||||
func adjCoreType(tpar *TypeParam) Type {
|
||||
// If the type parameter embeds a single, possibly named
|
||||
// type, use that one instead of the core type (which is
|
||||
// always the underlying type of that single type).
|
||||
if single := tpar.singleType(); single != nil {
|
||||
if debug {
|
||||
assert(under(single) == coreType(tpar))
|
||||
var single *term
|
||||
if tpar.is(func(t *term) bool {
|
||||
if single == nil && t != nil {
|
||||
single = t
|
||||
return true
|
||||
}
|
||||
return single
|
||||
return false // zero or more than one terms
|
||||
}) {
|
||||
if debug {
|
||||
assert(under(single.typ) == coreType(tpar))
|
||||
}
|
||||
return single.typ
|
||||
}
|
||||
return coreType(tpar)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,15 +92,6 @@ func (xl termlist) norm() termlist {
|
|||
return rl
|
||||
}
|
||||
|
||||
// If the type set represented by xl is specified by a single (non-𝓤) term,
|
||||
// singleType returns that type. Otherwise it returns nil.
|
||||
func (xl termlist) singleType() Type {
|
||||
if nl := xl.norm(); len(nl) == 1 {
|
||||
return nl[0].typ // if nl.isAll() then typ is nil, which is ok
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// union returns the union xl ∪ yl.
|
||||
func (xl termlist) union(yl termlist) termlist {
|
||||
return append(xl, yl...).norm()
|
||||
|
|
|
|||
|
|
@ -106,35 +106,6 @@ func TestTermlistNorm(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTermlistSingleType(t *testing.T) {
|
||||
// helper to deal with nil types
|
||||
tstring := func(typ Type) string {
|
||||
if typ == nil {
|
||||
return "nil"
|
||||
}
|
||||
return typ.String()
|
||||
}
|
||||
|
||||
for test, want := range map[string]string{
|
||||
"∅": "nil",
|
||||
"𝓤": "nil",
|
||||
"int": "int",
|
||||
"myInt": "myInt",
|
||||
"~int": "int",
|
||||
"~int ∪ string": "nil",
|
||||
"~int ∪ myInt": "int",
|
||||
"∅ ∪ int": "int",
|
||||
"∅ ∪ ~int": "int",
|
||||
"∅ ∪ ~int ∪ string": "nil",
|
||||
} {
|
||||
xl := maketl(test)
|
||||
got := tstring(xl.singleType())
|
||||
if got != want {
|
||||
t.Errorf("(%v).singleType() == %v; want %v", test, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTermlistUnion(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
xl, yl, want string
|
||||
|
|
|
|||
|
|
@ -140,16 +140,6 @@ func (t *TypeParam) iface() *Interface {
|
|||
return ityp
|
||||
}
|
||||
|
||||
// singleType returns the single type of the type parameter constraint; or nil.
|
||||
func (t *TypeParam) singleType() Type {
|
||||
return t.iface().typeSet().singleType()
|
||||
}
|
||||
|
||||
// hasTerms reports whether the type parameter constraint has specific type terms.
|
||||
func (t *TypeParam) hasTerms() bool {
|
||||
return t.iface().typeSet().hasTerms()
|
||||
}
|
||||
|
||||
// is calls f with the specific type terms of t's constraint and reports whether
|
||||
// all calls to f returned true. If there are no specific terms, is
|
||||
// returns the result of f(nil).
|
||||
|
|
|
|||
|
|
@ -101,9 +101,6 @@ func (s *_TypeSet) String() string {
|
|||
// hasTerms reports whether the type set has specific type terms.
|
||||
func (s *_TypeSet) hasTerms() bool { return !s.terms.isEmpty() && !s.terms.isAll() }
|
||||
|
||||
// singleType returns the single type in s if there is exactly one; otherwise the result is nil.
|
||||
func (s *_TypeSet) singleType() Type { return s.terms.singleType() }
|
||||
|
||||
// subsetOf reports whether s1 ⊆ s2.
|
||||
func (s1 *_TypeSet) subsetOf(s2 *_TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue