]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile, go/types: allow `any` anywhere (as a type)
authorRobert Griesemer <gri@golang.org>
Wed, 22 Sep 2021 18:26:40 +0000 (11:26 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 22 Sep 2021 19:19:49 +0000 (19:19 +0000)
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>
14 files changed:
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/testdata/check/typeparams.go2
src/cmd/compile/internal/types2/testdata/examples/constraints.go2
src/cmd/compile/internal/types2/testdata/examples/types.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47818.go2
src/cmd/compile/internal/types2/typexpr.go
src/go/types/decl.go
src/go/types/testdata/check/typeparams.go2
src/go/types/testdata/examples/constraints.go2
src/go/types/testdata/examples/types.go2
src/go/types/testdata/fixedbugs/issue47818.go2
src/go/types/typexpr.go
test/fixedbugs/issue14652.go
test/typeparam/tparam1.go

index 1926d93a86aeb9c943f8bc996f978b42a2b3783e..994c19ea30aa959887294af3bb5f0567c9e88841 100644 (file)
@@ -625,13 +625,7 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list []*syntax.Fiel
                // 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
        }
index 765d561f3b57dbdfde16903aa7c3d8da86d10dd5..69b6925b9f019eb795535273056b05ea413e587f 100644 (file)
@@ -6,11 +6,9 @@ package p
 
 // 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 }
index f40d18c63e8786bf57e427c7d483868bfdb81c6d..ecc75c1a46f98b7fa7e57fe0d1d8e2517ff9660c 100644 (file)
@@ -33,20 +33,20 @@ type (
        _ 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 }
index 97c9951ada56d0a520bff3b257b7ed568b0f72b0..55b1b0da57318bc72d16941b2e0a72bf8779ae84 100644 (file)
@@ -114,7 +114,7 @@ type I1[T any] interface{
 }
 
 // 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 {
@@ -213,9 +213,9 @@ func Sum[T Adder[T]](list []T) T {
 }
 
 // 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]]() {}
index 5334695b5e9e28b982c70057f76c91278d5d34c0..166cc680dbcc57e120a6c0dc0837d2de7d723d24 100644 (file)
@@ -8,13 +8,13 @@
 
 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]{}
index 5aacb94a605c756e0755bd21c5cf40e94ae33aa8..7f75a96bd837649a83ab121487d09997148ec0ed 100644 (file)
@@ -38,16 +38,10 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType boo
                }
                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)
 
index 0fdcfa8023dd51d915123fa4af0d8503a286a624..061fc018296cd23c6ea995600aa3dbf9d02edb3e 100644 (file)
@@ -668,27 +668,18 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
        *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)
        }
 
index 57b6d7a0ad87b307e8038548076fe63bf1f73717..bfacb3e1e7ebfcfd0cc3929f2de46f8c3a254616 100644 (file)
@@ -6,11 +6,9 @@ package p
 
 // 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 }
index f40d18c63e8786bf57e427c7d483868bfdb81c6d..ecc75c1a46f98b7fa7e57fe0d1d8e2517ff9660c 100644 (file)
@@ -33,20 +33,20 @@ type (
        _ 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 }
index 6f6f95e781b6858c8ea311fb44b8e354154adb06..2e6eeb22044a49fa4ecaeecf91f1c5a62f0d122d 100644 (file)
@@ -114,7 +114,7 @@ type I1[T any] interface{
 }
 
 // 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 {
@@ -219,9 +219,9 @@ func Sum[T Adder[T]](list []T) T {
 }
 
 // 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]]() {}
index 68c6a94ed44f3fb971d4a0073ee65f1b05a24755..e3e5a99637b6af353a434f9c4b240e283baf155d 100644 (file)
@@ -8,13 +8,13 @@
 
 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]{}
index a1b8bae3d5f6d0bf61bad92110e92002213ed4d5..505c6394443e250b39ceb798c359afee09fba451 100644 (file)
@@ -36,16 +36,10 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool)
                }
                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)
 
index 14a223977b4a1ddd1952d063f97e6bcd27517bc8..586663b676fd9c26abb18b2c4c0b8ccc226db9ae 100644 (file)
@@ -1,4 +1,4 @@
-// errorcheck
+// compile
 
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -6,4 +6,5 @@
 
 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
index 698877a6f00d65d13bc0c76edb2a6d3928644c00..3b4260c1023f053eca960f53627925d1fca4e604 100644 (file)
@@ -8,11 +8,10 @@
 
 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
 
@@ -24,16 +23,16 @@ type (
        _[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