diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index 7ba266a1505..3b15ac2c970 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -1095,6 +1095,9 @@ func (subst *subster) node(n ir.Node) ir.Node { // or channel receive to compute function value. transformCall(call) + case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.ODYNAMICDOTTYPE: + transformCall(call) + case ir.OFUNCINST: // A call with an OFUNCINST will get transformed // in stencil() once we have created & attached the diff --git a/test/typeparam/issue48042.go b/test/typeparam/issue48042.go new file mode 100644 index 00000000000..db5de3d8fae --- /dev/null +++ b/test/typeparam/issue48042.go @@ -0,0 +1,77 @@ +// run -gcflags=-G=3 + +// 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)) + } +} \ No newline at end of file