diff options
author | Robert Griesemer <gri@golang.org> | 2021-07-09 13:02:24 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-07-13 04:40:11 +0000 |
commit | 22e926546732e4ea1fb20551be4b91f51f3b6e65 (patch) | |
tree | d2f775b15c81044b86dda4a0cc119255daefecd3 /src/cmd/compile/internal/types2/subst.go | |
parent | 1c783dc1480e8dec8bd4e76b744238607ea527f0 (diff) | |
download | go-22e926546732e4ea1fb20551be4b91f51f3b6e65.tar.gz go-22e926546732e4ea1fb20551be4b91f51f3b6e65.zip |
[dev.typeparams] cmd/compile/internal/types2: replace types2.Instantiate with Checker.Instantiate
Allow Checker.Instantiate to work with a nil *Checker receiver
(for now). This opens the door to passing in a *Checker at all
times.
Also, added a verify flag to Instantiate, InstantiateLazy, and
instance, to be able to control if constraint satisfaction should
be checked or not.
Removed types2.Instantiate.
For #47103.
Change-Id: Ie00ce41b3e50a0fc4341e013922e5f874276d282
Reviewed-on: https://go-review.googlesource.com/c/go/+/333569
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/subst.go')
-rw-r--r-- | src/cmd/compile/internal/types2/subst.go | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go index 6e4e778b20..32cf527372 100644 --- a/src/cmd/compile/internal/types2/subst.go +++ b/src/cmd/compile/internal/types2/subst.go @@ -53,8 +53,24 @@ func (m *substMap) lookup(tpar *TypeParam) Type { return tpar } -func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslist []syntax.Pos) (res Type) { - if check.conf.Trace { +// Instantiate instantiates the type typ with the given type arguments +// targs. To check type constraint satisfaction, verify must be set. +// pos and posList correspond to the instantiation and type argument +// positions respectively; posList may be nil or shorter than the number +// of type arguments provided. +// typ must be a *Named or a *Signature type, and its number of type +// parameters must match the number of provided type arguments. +// The receiver (check) may be nil if and only if verify is not set. +// The result is a new, instantiated (not generic) type of the same kind +// (either a *Named or a *Signature). +// Any methods attached to a *Named are simply copied; they are not +// instantiated. +func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posList []syntax.Pos, verify bool) (res Type) { + if verify && check == nil { + panic("cannot have nil receiver if verify is set") + } + + if check != nil && check.conf.Trace { check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs)) check.indent++ defer func() { @@ -70,7 +86,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis }() } - assert(len(poslist) <= len(targs)) + assert(len(posList) <= len(targs)) // TODO(gri) What is better here: work with TypeParams, or work with TypeNames? var tparams []*TypeName @@ -97,18 +113,19 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis // anymore; we need to set tparams to nil. res.(*Signature).tparams = nil }() - default: - check.dump("%v: cannot instantiate %v", pos, typ) - unreachable() // only defined types and (defined) functions can be generic - + // only types and functions can be generic + panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ)) } // the number of supplied types must match the number of type parameters if len(targs) != len(tparams) { // TODO(gri) provide better error message - check.errorf(pos, "got %d arguments but %d type parameters", len(targs), len(tparams)) - return Typ[Invalid] + if check != nil { + check.errorf(pos, "got %d arguments but %d type parameters", len(targs), len(tparams)) + return Typ[Invalid] + } + panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, len(targs), len(tparams))) } if len(tparams) == 0 { @@ -118,15 +135,17 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis smap := makeSubstMap(tparams, targs) // check bounds - for i, tname := range tparams { - // best position for error reporting - pos := pos - if i < len(poslist) { - pos = poslist[i] - } - // stop checking bounds after the first failure - if !check.satisfies(pos, targs[i], tname.typ.(*TypeParam), smap) { - break + if verify { + for i, tname := range tparams { + // best position for error reporting + pos := pos + if i < len(posList) { + pos = posList[i] + } + // stop checking bounds after the first failure + if !check.satisfies(pos, targs[i], tname.typ.(*TypeParam), smap) { + break + } } } |