mirror of https://github.com/golang/go.git
go/types: don't compute parameter list twice for regular generic functions (optimization)
Avoid a substitution operation for non-variadic generic functions. Change-Id: Id40c0078a05be3aa53cd5b8551fa9fe6107bcda8
This commit is contained in:
parent
99c8ae0d28
commit
72d320ec6e
|
|
@ -262,7 +262,8 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, args []*oper
|
|||
ddd := call.Ellipsis.IsValid()
|
||||
|
||||
// set up parameters
|
||||
sig_params := sig.params
|
||||
sig_params := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
|
||||
adjusted := false // indicates if sig_params is different from t.params
|
||||
if sig.variadic {
|
||||
if ddd {
|
||||
// variadic_func(a, b, c...)
|
||||
|
|
@ -284,7 +285,8 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, args []*oper
|
|||
for len(vars) < nargs {
|
||||
vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
|
||||
}
|
||||
sig_params = NewTuple(vars...)
|
||||
sig_params = NewTuple(vars...) // possibly nil!
|
||||
adjusted = true
|
||||
npars = nargs
|
||||
} else {
|
||||
// nargs < npars-1
|
||||
|
|
@ -318,14 +320,24 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, args []*oper
|
|||
if targs == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// compute result signature
|
||||
rsig = check.instantiate(call.Pos(), sig, targs, nil).(*Signature)
|
||||
assert(rsig.tparams == nil) // signature is not generic anymore
|
||||
sig_params = check.subst(call.Pos(), sig_params, sig.tparams, targs).(*Tuple)
|
||||
// TODO(gri) Optimization: We don't need to check arguments
|
||||
// from which we inferred parameter types.
|
||||
|
||||
// Optimization: Only if the parameter list was adjusted do we
|
||||
// need to compute it from the adjusted list; otherwise we can
|
||||
// simply use the result signature's parameter list.
|
||||
if adjusted {
|
||||
sig_params = check.subst(call.Pos(), sig_params, sig.tparams, targs).(*Tuple)
|
||||
} else {
|
||||
sig_params = rsig.params
|
||||
}
|
||||
}
|
||||
|
||||
// check arguments
|
||||
// TODO(gri) Possible optimization (may be tricky): We could avoid
|
||||
// checking arguments from which we inferred type arguments.
|
||||
for i, a := range args {
|
||||
check.assignment(a, sig_params.vars[i].typ, "argument")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,14 @@
|
|||
|
||||
package p
|
||||
|
||||
/*
|
||||
type T(type E) struct {
|
||||
f *T(E)
|
||||
}
|
||||
|
||||
var _ T(int)
|
||||
*/
|
||||
|
||||
func f(type T)(...T) T
|
||||
|
||||
var _ int = f() /* ERROR cannot infer T */
|
||||
|
|
|
|||
Loading…
Reference in New Issue