From ba7673069d9be4972a864023d74e9e0dd6a77b80 Mon Sep 17 00:00:00 2001 From: korzhao Date: Sat, 25 Sep 2021 01:13:27 +0800 Subject: [PATCH] cmd/compile: add required CONVIFACE nodes when translating OFUNCINST node In CL 349614. we removed the early transformation code that was needed to create the implicit CONVIFACE nodes. Because the transformCall function is not called when translating OFUNCINST. So we add in needed CONVIFACE nodes via typecheckaste(). Fixes #48598 Change-Id: If9dc7040cdc38ef2e52fdbb08c840095651426f2 Reviewed-on: https://go-review.googlesource.com/c/go/+/351856 Reviewed-by: Cuong Manh Le Reviewed-by: Dan Scales Trust: Cuong Manh Le Trust: Dan Scales Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot --- src/cmd/compile/internal/noder/stencil.go | 4 +++ src/cmd/compile/internal/noder/transform.go | 6 +++++ test/typeparam/issue48598.go | 28 +++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 test/typeparam/issue48598.go diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index 23f53bac04..d5fb9f338c 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -1097,6 +1097,10 @@ func (subst *subster) node(n ir.Node) ir.Node { // A call with an OFUNCINST will get transformed // in stencil() once we have created & attached the // instantiation to be called. + // We must transform the arguments of the call now, though, + // so that any needed CONVIFACE nodes are exposed, + // so the dictionary format is correct + transformEarlyCall(call) case ir.OXDOT, ir.ODOTTYPE, ir.ODOTTYPE2: default: diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go index 953036eb42..f7115904fe 100644 --- a/src/cmd/compile/internal/noder/transform.go +++ b/src/cmd/compile/internal/noder/transform.go @@ -177,6 +177,12 @@ func transformCall(n *ir.CallExpr) { } } +// transformEarlyCall transforms the arguments of a call with an OFUNCINST node. +func transformEarlyCall(n *ir.CallExpr) { + transformArgs(n) + typecheckaste(ir.OCALL, n.X, n.IsDDD, n.X.Type().Params(), n.Args) +} + // transformCompare transforms a compare operation (currently just equals/not // equals). Corresponds to the "comparison operators" case in // typecheck.typecheck1, including tcArith. diff --git a/test/typeparam/issue48598.go b/test/typeparam/issue48598.go new file mode 100644 index 0000000000..ea360f2135 --- /dev/null +++ b/test/typeparam/issue48598.go @@ -0,0 +1,28 @@ +// 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 + +type Iterator[T any] interface { + Iterate() +} + +type IteratorFunc[T any] func(fn func(T) bool) + +func (f IteratorFunc[T]) Iterate() { +} + +func FromIterator[T any](it Iterator[T]) { + it.Iterate() +} + +func Foo[T, R any]() { + FromIterator[R](IteratorFunc[R](nil)) +} + +func main() { + Foo[int, int]() +} -- 2.50.0