// This also preserves the grouped output of type parameter lists
// when printing type strings.
if i == 0 || f.Type != list[i-1].Type {
- bound = check.boundType(f.Type)
+ // The predeclared identifier "any" is visible only as a type bound in a type parameter list.
+ // If we allow "any" for general use, this if-statement can be removed (issue #33232).
+ if name, _ := unparen(f.Type).(*syntax.Name); name != nil && name.Value == "any" && check.lookup("any") == universeAny {
+ bound = universeAny.Type()
+ } else {
+ bound = check.typ(f.Type)
+ }
}
tparams[i].bound = bound
}
+
+ check.later(func() {
+ for i, tpar := range tparams {
+ u := under(tpar.bound)
+ if _, ok := u.(*Interface); !ok && u != Typ[Invalid] {
+ check.errorf(list[i].Type, "%s is not an interface", tpar.bound)
+ }
+ }
+ })
}
func (check *Checker) declareTypeParam(name *syntax.Name) *TypeParam {
return tpar
}
-// boundType type-checks the type expression e and returns its type, or Typ[Invalid].
-// The type must be an interface, including the predeclared type "any".
-func (check *Checker) boundType(e syntax.Expr) Type {
- // The predeclared identifier "any" is visible only as a type bound in a type parameter list.
- // If we allow "any" for general use, this if-statement can be removed (issue #33232).
- if name, _ := unparen(e).(*syntax.Name); name != nil && name.Value == "any" && check.lookup("any") == universeAny {
- return universeAny.Type()
- }
-
- bound := check.typ(e)
- check.later(func() {
- u := under(bound)
- if _, ok := u.(*Interface); !ok && u != Typ[Invalid] {
- check.errorf(e, "%s is not an interface", bound)
- }
- })
- return bound
-}
-
func (check *Checker) collectMethods(obj *TypeName) {
// get associated methods
// (Checker.collectObjects only collects methods with non-blank names;