| // run | |
| // Copyright 2021 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package main | |
| import ( | |
| "fmt" | |
| "reflect" | |
| ) | |
| type G[T any] interface { | |
| g() func()(*T) | |
| } | |
| type Foo[T any] struct { | |
| } | |
| // OCALL | |
| func (l *Foo[T]) f1() (*T) { | |
| return g[T]()() | |
| } | |
| // OCALLFUNC | |
| func (l *Foo[T]) f2() (*T) { | |
| var f = g[T] | |
| return f()() | |
| } | |
| // OCALLMETH | |
| func (l *Foo[T]) f3() (*T) { | |
| return l.g()() | |
| } | |
| // OCALLINTER | |
| func (l *Foo[T]) f4() (*T) { | |
| var g G[T] = l | |
| return g.g()() | |
| } | |
| // ODYNAMICDOTTYPE | |
| func (l *Foo[T]) f5() (*T) { | |
| var x interface{} | |
| x = g[T] | |
| return x.(func()func()(*T))()() | |
| } | |
| func (l *Foo[T]) g() func() (*T) { | |
| return func() (*T) { | |
| t := new(T) | |
| reflect.ValueOf(t).Elem().SetInt(100) | |
| return t | |
| } | |
| } | |
| func g[T any]() func() (*T) { | |
| return func() (*T) { | |
| t := new(T) | |
| reflect.ValueOf(t).Elem().SetInt(100) | |
| return t | |
| } | |
| } | |
| func main() { | |
| foo := Foo[int]{} | |
| // Make sure the function conversion is correct | |
| if n := *(foo.f1()) ; n != 100{ | |
| panic(fmt.Sprintf("%v",n)) | |
| } | |
| if n := *(foo.f2()) ; n != 100{ | |
| panic(fmt.Sprintf("%v",n)) | |
| } | |
| if n := *(foo.f3()) ; n != 100{ | |
| panic(fmt.Sprintf("%v",n)) | |
| } | |
| if n := *(foo.f4()) ; n != 100{ | |
| panic(fmt.Sprintf("%v",n)) | |
| } | |
| if n := *(foo.f5()) ; n != 100{ | |
| panic(fmt.Sprintf("%v",n)) | |
| } | |
| } |