mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile: call transformArgs before early typecheckaste in noder
In the cases where we do an early call to typecheckaste() in noder to expose CONVIFACE nodes, we need a preceding call to transformArgs(). This is needed to allow typecheckaste() to run correctly, in the case of f(g()), where g has multiple return values. I also cleaned up the code a bit and commented the code in Call(), and we do the call to typecheckaste() in several more cases. In stencil.go:stencil(), I moved the transformCall earlier for the OCALLMETH/ODOTMETH case, just as I did in my previous CL for OCALL/OFUNCINST. By doing this, transformArgs no longer needs to deal with the extra dictionary args. Therefore, I was able to simply transformArgs() to look like typecheckargs() again, and make use of RewriteMultiValue directly. Updates #47514 Change-Id: I49eb82ac05707e50c2e2fb03e39458a70491d406 Reviewed-on: https://go-review.googlesource.com/c/go/+/340531 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
ca3c6985cd
commit
9f4d6a8359
5 changed files with 55 additions and 91 deletions
|
|
@ -171,39 +171,34 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
|
|||
}
|
||||
}
|
||||
|
||||
if fun.Type().HasTParam() {
|
||||
if fun.Type().HasTParam() || fun.Op() == ir.OXDOT || fun.Op() == ir.OFUNCINST {
|
||||
// If the fun arg is or has a type param, we can't do all the
|
||||
// transformations, since we may not have needed properties yet.
|
||||
// (e.g. number of return values, etc). However, if we do have the
|
||||
// function type (even though it is parameterized), then can add in
|
||||
// any needed CONVIFACE nodes. We can't do anything if fun is a type
|
||||
// param (which is probably described by a structural constraint)
|
||||
// transformations, since we may not have needed properties yet
|
||||
// (e.g. number of return values, etc). The same applies if a fun
|
||||
// which is an XDOT could not be transformed yet because of a generic
|
||||
// type in the X of the selector expression.
|
||||
//
|
||||
// A function instantiation (even if fully concrete) shouldn't be
|
||||
// transformed yet, because we need to add the dictionary during the
|
||||
// transformation.
|
||||
//
|
||||
// However, if we have a function type (even though it is
|
||||
// parameterized), then we can add in any needed CONVIFACE nodes via
|
||||
// typecheckaste(). We need to call transformArgs() to deal first
|
||||
// with the f(g(()) case where g returns multiple return values. We
|
||||
// can't do anything if fun is a type param (which is probably
|
||||
// described by a structural constraint)
|
||||
if fun.Type().Kind() == types.TFUNC {
|
||||
transformArgs(n)
|
||||
typecheckaste(ir.OCALL, fun, n.IsDDD, fun.Type().Params(), n.Args, true)
|
||||
}
|
||||
return typed(typ, n)
|
||||
}
|
||||
|
||||
if fun.Op() == ir.OXDOT {
|
||||
if !fun.(*ir.SelectorExpr).X.Type().HasTParam() {
|
||||
base.FatalfAt(pos, "Expecting type param receiver in %v", fun)
|
||||
}
|
||||
// For methods called in a generic function, don't do any extra
|
||||
// transformations. We will do those later when we create the
|
||||
// instantiated function and have the correct receiver type.
|
||||
typed(typ, n)
|
||||
return n
|
||||
}
|
||||
if fun.Op() != ir.OFUNCINST {
|
||||
// If no type params, do the normal call transformations. This
|
||||
// will convert OCALL to OCALLFUNC.
|
||||
typed(typ, n)
|
||||
transformCall(n)
|
||||
return n
|
||||
}
|
||||
|
||||
// Leave the op as OCALL, which indicates the call still needs typechecking.
|
||||
// If no type params, do the normal call transformations. This
|
||||
// will convert OCALL to OCALLFUNC.
|
||||
typed(typ, n)
|
||||
transformCall(n)
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue