aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/noder/expr.go8
-rw-r--r--src/cmd/compile/internal/noder/stencil.go11
-rw-r--r--src/cmd/compile/internal/noder/transform.go3
-rw-r--r--src/cmd/compile/internal/typecheck/subr.go6
4 files changed, 22 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go
index 6e2b1a839b..3e3c352a32 100644
--- a/src/cmd/compile/internal/noder/expr.go
+++ b/src/cmd/compile/internal/noder/expr.go
@@ -125,13 +125,17 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
}
if fun.Op() == ir.OFUNCINST {
// Replace explicit type args with the full list that
- // includes the additional inferred type args
+ // includes the additional inferred type args.
+ // Substitute the type args for the type params in
+ // the generic function's type.
fun.(*ir.InstExpr).Targs = targs
+ newt := g.substType(fun.Type(), fun.Type().TParams(), targs)
+ typed(newt, fun)
} else {
// Create a function instantiation here, given there
// are only inferred type args (e.g. min(5,6), where
// min is a generic function). Substitute the type
- // args for the type params in the uninstantiated function's
+ // args for the type params in the generic function's
// type.
inst := ir.NewInstExpr(pos, ir.OFUNCINST, fun, targs)
newt := g.substType(fun.Type(), fun.Type().TParams(), targs)
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index 7cc37f1154..b37f76dcee 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -119,6 +119,14 @@ func (g *irgen) stencil() {
fmt.Printf("%s in %v at generic function call: %v - %v\n", dictkind, decl, inst.X, call)
}
}
+
+ // Transform the Call now, which changes OCALL to
+ // OCALLFUNC and does typecheckaste/assignconvfn. Do
+ // it before installing the instantiation, so we are
+ // checking against non-shape param types in
+ // typecheckaste.
+ transformCall(call)
+
// Replace the OFUNCINST with a direct reference to the
// new stenciled function
call.X = st.Nname
@@ -132,9 +140,6 @@ func (g *irgen) stencil() {
// Add dictionary to argument list.
call.Args.Prepend(dictValue)
- // Transform the Call now, which changes OCALL
- // to OCALLFUNC and does typecheckaste/assignconvfn.
- transformCall(call)
modified = true
}
if n.Op() == ir.OCALLMETH && n.(*ir.CallExpr).X.Op() == ir.ODOTMETH && len(deref(n.(*ir.CallExpr).X.Type().Recv().Type).RParams()) > 0 {
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go
index 9c791d8a7b..61af92b62a 100644
--- a/src/cmd/compile/internal/noder/transform.go
+++ b/src/cmd/compile/internal/noder/transform.go
@@ -130,7 +130,8 @@ func transformConvCall(n *ir.CallExpr) ir.Node {
}
// transformCall transforms a normal function/method call. Corresponds to last half
-// (non-conversion, non-builtin part) of typecheck.tcCall.
+// (non-conversion, non-builtin part) of typecheck.tcCall. This code should work even
+// in the case of OCALL/OFUNCINST.
func transformCall(n *ir.CallExpr) {
// n.Type() can be nil for calls with no return value
assert(n.Typecheck() == 1)
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index 53c3933370..e840df56dc 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -1278,6 +1278,12 @@ func (ts *Tsubster) tstruct(t *types.Type, force bool) *types.Type {
// the type param, not the instantiated type).
newfields[i] = types.NewField(f.Pos, f.Sym, t2)
newfields[i].Embedded = f.Embedded
+ if f.IsDDD() {
+ newfields[i].SetIsDDD(true)
+ }
+ if f.Nointerface() {
+ newfields[i].SetNointerface(true)
+ }
if f.Nname != nil && ts.Vars != nil {
v := ts.Vars[f.Nname.(*ir.Name)]
if v != nil {