diff options
author | Robert Griesemer <gri@golang.org> | 2021-06-17 17:49:15 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-06-30 18:58:34 +0000 |
commit | 4b5fdb0b7a362cb6fa6ad551757104e490483121 (patch) | |
tree | a2d35fe408f7c5fb8d2fd8836481a23d023844c3 /src/cmd/compile/internal/types2/subst.go | |
parent | f503740ccf6302ed13c7722ea50c6880a17703fb (diff) | |
download | go-4b5fdb0b7a362cb6fa6ad551757104e490483121.tar.gz go-4b5fdb0b7a362cb6fa6ad551757104e490483121.zip |
[dev.typeparams] cmd/compile/internal/types2: introduce type set abstraction for interfaces
With this change, interfaces are "completed" on-demand, when needed,
and the respective information (set of all methods, type constraints)
is recorded in a new typeSet data structure.
As a consequence, interfaces don't need to be explicitly completed
anymore and (internal) uses of interfaces have become much simpler.
This change also introduces a new field Interface.complete to indicate
that all methods and embedded elements have been set up. This prevent
the computation and recording (!) of a partial type set for erroneous
programs (if we compute the partial type set and store it, subsequent
type set accesses use the wrong type set which may lead to follow-on
errors).
Change-Id: I1ffc907f7d0fb93b3e987fe5ff9c6fa5cae00d7f
Reviewed-on: https://go-review.googlesource.com/c/go/+/329309
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/subst.go')
-rw-r--r-- | src/cmd/compile/internal/types2/subst.go | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go index 3ef65c2e92..38bd07b8a2 100644 --- a/src/cmd/compile/internal/types2/subst.go +++ b/src/cmd/compile/internal/types2/subst.go @@ -136,6 +136,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis // satisfies reports whether the type argument targ satisfies the constraint of type parameter // parameter tpar (after any of its type parameters have been substituted through smap). // A suitable error is reported if the result is false. +// TODO(gri) This should be a method of interfaces or type sets. func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap *substMap) bool { iface := tpar.Bound() if iface.Empty() { @@ -150,8 +151,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap // targ must implement iface (methods) // - check only if we have methods - check.completeInterface(nopos, iface) - if len(iface.allMethods) > 0 { + if iface.NumMethods() > 0 { // If the type argument is a pointer to a type parameter, the type argument's // method set is empty. // TODO(gri) is this what we want? (spec question) @@ -182,7 +182,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap } // targ's underlying type must also be one of the interface types listed, if any - if iface.allTypes == nil { + if iface.typeSet().types == nil { return true // nothing to do } @@ -190,7 +190,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap // list of iface types (i.e., the targ type list must be a non-empty subset of the iface types). if targ := asTypeParam(targ); targ != nil { targBound := targ.Bound() - if targBound.allTypes == nil { + if targBound.typeSet().types == nil { check.softErrorf(pos, "%s does not satisfy %s (%s has no type constraints)", targ, tpar.bound, targ) return false } @@ -198,7 +198,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap // 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, typ, iface.allTypes) + check.softErrorf(pos, "%s does not satisfy %s (%s type constraint %s not found in %s)", targ, tpar.bound, targ, typ, iface.typeSet().types) return false } return true @@ -207,7 +207,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap // Otherwise, targ's type or underlying type must also be one of the interface types listed, if any. if !iface.isSatisfiedBy(targ) { - check.softErrorf(pos, "%s does not satisfy %s (%s not found in %s)", targ, tpar.bound, targ, iface.allTypes) + check.softErrorf(pos, "%s does not satisfy %s (%s not found in %s)", targ, tpar.bound, targ, iface.typeSet().types) return false } @@ -312,12 +312,11 @@ func (subst *subster) typ(typ Type) Type { methods, mcopied := subst.funcList(t.methods) embeddeds, ecopied := subst.typeList(t.embeddeds) if mcopied || ecopied { - iface := &Interface{methods: methods, embeddeds: embeddeds} + iface := &Interface{methods: methods, embeddeds: embeddeds, complete: t.complete} if subst.check == nil { panic("internal error: cannot instantiate interfaces yet") } subst.check.posMap[iface] = subst.check.posMap[t] // satisfy completeInterface requirement - subst.check.completeInterface(nopos, iface) return iface } |