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 token.Pos, typ Type, tparams []*TypeName, targs []Type, posList []token.Pos, verify bool) (res Type) {
+func (check *Checker) instantiate(pos token.Pos, typ Type, tparams []*TypeName, targs []Type, posList []token.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
}
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 && trace {
check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs))
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)
}
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 {
if named := check.typMap[h]; named != nil {
return named
}
+func (check *Checker) verify(pos token.Pos, tparams []*TypeName, targs []Type, posList []token.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.