aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-05-27 22:09:58 -0700
committerRobert Griesemer <gri@golang.org>2021-06-02 23:19:27 +0000
commit3c1d502a19dcdaaf0f7ddf58ccad9953fe5d92d1 (patch)
treea1dc7779abe65bab182f3d2464e0c1cb6b0e9d27 /src
parent848b58e47357965dc5a61fb0ae5535da717e2633 (diff)
downloadgo-3c1d502a19dcdaaf0f7ddf58ccad9953fe5d92d1.tar.gz
go-3c1d502a19dcdaaf0f7ddf58ccad9953fe5d92d1.zip
[dev.typeparams] cmd/compile/internal/types2: eliminate need for unpack and asUnion functions
Change-Id: Iaa75b091d52f44939330e5945305aea323ba58f4 Reviewed-on: https://go-review.googlesource.com/c/go/+/323355 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/builtins.go12
-rw-r--r--src/cmd/compile/internal/types2/infer.go15
-rw-r--r--src/cmd/compile/internal/types2/subst.go11
-rw-r--r--src/cmd/compile/internal/types2/type.go35
4 files changed, 29 insertions, 44 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 1779e32c5c..20c4ff62a1 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -749,14 +749,12 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
if tp := asTypeParam(x); tp != nil {
// Test if t satisfies the requirements for the argument
// type and collect possible result types at the same time.
- // TODO(gri) This needs to consider the ~ information if we
- // have a union type.
var rtypes []Type
- var tilde []bool
- if !tp.Bound().is(func(x Type) bool {
- if r := f(x); r != nil {
+ var tildes []bool
+ if !tp.Bound().is(func(typ Type, tilde bool) bool {
+ if r := f(typ); r != nil {
rtypes = append(rtypes, r)
- tilde = append(tilde, true) // for now - see TODO above
+ tildes = append(tildes, tilde)
return true
}
return false
@@ -772,7 +770,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
// construct a suitable new type parameter
tpar := NewTypeName(nopos, nil /* = Universe pkg */, "<type parameter>", nil)
ptyp := check.NewTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
- tsum := newUnion(rtypes, tilde)
+ tsum := newUnion(rtypes, tildes)
ptyp.bound = &Interface{allMethods: markComplete, allTypes: tsum}
return ptyp
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index 73ea8330d4..63cd63aacc 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -328,7 +328,7 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
return true
}
}
- return w.isParameterizedList(unpack(t.allTypes))
+ return w.isParameterized(t.allTypes)
}
return t.iterate(func(t *Interface) bool {
@@ -477,11 +477,14 @@ func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (ty
func (check *Checker) structuralType(constraint Type) Type {
if iface, _ := under(constraint).(*Interface); iface != nil {
check.completeInterface(nopos, iface)
- types := unpack(iface.allTypes)
- if len(types) == 1 {
- return types[0]
+ if u, _ := iface.allTypes.(*Union); u != nil {
+ if u.NumTerms() == 1 {
+ // TODO(gri) do we need to respect tilde?
+ return u.types[0]
+ }
+ return nil
}
- return nil
+ return iface.allTypes
}
- return constraint
+ return nil
}
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go
index 617a03ddbc..35ca197d64 100644
--- a/src/cmd/compile/internal/types2/subst.go
+++ b/src/cmd/compile/internal/types2/subst.go
@@ -194,14 +194,15 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap
check.softErrorf(pos, "%s does not satisfy %s (%s has no type constraints)", targ, tpar.bound, targ)
return false
}
- for _, t := range unpack(targBound.allTypes) {
- if !iface.isSatisfiedBy(t) {
+ return iface.is(func(typ Type, tilde bool) bool {
+ // TODO(gri) incorporate tilde information!
+ if !iface.isSatisfiedBy(typ) {
// TODO(gri) match this error message with the one below (or vice versa)
- check.softErrorf(pos, "%s does not satisfy %s (%s type constraint %s not found in %s)", targ, tpar.bound, targ, t, iface.allTypes)
+ check.softErrorf(pos, "%s does not satisfy %s (%s type constraint %s not found in %s)", targ, tpar.bound, targ, typ, iface.allTypes)
return false
}
- }
- return false
+ return true
+ })
}
// Otherwise, targ's type or underlying type must also be one of the interface types listed, if any.
diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go
index 990b9d374c..92f35f1279 100644
--- a/src/cmd/compile/internal/types2/type.go
+++ b/src/cmd/compile/internal/types2/type.go
@@ -272,29 +272,17 @@ type Interface struct {
obj Object // type declaration defining this interface; or nil (for better error messages)
}
-// unpack unpacks a type into a list of types.
-// TODO(gri) Try to eliminate the need for this function.
-func unpack(typ Type) []Type {
- if typ == nil {
- return nil
- }
- if u := asUnion(typ); u != nil {
- return u.types
- }
- return []Type{typ}
-}
-
-// is reports whether interface t represents types that all satisfy pred.
-func (t *Interface) is(pred func(Type) bool) bool {
- if t.allTypes == nil {
+// is reports whether interface t represents types that all satisfy f.
+func (t *Interface) is(f func(Type, bool) bool) bool {
+ switch t := t.allTypes.(type) {
+ case nil, *top:
+ // TODO(gri) should settle on top or nil to represent this case
return false // we must have at least one type! (was bug)
+ case *Union:
+ return t.is(func(typ Type, tilde bool) bool { return f(typ, tilde) })
+ default:
+ return f(t, false)
}
- for _, t := range unpack(t.allTypes) {
- if !pred(t) {
- return false
- }
- }
- return true
}
// emptyInterface represents the empty (completed) interface
@@ -828,11 +816,6 @@ func asSignature(t Type) *Signature {
return op
}
-func asUnion(t Type) *Union {
- op, _ := optype(t).(*Union)
- return op
-}
-
func asInterface(t Type) *Interface {
op, _ := optype(t).(*Interface)
return op