]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: parameterized functions must have a...
authorRobert Griesemer <gri@golang.org>
Mon, 9 Aug 2021 17:53:43 +0000 (10:53 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 10 Aug 2021 01:20:34 +0000 (01:20 +0000)
Add the respective check and add missing bodies to tests.
Use {} as body for functions that don't return a result.
Use { panic(0) } as body for functions that return a result.

For #47069.

Change-Id: Ia5d7525c9c036baf8a955d13bff448401e08235e
Reviewed-on: https://go-review.googlesource.com/c/go/+/340911
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
24 files changed:
src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/testdata/check/issues.go2
src/cmd/compile/internal/types2/testdata/check/map2.go2
src/cmd/compile/internal/types2/testdata/check/mtypeparams.go2
src/cmd/compile/internal/types2/testdata/check/tinference.go2
src/cmd/compile/internal/types2/testdata/check/typeinst2.go2
src/cmd/compile/internal/types2/testdata/check/typeparams.go2
src/cmd/compile/internal/types2/testdata/examples/functions.go2
src/cmd/compile/internal/types2/testdata/examples/inference.go2
src/cmd/compile/internal/types2/testdata/examples/types.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47411.go2
test/typeparam/smoketest.go
test/typeparam/tparam1.go
test/typeparam/typelist.go

index c625bd49594a7cebdc79c64fed57b4c2be5791b2..d8844956afb9f74c2bdd0a0d79ef325953abbb7f 100644 (file)
@@ -329,10 +329,10 @@ func TestTypesInfo(t *testing.T) {
                {brokenPkg + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string]invalid type`},
 
                // parameterized functions
-               {genericPkg + `p0; func f[T any](T); var _ = f[int]`, `f`, `func[generic_p0.T₁ interface{}](generic_p0.T₁)`},
-               {genericPkg + `p1; func f[T any](T); var _ = f[int]`, `f[int]`, `func(int)`},
-               {genericPkg + `p2; func f[T any](T); func _() { f(42) }`, `f`, `func[generic_p2.T₁ interface{}](generic_p2.T₁)`},
-               {genericPkg + `p3; func f[T any](T); func _() { f(42) }`, `f(42)`, `()`},
+               {genericPkg + `p0; func f[T any](T) {}; var _ = f[int]`, `f`, `func[generic_p0.T₁ interface{}](generic_p0.T₁)`},
+               {genericPkg + `p1; func f[T any](T) {}; var _ = f[int]`, `f[int]`, `func(int)`},
+               {genericPkg + `p2; func f[T any](T) {}; func _() { f(42) }`, `f`, `func[generic_p2.T₁ interface{}](generic_p2.T₁)`},
+               {genericPkg + `p3; func f[T any](T) {}; func _() { f(42) }`, `f(42)`, `()`},
 
                // type parameters
                {genericPkg + `t0; type t[] int; var _ t`, `t`, `generic_t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
@@ -389,60 +389,60 @@ func TestInferredInfo(t *testing.T) {
                targs []string
                sig   string
        }{
-               {genericPkg + `p0; func f[T any](T); func _() { f(42) }`,
+               {genericPkg + `p0; func f[T any](T) {}; func _() { f(42) }`,
                        `f`,
                        []string{`int`},
                        `func(int)`,
                },
-               {genericPkg + `p1; func f[T any](T) T; func _() { f('@') }`,
+               {genericPkg + `p1; func f[T any](T) T { panic(0) }; func _() { f('@') }`,
                        `f`,
                        []string{`rune`},
                        `func(rune) rune`,
                },
-               {genericPkg + `p2; func f[T any](...T) T; func _() { f(0i) }`,
+               {genericPkg + `p2; func f[T any](...T) T { panic(0) }; func _() { f(0i) }`,
                        `f`,
                        []string{`complex128`},
                        `func(...complex128) complex128`,
                },
-               {genericPkg + `p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }`,
+               {genericPkg + `p3; func f[A, B, C any](A, *B, []C) {}; func _() { f(1.2, new(string), []byte{}) }`,
                        `f`,
                        []string{`float64`, `string`, `byte`},
                        `func(float64, *string, []byte)`,
                },
-               {genericPkg + `p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }`,
+               {genericPkg + `p4; func f[A, B any](A, *B, ...[]B) {}; func _() { f(1.2, new(byte)) }`,
                        `f`,
                        []string{`float64`, `byte`},
                        `func(float64, *byte, ...[]byte)`,
                },
 
                // we don't know how to translate these but we can type-check them
-               {genericPkg + `q0; type T struct{}; func (T) m[P any](P); func _(x T) { x.m(42) }`,
+               {genericPkg + `q0; type T struct{}; func (T) m[P any](P) {}; func _(x T) { x.m(42) }`,
                        `x.m`,
                        []string{`int`},
                        `func(int)`,
                },
-               {genericPkg + `q1; type T struct{}; func (T) m[P any](P) P; func _(x T) { x.m(42) }`,
+               {genericPkg + `q1; type T struct{}; func (T) m[P any](P) P { panic(0) }; func _(x T) { x.m(42) }`,
                        `x.m`,
                        []string{`int`},
                        `func(int) int`,
                },
-               {genericPkg + `q2; type T struct{}; func (T) m[P any](...P) P; func _(x T) { x.m(42) }`,
+               {genericPkg + `q2; type T struct{}; func (T) m[P any](...P) P { panic(0) }; func _(x T) { x.m(42) }`,
                        `x.m`,
                        []string{`int`},
                        `func(...int) int`,
                },
-               {genericPkg + `q3; type T struct{}; func (T) m[A, B, C any](A, *B, []C); func _(x T) { x.m(1.2, new(string), []byte{}) }`,
+               {genericPkg + `q3; type T struct{}; func (T) m[A, B, C any](A, *B, []C) {}; func _(x T) { x.m(1.2, new(string), []byte{}) }`,
                        `x.m`,
                        []string{`float64`, `string`, `byte`},
                        `func(float64, *string, []byte)`,
                },
-               {genericPkg + `q4; type T struct{}; func (T) m[A, B any](A, *B, ...[]B); func _(x T) { x.m(1.2, new(byte)) }`,
+               {genericPkg + `q4; type T struct{}; func (T) m[A, B any](A, *B, ...[]B) {}; func _(x T) { x.m(1.2, new(byte)) }`,
                        `x.m`,
                        []string{`float64`, `byte`},
                        `func(float64, *byte, ...[]byte)`,
                },
 
-               {genericPkg + `r0; type T[P any] struct{}; func (_ T[P]) m[Q any](Q); func _[P any](x T[P]) { x.m(42) }`,
+               {genericPkg + `r0; type T[P any] struct{}; func (_ T[P]) m[Q any](Q) {}; func _[P any](x T[P]) { x.m(42) }`,
                        `x.m`,
                        []string{`int`},
                        `func(int)`,
@@ -454,38 +454,38 @@ func TestInferredInfo(t *testing.T) {
                //      `func(float64)`,
                // },
 
-               {genericPkg + `s1; func f[T any, P interface{~*T}](x T); func _(x string) { f(x) }`,
+               {genericPkg + `s1; func f[T any, P interface{~*T}](x T) {}; func _(x string) { f(x) }`,
                        `f`,
                        []string{`string`, `*string`},
                        `func(x string)`,
                },
-               {genericPkg + `s2; func f[T any, P interface{~*T}](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s2; func f[T any, P interface{~*T}](x []T) {}; func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `*int`},
                        `func(x []int)`,
                },
-               {genericPkg + `s3; type C[T any] interface{~chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s3; type C[T any] interface{~chan<- T}; func f[T any, P C[T]](x []T) {}; func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `chan<- int`},
                        `func(x []int)`,
                },
-               {genericPkg + `s4; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s4; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T) {}; func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
                        `func(x []int)`,
                },
 
-               {genericPkg + `t1; func f[T any, P interface{~*T}]() T; func _() { _ = f[string] }`,
+               {genericPkg + `t1; func f[T any, P interface{~*T}]() T { panic(0) }; func _() { _ = f[string] }`,
                        `f`,
                        []string{`string`, `*string`},
                        `func() string`,
                },
-               {genericPkg + `t2; type C[T any] interface{~chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
+               {genericPkg + `t2; type C[T any] interface{~chan<- T}; func f[T any, P C[T]]() []T { return nil }; func _() { _ = f[int] }`,
                        `f`,
                        []string{`int`, `chan<- int`},
                        `func() []int`,
                },
-               {genericPkg + `t3; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
+               {genericPkg + `t3; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T { return nil }; func _() { _ = f[int] }`,
                        `f`,
                        []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
                        `func() []int`,
index bb33c287f32bb2dc2a5007eae5910ef02b6b4736..bfccbc5dbf275fbf1c4e4b2a23a94229eae37c95 100644 (file)
@@ -719,6 +719,10 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
        check.funcType(sig, fdecl.Recv, fdecl.TParamList, fdecl.Type)
        obj.color_ = saved
 
+       if len(fdecl.TParamList) > 0 && fdecl.Body == nil {
+               check.softErrorf(fdecl, "parameterized function is missing function body")
+       }
+
        // function body must be type-checked after global declarations
        // (functions implemented elsewhere have no body)
        if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
index 1ede383ebe551cd413a5f7ffc5addade72d65411..effc2db7ae3d1e47e314b85969b24c23edef8bae 100644 (file)
@@ -40,7 +40,7 @@ func _[T interface{ m() }](x *T) {
        x.m /* ERROR x\.m undefined */ ()
 }
 
-func f2[_ interface{ m1(); m2() }]()
+func f2[_ interface{ m1(); m2() }]() {}
 
 type T struct{}
 func (T) m1()
@@ -232,7 +232,7 @@ func _[T interface{ ~func() }](f T) {
 
 type sliceOf[E any] interface{ ~[]E }
 
-func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S
+func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
 
 var f           func()
 var cancelSlice []context.CancelFunc
@@ -240,7 +240,7 @@ var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](can
 
 // A generic function must be instantiated with a type, not a value.
 
-func g[T any](T) T
+func g[T any](T) T { panic(0) }
 
 var _ = g[int]
 var _ = g[nil /* ERROR is not a type */ ]
index 2833445662de813d6d3eeed95978c8342316b29f..be2c49f621efeff4b22a42ca683a5084224a210a 100644 (file)
@@ -114,7 +114,7 @@ func (it *Iterator[K, V]) Next() (K, V, bool) {
 
 // chans
 
-func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T])
+func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T]) { panic(0) }
 
 // A sender is used to send values to a Receiver.
 type chans_Sender[T any] struct {
index c2f282bae11a9817620365e445a9bc8b3f3b310f..1b406593f888a47fc8eb7682c142c9725402a9bc 100644 (file)
@@ -10,7 +10,7 @@ package p
 
 type S struct{}
 
-func (S) m[T any](v T)
+func (S) m[T any](v T) {}
 
 // TODO(gri) Once we collect interface method type parameters
 //           in the parser, we can enable these tests again.
index 1b709817595dd7ca20e568a18b6371ac9a051ab4..0afb77c1e41cfdbc5f6273fa8cf35cf4581a9823 100644 (file)
@@ -23,7 +23,7 @@ type any interface{}
 //     f1(int(0), int(0))
 // }
 
-func f2[A any, B interface{~[]A}](A, B)
+func f2[A any, B interface{~[]A}](A, B) {}
 func _() {
        f := f2[byte]
        f(byte(0), []byte{})
@@ -39,7 +39,7 @@ func _() {
 //     f3(x, &x, &x)
 // }
 
-func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
+func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C) {}
 func _() {
        f := f4[int]
        var x int
@@ -47,14 +47,14 @@ func _() {
        f4(x, []*int{}, &x)
 }
 
-func f5[A interface{~struct{b B; c C}}, B any, C interface{~*B}](x B) A
+func f5[A interface{~struct{b B; c C}}, B any, C interface{~*B}](x B) A { panic(0) }
 func _() {
        x := f5(1.2)
        var _ float64 = x.b
        var _ float64 = *x.c
 }
 
-func f6[A any, B interface{~struct{f []A}}](B) A
+func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
 func _() {
        x := f6(struct{f []string}{})
        var _ string = x
index e90e4dde4482fbd5a24d9a327cdc6503146a6923..d087c26a47e637836a8cc56308dfb53e7314bf1f 100644 (file)
@@ -85,7 +85,7 @@ type NumericAbs[T any] interface {
        Abs() T
 }
 
-func AbsDifference[T NumericAbs[T]](x T)
+func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
 
 type OrderedAbs[T any] T
 
@@ -97,7 +97,7 @@ func OrderedAbsDifference[T any](x T) {
 
 // same code, reduced to essence
 
-func g[P interface{ m() P }](x P)
+func g[P interface{ m() P }](x P) { panic(0) }
 
 type T4[P any] P
 
@@ -205,7 +205,7 @@ type I0 interface {
        E0
 }
 
-func f0[T I0]()
+func f0[T I0]() {}
 var _ = f0[int]
 var _ = f0[bool]
 var _ = f0[string]
@@ -216,7 +216,7 @@ type I01 interface {
        E1
 }
 
-func f01[T I01]()
+func f01[T I01]() {}
 var _ = f01[int]
 var _ = f01[bool /* ERROR does not satisfy I0 */ ]
 var _ = f01[string]
@@ -228,7 +228,7 @@ type I012 interface {
        E2
 }
 
-func f012[T I012]()
+func f012[T I012]() {}
 var _ = f012[int /* ERROR does not satisfy I012 */ ]
 var _ = f012[bool /* ERROR does not satisfy I012 */ ]
 var _ = f012[string /* ERROR does not satisfy I012 */ ]
@@ -239,7 +239,7 @@ type I12 interface {
        E2
 }
 
-func f12[T I12]()
+func f12[T I12]() {}
 var _ = f12[int /* ERROR does not satisfy I12 */ ]
 var _ = f12[bool /* ERROR does not satisfy I12 */ ]
 var _ = f12[string /* ERROR does not satisfy I12 */ ]
@@ -250,7 +250,7 @@ type I0_ interface {
        ~int
 }
 
-func f0_[T I0_]()
+func f0_[T I0_]() {}
 var _ = f0_[int]
 var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
 var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
index ba8e837346423e5349aa0c00aaf2960fbe05bd00..1ad80b1e1b90fc98d343597771d7d8f9e0e30f3d 100644 (file)
@@ -15,9 +15,9 @@ func _[_ any /* ok here */ , _ interface{any /* ERROR constraint */ }](any /* ER
 
 func identity[T any](x T) T { return x }
 
-func _[_ any](x int) int
-func _[T any](T /* ERROR redeclared */ T)()
-func _[T, T /* ERROR redeclared */ any]()
+func _[_ any](x int) int { panic(0) }
+func _[T any](T /* ERROR redeclared */ T)() {}
+func _[T, T /* ERROR redeclared */ any]() {}
 
 // Constraints (incl. any) may be parenthesized.
 func _[_ (any)]() {}
@@ -77,18 +77,18 @@ func new[T any]() *T {
 var _ = new /* ERROR cannot use generic function new */
 var _ *int = new[int]()
 
-func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable
+func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) {} // w/o constraint we don't know if T is comparable
 
-func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int
+func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int { panic(0) }
 var _ = f1[int](struct{T1}{})
 type T1 = int
 
-func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int
+func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int { panic(0) }
 var _ = f2[t1](struct{t1; x float32}{})
 type t1 = int
 
 
-func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int
+func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int { panic(0) }
 
 var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
 
@@ -257,28 +257,28 @@ func _[
 
 var _ = new() /* ERROR cannot infer T */
 
-func f4[A, B, C any](A, B) C
+func f4[A, B, C any](A, B) C { panic(0) }
 
 var _ = f4(1, 2) /* ERROR cannot infer C */
 var _ = f4[int, float32, complex128](1, 2)
 
-func f5[A, B, C any](A, []*B, struct{f []C}) int
+func f5[A, B, C any](A, []*B, struct{f []C}) int { panic(0) }
 
 var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
 var _ = f5(0, nil, struct{f []complex128}{}) // ERROR cannot infer
 var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
 
-func f6[A any](A, []A) int
+func f6[A any](A, []A) int { panic(0) }
 
 var _ = f6(0, nil)
 
-func f6nil[A any](A) int
+func f6nil[A any](A) int { panic(0) }
 
 var _ = f6nil(nil) // ERROR cannot infer
 
 // type inference with variadic functions
 
-func f7[T any](...T) T
+func f7[T any](...T) T { panic(0) }
 
 var _ int = f7() /* ERROR cannot infer T */
 var _ int = f7(1)
@@ -291,7 +291,7 @@ var _ = f7(float64(1), 2.3)
 var _ = f7(1, 2.3 /* ERROR does not match */ )
 var _ = f7(1.2, 3 /* ERROR does not match */ )
 
-func f8[A, B any](A, B, ...B) int
+func f8[A, B any](A, B, ...B) int { panic(0) }
 
 var _ = f8(1) /* ERROR not enough arguments */
 var _ = f8(1, 2.3)
@@ -318,7 +318,7 @@ func (T) m3[P any]() {}
 
 type S1[P any] struct { f P }
 
-func f9[P any](x S1[P])
+func f9[P any](x S1[P]) {}
 
 func _() {
         f9[int](S1[int]{42})
@@ -327,7 +327,7 @@ func _() {
 
 type S2[A, B, C any] struct{}
 
-func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool])
+func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) {}
 
 func _[P any]() {
         f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
@@ -338,7 +338,7 @@ func _[P any]() {
 // corner case for type inference
 // (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
 
-func f11[T any]()
+func f11[T any]() {}
 
 func _() {
        f11[int]()
@@ -346,7 +346,7 @@ func _() {
 
 // the previous example was extracted from
 
-func f12[T interface{m() T}]()
+func f12[T interface{m() T}]() {}
 
 type A[T any] T
 
@@ -374,15 +374,15 @@ func _[T any] (x T) {
 
 type R0 struct{}
 
-func (R0) _[T any](x T)
-func (R0 /* ERROR invalid receiver */ ) _[R0 any]() // scope of type parameters starts at "func"
+func (R0) _[T any](x T) {}
+func (R0 /* ERROR invalid receiver */ ) _[R0 any]() {} // scope of type parameters starts at "func"
 
 type R1[A, B any] struct{}
 
 func (_ R1[A, B]) m0(A, B)
-func (_ R1[A, B]) m1[T any](A, B, T) T
+func (_ R1[A, B]) m1[T any](A, B, T) T { panic(0) }
 func (_ R1 /* ERROR not a generic type */ [R1, _]) _()
-func (_ R1[A, B]) _[A /* ERROR redeclared */ any](B)
+func (_ R1[A, B]) _[A /* ERROR redeclared */ any](B) {}
 
 func _() {
         var r R1[int, string]
index 154d09f52878e226958a11ba8c5b4e79a42c64c7..ef8953cb43b92ff8c3b13d5d661533508077897a 100644 (file)
@@ -66,7 +66,7 @@ var _ float64 = foo(42, []float64{1.0}, &s)
 
 // Type inference works in a straight-forward manner even
 // for variadic functions.
-func variadic[A, B any](A, B, ...B) int
+func variadic[A, B any](A, B, ...B) int { panic(0) }
 
 // var _ = variadic(1) // ERROR not enough arguments
 var _ = variadic(1, 2.3)
@@ -118,9 +118,9 @@ func max[T interface{ ~int }](x ...T) T {
 // Thus even if a type can be inferred successfully, the function
 // call may not be valid.
 
-func fboth[T any](chan T)
-func frecv[T any](<-chan T)
-func fsend[T any](chan<- T)
+func fboth[T any](chan T) {}
+func frecv[T any](<-chan T) {}
+func fsend[T any](chan<- T) {}
 
 func _() {
        var both chan int
@@ -140,9 +140,9 @@ func _() {
        fsend(send)
 }
 
-func ffboth[T any](func(chan T))
-func ffrecv[T any](func(<-chan T))
-func ffsend[T any](func(chan<- T))
+func ffboth[T any](func(chan T)) {}
+func ffrecv[T any](func(<-chan T)) {}
+func ffsend[T any](func(chan<- T)) {}
 
 func _() {
        var both func(chan int)
@@ -169,9 +169,9 @@ func _() {
 // assignment is permitted, parameter passing is permitted as well,
 // so type inference should be able to handle these cases well.
 
-func g1[T any]([]T)
-func g2[T any]([]T, T)
-func g3[T any](*T, ...T)
+func g1[T any]([]T) {}
+func g2[T any]([]T, T) {}
+func g3[T any](*T, ...T) {}
 
 func _() {
        type intSlize []int
@@ -195,7 +195,7 @@ func _() {
 
 // Here's a realistic example.
 
-func append[T any](s []T, t ...T) []T
+func append[T any](s []T, t ...T) []T { panic(0) }
 
 func _() {
        var f func()
@@ -208,8 +208,12 @@ func _() {
 // (that would indicate a slice type). Thus, generic functions cannot
 // have empty type parameter lists, either. This is a syntax error.
 
-func h[] /* ERROR empty type parameter list */ ()
+func h[] /* ERROR empty type parameter list */ () {}
 
 func _() {
        h[] /* ERROR operand */ ()
 }
+
+// Parameterized functions must have a function body.
+
+func _ /* ERROR missing function body */ [P any]()
index 75d47d2c9b48c054a259ff183a3f0d04d16c14eb..e169aec74660bad3c4c3719ac8d07d2fe37e0872 100644 (file)
@@ -10,7 +10,7 @@ type Ordered interface {
        ~int|~float64|~string
 }
 
-func min[T Ordered](x, y T) T
+func min[T Ordered](x, y T) T { panic(0) }
 
 func _() {
        // min can be called with explicit instantiation.
@@ -37,7 +37,7 @@ func _() {
        _ = min("foo", "bar")
 }
 
-func mixed[T1, T2, T3 any](T1, T2, T3)
+func mixed[T1, T2, T3 any](T1, T2, T3) {}
 
 func _() {
        // mixed can be called with explicit instantiation.
@@ -54,7 +54,7 @@ func _() {
        mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
 }
 
-func related1[Slice interface{~[]Elem}, Elem any](s Slice, e Elem)
+func related1[Slice interface{~[]Elem}, Elem any](s Slice, e Elem) {}
 
 func _() {
        // related1 can be called with explicit instantiation.
@@ -78,7 +78,7 @@ func _() {
        related1(si, "foo" /* ERROR cannot use "foo" */ )
 }
 
-func related2[Elem any, Slice interface{~[]Elem}](e Elem, s Slice)
+func related2[Elem any, Slice interface{~[]Elem}](e Elem, s Slice) {}
 
 func _() {
        // related2 can be called with explicit instantiation.
index 4ecc34dfa45beee8bcb44fb65c6200d8c0420593..d662444ead817851e3500a16c0105393b0e58be9 100644 (file)
@@ -216,15 +216,15 @@ type B0 interface {}
 type B1[_ any] interface{}
 type B2[_, _ any] interface{}
 
-func _[T1 B0]()
-func _[T1 B1[T1]]()
-func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+func _[T1 B0]() {}
+func _[T1 B1[T1]]() {}
+func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
 
-func _[T1, T2 B0]()
-func _[T1 B1[T1], T2 B1[T2]]()
-func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]()
+func _[T1, T2 B0]() {}
+func _[T1 B1[T1], T2 B1[T2]]() {}
+func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
 
-func _[T1 B0, T2 B1[T2]]() // here B1 applies to T2
+func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2
 
 // When the type argument is left away, the type bound is
 // instantiated for each type parameter with that type
index 5cb15e7e58a39cee8e118d0a986fc66bd56c2510..8d14f8acaf825937d8d77d59533978ddd87f58d9 100644 (file)
@@ -50,7 +50,7 @@ func (G15 /* ERROR generic type .* without instantiation */ ) p()
 
 // crash 16
 type Foo16[T any] r16 /* ERROR not a type */
-func r16[T any]() Foo16[Foo16[T]]
+func r16[T any]() Foo16[Foo16[T]] { panic(0) }
 
 // crash 17
 type Y17 interface{ c() }
@@ -58,7 +58,7 @@ type Z17 interface {
        c() Y17
        Y17 /* ERROR duplicate method */
 }
-func F17[T Z17](T)
+func F17[T Z17](T) {}
 
 // crash 18
 type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
@@ -88,5 +88,5 @@ type T26 = interface{ F26[ /* ERROR cannot have type parameters */ Z any]() }
 func F26[Z any]() T26 { return F26 /* ERROR without instantiation */ /* ERROR missing method */ [] /* ERROR operand */ }
 
 // crash 27
-func e27[T any]() interface{ x27 /* ERROR not a type */ }
+func e27[T any]() interface{ x27 /* ERROR not a type */ } { panic(0) }
 func x27() { e27( /* ERROR cannot infer T */ ) }
\ No newline at end of file
index 367b3f1360f3cfdb82736edd00a7ac1cd7f27025..d5311ed3e7538e9350a0df3dc23b137a88503ae4 100644 (file)
@@ -6,4 +6,4 @@ package p
 
 // A constraint must be an interface; it cannot
 // be a type parameter, for instance.
-func _[A interface{ ~int }, B A /* ERROR not an interface */ ]()
+func _[A interface{ ~int }, B A /* ERROR not an interface */ ]() {}
index e19b6770bfe4bd21462434f97ace29659a02c4ed..62dc45a59601eecc43e0b23fd09123cf00fbf57d 100644 (file)
@@ -4,13 +4,13 @@
 
 package p
 
-func f1[T1, T2 any](T1, T2, struct{a T1; b T2})
+func f1[T1, T2 any](T1, T2, struct{a T1; b T2}) {}
 func _() {
        f1(42, string("foo"), struct /* ERROR does not match inferred type struct\{a int; b string\} */ {a, b int}{})
 }
 
 // simplified test case from issue
-func f2[T any](_ []T, _ func(T))
+func f2[T any](_ []T, _ func(T)) {}
 func _() {
        f2([]string{}, func /* ERROR does not match inferred type func\(string\) */ (f []byte) {})
 }
index 3db4eae0123930db81b5ff193e58ff802678878a..d703da90a2176a3e975f5a62cad5cf5b3f665faf 100644 (file)
@@ -7,7 +7,7 @@ package p
 type policy[K, V any] interface{}
 type LRU[K, V any] struct{}
 
-func NewCache[K, V any](p policy[K, V])
+func NewCache[K, V any](p policy[K, V]) {}
 
 func _() {
        var lru LRU[int, string]
index 8948d61caa477fff40ac7f773946d0377df734e4..0981a335da3aa91cc12538ddc976f1e34e428e6d 100644 (file)
@@ -8,7 +8,7 @@ type A[T any] int
 
 func (A[T]) m(A[T])
 
-func f[P interface{m(P)}]()
+func f[P interface{m(P)}]() {}
 
 func _() {
        _ = f[A[int]]
index 747aab49dd1639b79bbf7eb0efcf84787b337c4c..a3f3eecca098c6dbbace1dbc19eee13069484b6c 100644 (file)
@@ -10,6 +10,6 @@ func _() {
 
 type S struct {}
 
-func NewS[T any]() *S
+func NewS[T any]() *S { panic(0) }
 
 func (_ *S /* ERROR S is not a generic type */ [T]) M()
index 0269c3a62ce6d0d10d92f0f2cb4e0ce8e82129cf..58d0f69f6503164328feb8990baa1d4bbf201c52 100644 (file)
@@ -6,8 +6,8 @@ package p
 
 type T[_ any] int
 
-func f[_ any]()
-func g[_, _ any]()
+func f[_ any]() {}
+func g[_, _ any]() {}
 
 func _() {
        _ = f[T /* ERROR without instantiation */ ]
index 60650432a47982f1f725b5ef8474d1cf6e3373af..4642ab60fc8edaf7f78c709459f29b549258e33f 100644 (file)
@@ -79,9 +79,9 @@ type T3[_, _, _ any] struct{}
 var _ T1[I2 /* ERROR interface contains type constraints */ ]
 var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
 
-func f1[_ any]() int
+func f1[_ any]() int { panic(0) }
 var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
-func f3[_, _, _ any]() int
+func f3[_, _, _ any]() int { panic(0) }
 var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
 
 func _(x interface{}) {
index 387c946957cd0436f5c9a39b6f4fe9d64d0c5355..108d600a38a6c9ce9075ca792ab7abf4077f1d8e 100644 (file)
@@ -30,8 +30,8 @@ func _[P any]() {
         )
 }
 
-func _[P any, Q interface{ *P | []P | chan P | map[string]P }]()
-func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]()
-func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]()
-func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]()
-func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]()
+func _[P any, Q interface{ *P | []P | chan P | map[string]P }]() {}
+func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]() {}
+func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]() {}
+func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]() {}
+func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]() {}
index 72968f9d43f73ed5b4803d1008d0b1723ab78182..77281a19a2032cf3ac8a250f8a3280fbbca342ef 100644 (file)
@@ -4,8 +4,8 @@
 
 package p
 
-func f[_ comparable]()
-func g[_ interface{interface{comparable; ~int|~string}}]()
+func f[_ comparable]() {}
+func g[_ interface{interface{comparable; ~int|~string}}]() {}
 
 func _[P comparable,
         Q interface{ comparable; ~int|~string },
index eeda25964f40d9f4d4b21ab7112f4416c3b22db1..5243dc5c3c15f7d806f2c9f80942d81ce05e8671 100644 (file)
@@ -9,9 +9,9 @@
 package smoketest
 
 // type parameters for functions
-func f1[P any]()
-func f2[P1, P2 any, P3 any]()
-func f3[P interface{}](x P, y T1[int])
+func f1[P any]() {}
+func f2[P1, P2 any, P3 any]() {}
+func f3[P interface{}](x P, y T1[int]) {}
 
 // function instantiations
 var _ = f1[int]
index a196caf976b0e8d8356ab371540e4d2e32fe7b6f..698877a6f00d65d13bc0c76edb2a6d3928644c00 100644 (file)
@@ -24,17 +24,17 @@ type (
        _[T1, T2 any, T3 any] struct{}
 )
 
-func _[T any]()
-func _[T, T any]() // ERROR "T redeclared"
-func _[T1, T2 any](x T1) T2
+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{ m() T }]()
+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
 }
index a68ae1b5cd04e11e8c47e480c97c35a9f75a0b87..5ba14261ab0823efee35dc1e626906316daabfe2 100644 (file)
@@ -85,7 +85,7 @@ func f1x() {
 }
 */
 
-func f2[A any, B interface{ type []A }](_ A, _ B)
+func f2[A any, B interface{ type []A }](_ A, _ B) {}
 func f2x() {
        f := f2[byte]
        f(byte(0), []byte{})
@@ -105,7 +105,7 @@ func f3x() {
 }
 */
 
-func f4[A any, B interface{ type []C }, C interface{ type *A }](_ A, _ B, c C)
+func f4[A any, B interface{ type []C }, C interface{ type *A }](_ A, _ B, c C) {}
 func f4x() {
        f := f4[int]
        var x int
@@ -118,14 +118,14 @@ func f5[A interface {
                b B
                c C
        }
-}, B any, C interface{ type *B }](x B) A
+}, B any, C interface{ type *B }](x B) A { panic(0) }
 func f5x() {
        x := f5(1.2)
        var _ float64 = x.b
        var _ float64 = *x.c
 }
 
-func f6[A any, B interface{ type struct{ f []A } }](B) A
+func f6[A any, B interface{ type struct{ f []A } }](B) A { panic(0) }
 func f6x() {
        x := f6(struct{ f []string }{})
        var _ string = x