Adjust types2 and go/types and some test cases.
Because `any` is not treated specially anymore in constraint
position we get additional errors in constraints if `any` is
used before Go1.18 (in addition to the error that type parameter
lists are not permitted before Go1.18).
Fixes #33232.
Change-Id: I85590c6094b07c3e494fef319e3a38d0217cf6f0
Reviewed-on: https://go-review.googlesource.com/c/go/+/351456
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>
// This also preserves the grouped output of type parameter lists
// when printing type strings.
if i == 0 || f.Type != list[i-1].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)
- }
+ bound = check.typ(f.Type)
}
tparams[i].bound = bound
}
// import "io" // for type assertion tests
-// The predeclared identifier "any" can only be used as a constraint
-// in a type parameter list.
-var _ any // ERROR cannot use any outside constraint position
-func _[_ any /* ok here */ , _ interface{any /* ERROR constraint */ }](any /* ERROR constraint */ ) {
- var _ any /* ERROR constraint */
+var _ any // ok to use any anywhere
+func _[_ any, _ interface{any}](any) {
+ var _ any
}
func identity[T any](x T) T { return x }
_ interface{int|~ /* ERROR overlapping terms ~int */ int }
_ interface{~int|~ /* ERROR overlapping terms ~int */ int }
_ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ }
- _ interface{int|interface{}}
+ _ interface{int|any}
_ interface{int|~string|union}
_ interface{int|~string|interface{int}}
_ interface{union|union /* ERROR overlapping terms p.union and p.union */ }
// For now we do not permit interfaces with methods in unions.
- _ interface{~ /* ERROR invalid use of ~ */ interface{}}
+ _ interface{~ /* ERROR invalid use of ~ */ any}
_ interface{int|interface /* ERROR cannot use .* in union */ { m() }}
)
type (
// Tilde is not permitted on defined types or interfaces.
foo int
- bar interface{}
+ bar any
_ interface{foo}
_ interface{~ /* ERROR invalid use of ~ */ foo }
_ interface{~ /* ERROR invalid use of ~ */ bar }
}
// There is no such thing as a variadic generic type.
-type _[T ... /* ERROR invalid use of ... */ interface{}] struct{}
+type _[T ... /* ERROR invalid use of ... */ any] struct{}
// Generic interfaces may be embedded as one would expect.
type I2 interface {
}
// Valid and invalid variations.
-type B0 interface {}
-type B1[_ any] interface{}
-type B2[_, _ any] interface{}
+type B0 any
+type B1[_ any] any
+type B2[_, _ any] any
func _[T1 B0]() {}
func _[T1 B1[T1]]() {}
package go1_17
-type T[P /* ERROR type parameters require go1\.18 or later */ any] struct{}
+type T[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ] struct{}
// for init (and main, but we're not in package main) we should only get one error
-func init[P /* ERROR func init must have no type parameters */ any]() {}
-func main[P /* ERROR type parameters require go1\.18 or later */ any]() {}
+func init[P /* ERROR func init must have no type parameters */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ]() {}
+func main[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ]() {}
-func f[P /* ERROR type parameters require go1\.18 or later */ any](x P) {
+func f[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ](x P) {
var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int]
var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int])
_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{}
}
return
case universeAny, universeComparable:
- // complain if necessary
if !check.allowVersion(check.pkg, 1, 18) {
check.errorf(e, "undeclared name: %s (requires version go1.18 or later)", e.Value)
return // avoid follow-on errors
}
- if obj == universeAny {
- // If we allow "any" for general use, this if-statement can be removed (issue #33232).
- check.softErrorf(e, "cannot use any outside constraint position")
- // ok to continue
- }
}
check.recordUse(e, obj)
*dst = bindTParams(tparams)
index := 0
- var bound Type
var bounds []Type
var posns []positioner // bound positions
for _, f := range list.List {
- if f.Type == nil {
- goto next
- }
- // 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).(*ast.Ident); name != nil && name.Name == "any" && check.lookup("any") == universeAny {
- bound = universeAny.Type()
- } else {
- bound = check.typ(f.Type)
- }
- bounds = append(bounds, bound)
- posns = append(posns, f.Type)
- for i := range f.Names {
- tparams[index+i].bound = bound
+ // TODO(rfindley) we should be able to rely on f.Type != nil at this point
+ if f.Type != nil {
+ bound := check.typ(f.Type)
+ bounds = append(bounds, bound)
+ posns = append(posns, f.Type)
+ for i := range f.Names {
+ tparams[index+i].bound = bound
+ }
}
-
- next:
index += len(f.Names)
}
// import "io" // for type assertion tests
-// The predeclared identifier "any" can only be used as a constraint
-// in a type parameter list.
-var _ any // ERROR cannot use any outside constraint position
-func _[_ any /* ok here */ , _ interface{any /* ERROR constraint */ }](any /* ERROR constraint */ ) {
- var _ any /* ERROR constraint */
+var _ any // ok to use any anywhere
+func _[_ any, _ interface{any}](any) {
+ var _ any
}
func identity[T any](x T) T { return x }
_ interface{int|~ /* ERROR overlapping terms ~int */ int }
_ interface{~int|~ /* ERROR overlapping terms ~int */ int }
_ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ }
- _ interface{int|interface{}}
+ _ interface{int|any}
_ interface{int|~string|union}
_ interface{int|~string|interface{int}}
_ interface{union|union /* ERROR overlapping terms p.union and p.union */ }
// For now we do not permit interfaces with methods in unions.
- _ interface{~ /* ERROR invalid use of ~ */ interface{}}
+ _ interface{~ /* ERROR invalid use of ~ */ any}
_ interface{int|interface /* ERROR cannot use .* in union */ { m() }}
)
type (
// Tilde is not permitted on defined types or interfaces.
foo int
- bar interface{}
+ bar any
_ interface{foo}
_ interface{~ /* ERROR invalid use of ~ */ foo }
_ interface{~ /* ERROR invalid use of ~ */ bar }
}
// There is no such thing as a variadic generic type.
-type _[T ... /* ERROR invalid use of ... */ interface{}] struct{}
+type _[T ... /* ERROR invalid use of ... */ any] struct{}
// Generic interfaces may be embedded as one would expect.
type I2 interface {
}
// Valid and invalid variations.
-type B0 interface {}
-type B1[_ any] interface{}
-type B2[_, _ any] interface{}
+type B0 any
+type B1[_ any] any
+type B2[_, _ any] any
func _[T1 B0]() {}
func _[T1 B1[T1]]() {}
package go1_17
-type T[P /* ERROR type parameters require go1\.18 or later */ any] struct{}
+type T[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ] struct{}
// for init (and main, but we're not in package main) we should only get one error
-func init[P /* ERROR func init must have no type parameters */ any]() {}
-func main[P /* ERROR type parameters require go1\.18 or later */ any]() {}
+func init[P /* ERROR func init must have no type parameters */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ]() {}
+func main[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ]() {}
-func f[P /* ERROR type parameters require go1\.18 or later */ any](x P) {
+func f[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ](x P) {
var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int]
var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int])
_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{}
}
return
case universeAny, universeComparable:
- // complain if necessary
if !check.allowVersion(check.pkg, 1, 18) {
check.errorf(e, _UndeclaredName, "undeclared name: %s (requires version go1.18 or later)", e.Name)
return // avoid follow-on errors
}
- if obj == universeAny {
- // If we allow "any" for general use, this if-statement can be removed (issue #33232).
- check.softErrorf(e, _Todo, "cannot use any outside constraint position")
- // ok to continue
- }
}
check.recordUse(e, obj)
-// errorcheck
+// compile
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
package p
-var x any // ERROR "undefined: any|undefined type .*any.*|cannot use any outside constraint position"
+// any is now permitted instead of interface{}
+var x any
package tparam1
-// The predeclared identifier "any" is only visible as a constraint
-// in a type parameter list.
-var _ any // ERROR "cannot use any outside constraint position"
-func _(_ any) // ERROR "cannot use any outside constraint position"
-type _[_ any /* ok here */] struct{}
+// The predeclared identifier "any" may be used in place of interface{}.
+var _ any
+func _(_ any)
+type _[_ any] struct{}
const N = 10
_[T1, T2 any, T3 any] struct{}
)
-func _[T any]() {}
-func _[T, T any]() {} // ERROR "T redeclared"
+func _[T any]() {}
+func _[T, T any]() {} // ERROR "T redeclared"
func _[T1, T2 any](x T1) T2 { panic(0) }
// Type parameters are visible from opening [ to end of function.
type C interface{}
-func _[T interface{}]() {}
-func _[T C]() {}
-func _[T struct{}]() {}// ERROR "not an interface"
+func _[T interface{}]() {}
+func _[T C]() {}
+func _[T struct{}]() {} // ERROR "not an interface"
func _[T interface{ m() T }]() {}
func _[T1 interface{ m() T2 }, T2 interface{ m() T1 }]() {
var _ T1