aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-07-28 13:50:09 -0700
committerRobert Griesemer <gri@golang.org>2021-07-29 19:45:50 +0000
commitc079b6baaa781e71a48661c05063d1d2754937f8 (patch)
tree55c52c63513c657ab611f0d3f9b2c7cbf4834cc4
parentff0c0dbca6a7a3a3d6528481829679be4c9d7e94 (diff)
downloadgo-c079b6baaa781e71a48661c05063d1d2754937f8.tar.gz
go-c079b6baaa781e71a48661c05063d1d2754937f8.zip
[dev.typeparams] cmd/compile/internal/types2: trigger verification while resolving instance
This is a straight port of CL 335978 with minor adjustements to white space and an error message. Change-Id: Icfcb562f75802a119ce5d02427bffecf7e279b2f Reviewed-on: https://go-review.googlesource.com/c/go/+/338097 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
-rw-r--r--src/cmd/compile/internal/types2/instance.go2
-rw-r--r--src/cmd/compile/internal/types2/instantiate.go59
-rw-r--r--src/cmd/compile/internal/types2/testdata/check/issues.go24
3 files changed, 37 insertions, 28 deletions
diff --git a/src/cmd/compile/internal/types2/instance.go b/src/cmd/compile/internal/types2/instance.go
index df0fc17ba7..711d7de53c 100644
--- a/src/cmd/compile/internal/types2/instance.go
+++ b/src/cmd/compile/internal/types2/instance.go
@@ -26,7 +26,7 @@ func (n *Named) expand() {
// tparams. This is done implicitly by the call to n.TParams, but making it
// explicit is harmless: load is idempotent.
n.load()
- inst := n.check.instantiate(n.instance.pos, n.orig.underlying, n.TParams(), n.targs, n.instance.posList, n.instance.verify)
+ inst := n.check.instantiate(n.instance.pos, n.orig.underlying, n.TParams(), n.targs, n.instance.posList)
n.underlying = inst
n.fromRHS = inst
n.instance = nil
diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go
index 1294b08490..7a40cea889 100644
--- a/src/cmd/compile/internal/types2/instantiate.go
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -54,10 +54,15 @@ func (check *Checker) Instantiate(pos syntax.Pos, typ Type, targs []Type, posLis
// only types and functions can be generic
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
}
- return check.instantiate(pos, typ, tparams, targs, posList, verify)
+
+ inst := check.instantiate(pos, typ, tparams, targs, posList)
+ if verify && len(tparams) == len(targs) {
+ check.verify(pos, tparams, targs, posList)
+ }
+ return inst
}
-func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName, targs []Type, posList []syntax.Pos, verify bool) (res Type) {
+func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName, targs []Type, posList []syntax.Pos) (res Type) {
// the number of supplied types must match the number of type parameters
if len(targs) != len(tparams) {
// TODO(gri) provide better error message
@@ -67,9 +72,6 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName,
}
panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, len(targs), len(tparams)))
}
- 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))
@@ -93,24 +95,7 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, tparams []*TypeName,
return typ // nothing to do (minor optimization)
}
- smap := makeSubstMap(tparams, targs)
-
- // check bounds
- 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
- }
- }
- }
-
- return check.subst(pos, typ, smap)
+ return check.subst(pos, typ, makeSubstMap(tparams, targs))
}
// InstantiateLazy is like Instantiate, but avoids actually
@@ -120,10 +105,16 @@ func (check *Checker) InstantiateLazy(pos syntax.Pos, typ Type, targs []Type, po
// Don't use asNamed here: we don't want to expand the base during lazy
// instantiation.
base := typ.(*Named)
-
if base == nil {
panic(fmt.Sprintf("%v: cannot instantiate %v", pos, typ))
}
+
+ if verify && len(base.tparams) == len(targs) {
+ check.later(func() {
+ check.verify(pos, base.tparams, targs, posList)
+ })
+ }
+
h := instantiatedHash(base, targs)
if check != nil {
// typ may already have been instantiated with identical type arguments. In
@@ -148,6 +139,26 @@ func (check *Checker) InstantiateLazy(pos syntax.Pos, typ Type, targs []Type, po
return named
}
+func (check *Checker) verify(pos syntax.Pos, tparams []*TypeName, targs []Type, posList []syntax.Pos) {
+ if check == nil {
+ panic("cannot have nil Checker if verifying constraints")
+ }
+
+ smap := makeSubstMap(tparams, targs)
+ 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
+ }
+ }
+}
+
// 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.
diff --git a/src/cmd/compile/internal/types2/testdata/check/issues.go2 b/src/cmd/compile/internal/types2/testdata/check/issues.go2
index e29357de0b..1ede383ebe 100644
--- a/src/cmd/compile/internal/types2/testdata/check/issues.go2
+++ b/src/cmd/compile/internal/types2/testdata/check/issues.go2
@@ -74,10 +74,8 @@ func (u T2[U]) Add1() U {
return u.s + 1
}
-// TODO(rfindley): we should probably report an error here as well, not
-// just when the type is first instantiated.
func NewT2[U any]() T2[U /* ERROR U has no constraints */ ] {
- return T2[U]{}
+ return T2[U /* ERROR U has no constraints */ ]{}
}
func _() {