]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile: implicit conversions for return statements
authorMatthew Dempsky <mdempsky@google.com>
Tue, 21 Jun 2022 19:02:03 +0000 (12:02 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 23 Jun 2022 21:55:25 +0000 (21:55 +0000)
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 <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/noder/writer.go

index 7d4cdb014b751b8c923401e20227b9159e7c45c6..ec744f41222f20f13f5c96865435a5d1088e95f2 100644 (file)
@@ -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)