aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/type.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-05-25 17:49:32 -0700
committerRobert Griesemer <gri@golang.org>2021-06-02 20:31:01 +0000
commit589e32dbdf89484d620c635a966c736085cae5c4 (patch)
tree75e1633438a390fa4dab5a4f010e813441636d5c /src/cmd/compile/internal/types2/type.go
parent7b876def6c4936cfae774d3007f8265876a9fbf7 (diff)
downloadgo-589e32dbdf89484d620c635a966c736085cae5c4.tar.gz
go-589e32dbdf89484d620c635a966c736085cae5c4.zip
[dev.typeparams] cmd/compile/internal/types2: replace Sum type with Union type
- We still mostly ignore the tilde information. - More consistent naming: A Union term is the pair (type, tilde). Rename Union.terms to Union.types; the Union.types and Union.tilde slices make up the Union terms. - Replace Sum.is with Union.underIs: underIs iterates through all union terms and calls its argument function with the underlying type of the term (and thus can ignore the tilde information). This also eliminates the need to call under in the argument function. - Added Union.is for situations where we need to consider the tilde information for each Union term. Change-Id: I70fcf1813e072651dc0f61d52d5555642ee762fd Reviewed-on: https://go-review.googlesource.com/c/go/+/323274 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/type.go')
-rw-r--r--src/cmd/compile/internal/types2/type.go72
1 files changed, 15 insertions, 57 deletions
diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go
index 3b2a5960e8..aab75811b8 100644
--- a/src/cmd/compile/internal/types2/type.go
+++ b/src/cmd/compile/internal/types2/type.go
@@ -261,53 +261,6 @@ func (s *Signature) Results() *Tuple { return s.results }
// Variadic reports whether the signature s is variadic.
func (s *Signature) Variadic() bool { return s.variadic }
-// A Sum represents a set of possible types.
-// Sums are currently used to represent type lists of interfaces
-// and thus the underlying types of type parameters; they are not
-// first class types of Go.
-type Sum struct {
- types []Type // types are unique
-}
-
-// NewSum returns a new Sum type consisting of the provided
-// types if there are more than one. If there is exactly one
-// type, it returns that type. If the list of types is empty
-// the result is nil.
-func NewSum(types []Type) Type {
- if len(types) == 0 {
- return nil
- }
-
- // What should happen if types contains a sum type?
- // Do we flatten the types list? For now we check
- // and panic. This should not be possible for the
- // current use case of type lists.
- // TODO(gri) Come up with the rules for sum types.
- for _, t := range types {
- if _, ok := t.(*Sum); ok {
- panic("sum type contains sum type - unimplemented")
- }
- }
-
- if len(types) == 1 {
- return types[0]
- }
- return &Sum{types: types}
-}
-
-// is reports whether all types in t satisfy pred.
-func (s *Sum) is(pred func(Type) bool) bool {
- if s == nil {
- return false
- }
- for _, t := range s.types {
- if !pred(t) {
- return false
- }
- }
- return true
-}
-
// An Interface represents an interface type.
type Interface struct {
methods []*Func // ordered list of explicitly declared methods
@@ -325,8 +278,8 @@ func unpack(typ Type) []Type {
if typ == nil {
return nil
}
- if sum := asSum(typ); sum != nil {
- return sum.types
+ if u := asUnion(typ); u != nil {
+ return u.types
}
return []Type{typ}
}
@@ -716,9 +669,16 @@ func optype(typ Type) Type {
// for a type parameter list of the form:
// (type T interface { type T }).
// See also issue #39680.
- if u := t.Bound().allTypes; u != nil && u != typ {
- // u != typ and u is a type parameter => under(u) != typ, so this is ok
- return under(u)
+ if a := t.Bound().allTypes; a != nil {
+ // If we have a union with a single entry, ignore
+ // any tilde because under(~t) == under(t).
+ if u, _ := a.(*Union); u != nil && u.NumTerms() == 1 {
+ a = u.types[0]
+ }
+ if a != typ {
+ // a != typ and a is a type parameter => under(a) != typ, so this is ok
+ return under(a)
+ }
}
return theTop
}
@@ -800,7 +760,6 @@ func (t *Struct) Underlying() Type { return t }
func (t *Pointer) Underlying() Type { return t }
func (t *Tuple) Underlying() Type { return t }
func (t *Signature) Underlying() Type { return t }
-func (t *Sum) Underlying() Type { return t }
func (t *Interface) Underlying() Type { return t }
func (t *Map) Underlying() Type { return t }
func (t *Chan) Underlying() Type { return t }
@@ -818,7 +777,6 @@ func (t *Struct) String() string { return TypeString(t, nil) }
func (t *Pointer) String() string { return TypeString(t, nil) }
func (t *Tuple) String() string { return TypeString(t, nil) }
func (t *Signature) String() string { return TypeString(t, nil) }
-func (t *Sum) String() string { return TypeString(t, nil) }
func (t *Interface) String() string { return TypeString(t, nil) }
func (t *Map) String() string { return TypeString(t, nil) }
func (t *Chan) String() string { return TypeString(t, nil) }
@@ -833,7 +791,7 @@ func (t *top) String() string { return TypeString(t, nil) }
// under must only be called when a type is known
// to be fully set up.
func under(t Type) Type {
- // TODO(gri) is this correct for *Sum?
+ // TODO(gri) is this correct for *Union?
if n := asNamed(t); n != nil {
return n.under()
}
@@ -880,8 +838,8 @@ func asSignature(t Type) *Signature {
return op
}
-func asSum(t Type) *Sum {
- op, _ := optype(t).(*Sum)
+func asUnion(t Type) *Union {
+ op, _ := optype(t).(*Union)
return op
}