From 421e9e9db21363a196f9c5d736749a6754803bff Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 21 Jun 2022 12:02:03 -0700 Subject: [PATCH] [dev.unified] cmd/compile: implicit conversions for return statements This CL inserts implicit conversions for simple N:N return statements. A subsequent CL will handle N:1 return statements. Change-Id: Ia672db3e214025510485e17d3d50d42ff01bc74e Reviewed-on: https://go-review.googlesource.com/c/go/+/413517 Reviewed-by: Keith Randall Run-TryBot: Matthew Dempsky Reviewed-by: David Chase TryBot-Result: Gopher Robot --- src/cmd/compile/internal/noder/writer.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 7d4cdb014b7..ec744f41222 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -134,6 +134,9 @@ type writer struct { pkgbits.Encoder + // sig holds the signature for the current function body, if any. + sig *types2.Signature + // TODO(mdempsky): We should be able to prune localsIdx whenever a // scope closes, and then maybe we can just use the same map for // storing the TypeParams too (as their TypeName instead). @@ -957,6 +960,7 @@ func (w *writer) pragmaFlag(p ir.PragmaFlag) { // block), adding it to the export data func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posVar) { w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody) + w.sig = sig w.dict = dict w.funcargs(sig) @@ -1132,7 +1136,25 @@ func (w *writer) stmt1(stmt syntax.Stmt) { case *syntax.ReturnStmt: w.Code(stmtReturn) w.pos(stmt) - w.exprList(stmt.Results) // TODO(mdempsky): Implicit conversions to result types. + + // As if w.exprList(stmt.Results), but with implicit conversions to result types. + w.Sync(pkgbits.SyncExprList) + exprs := unpackListExpr(stmt.Results) + w.Sync(pkgbits.SyncExprs) + w.Len(len(exprs)) + + resultTypes := w.sig.Results() + if len(exprs) == resultTypes.Len() { + for i, expr := range exprs { + w.implicitExpr(stmt, resultTypes.At(i).Type(), expr) + } + } else if len(exprs) == 0 { + // ok: bare "return" with named result parameters + } else { + // TODO(mdempsky): Implicit conversions for "return g()", where g() is multi-valued. + assert(len(exprs) == 1) + w.expr(exprs[0]) + } case *syntax.SelectStmt: w.Code(stmtSelect)