Skip to content

Commit

Permalink
[dev.unified] cmd/compile: special case f(g()) calls in Unified IR
Browse files Browse the repository at this point in the history
For f(g()) calls where g() is multi-valued, we may need to insert
implicit conversions to convert g()'s result values to f()'s parameter
types. This CL refactors code slightly so this will be easier to
handle.

Change-Id: I3a432220dcb62daecf9a66030e8fa1f097e95f95
Reviewed-on: https://go-review.googlesource.com/c/go/+/413362
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
  • Loading branch information
mdempsky committed Jun 23, 2022
1 parent 61ae2b7 commit 20e1d5a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
11 changes: 9 additions & 2 deletions src/cmd/compile/internal/noder/reader.go
Expand Up @@ -1735,8 +1735,15 @@ func (r *reader) expr() (res ir.Node) {
fun = typecheck.Callee(ir.NewSelectorExpr(pos, ir.OXDOT, fun, sym))
}
pos := r.pos()
args := r.exprs()
dots := r.Bool()
var args ir.Nodes
var dots bool
if r.Bool() { // f(g())
call := r.expr()
args = []ir.Node{call}
} else {
args = r.exprs()
dots = r.Bool()
}
n := typecheck.Call(pos, fun, args, dots)
switch n.Op() {
case ir.OAPPEND:
Expand Down
23 changes: 21 additions & 2 deletions src/cmd/compile/internal/noder/writer.go
Expand Up @@ -1505,8 +1505,14 @@ func (w *writer) expr(expr syntax.Expr) {
w.Code(exprCall)
writeFunExpr()
w.pos(expr)
w.exprs(expr.ArgList)
w.Bool(expr.HasDots)
if w.Bool(len(expr.ArgList) == 1 && isMultiValueExpr(w.p.info, expr.ArgList[0])) {
// f(g()) call
assert(!expr.HasDots)
w.expr(expr.ArgList[0])
} else {
w.exprs(expr.ArgList)
w.Bool(expr.HasDots)
}
}
}

Expand Down Expand Up @@ -1999,6 +2005,19 @@ func isPkgQual(info *types2.Info, sel *syntax.SelectorExpr) bool {
return false
}

// isMultiValueExpr reports whether expr is a function call expression
// that yields multiple values.
func isMultiValueExpr(info *types2.Info, expr syntax.Expr) bool {
tv, ok := info.Types[expr]
assert(ok)
assert(tv.IsValue())
if tuple, ok := tv.Type.(*types2.Tuple); ok {
assert(tuple.Len() > 1)
return true
}
return false
}

// recvBase returns the base type for the given receiver parameter.
func recvBase(recv *types2.Var) *types2.Named {
typ := recv.Type()
Expand Down

0 comments on commit 20e1d5a

Please sign in to comment.