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:
Robert Griesemer 2022-02-22 16:53:17 -08:00
parent 5a9fc946b4
commit c15527f0b0
10 changed files with 32 additions and 116 deletions

View File

@ -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)
}

View File

@ -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()

View File

@ -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

View File

@ -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).

View File

@ -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) }

View File

@ -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)
}

View File

@ -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()

View File

@ -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

View File

@ -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).

View File

@ -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) }