]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile: refactor `range` desugaring
authorMatthew Dempsky <mdempsky@google.com>
Thu, 30 Jun 2022 02:23:34 +0000 (19:23 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 30 Jun 2022 18:42:33 +0000 (18:42 +0000)
This CL refactors the code responsible for emitting the user-visible
assignments within a range statement. This will make it easier to
propagate RTTI from the frontend into any implicit conversions.

Updates #53328.

Change-Id: Ibed15e3b4951b0a6a726067b401a630977f4c6c2
Reviewed-on: https://go-review.googlesource.com/c/go/+/415158
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/walk/range.go

index 16d7595baa644098fea138aeeb6bd7a13783ce88..60eec25bcf1b8d7e42db0fa634ac4de33304ffbf 100644 (file)
@@ -103,7 +103,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
 
                // for v1 := range ha { body }
                if v2 == nil {
-                       body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+                       body = []ir.Node{rangeAssign(nrange, hv1)}
                        break
                }
 
@@ -112,10 +112,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                        // v1, v2 = hv1, ha[hv1]
                        tmp := ir.NewIndexExpr(base.Pos, ha, hv1)
                        tmp.SetBounded(true)
-                       // Use OAS2 to correctly handle assignments
-                       // of the form "v1, a[v1] := range".
-                       a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, tmp})
-                       body = []ir.Node{a}
+                       body = []ir.Node{rangeAssign2(nrange, hv1, tmp)}
                        break
                }
 
@@ -140,9 +137,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                tmp.SetBounded(true)
                init = append(init, ir.NewAssignStmt(base.Pos, hp, typecheck.NodAddr(tmp)))
 
-               // Use OAS2 to correctly handle assignments
-               // of the form "v1, a[v1] := range".
-               a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, ir.NewStarExpr(base.Pos, hp)})
+               a := rangeAssign2(nrange, hv1, ir.NewStarExpr(base.Pos, hp))
                body = append(body, a)
 
                // Advance pointer as part of the late increment.
@@ -179,11 +174,10 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                if v1 == nil {
                        body = nil
                } else if v2 == nil {
-                       body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, key)}
+                       body = []ir.Node{rangeAssign(nrange, key)}
                } else {
                        elem := ir.NewStarExpr(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, elemsym))
-                       a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{key, elem})
-                       body = []ir.Node{a}
+                       body = []ir.Node{rangeAssign2(nrange, key, elem)}
                }
 
        case types.TCHAN:
@@ -206,7 +200,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                if v1 == nil {
                        body = nil
                } else {
-                       body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+                       body = []ir.Node{rangeAssign(nrange, hv1)}
                }
                // Zero hv1. This prevents hv1 from being the sole, inaccessible
                // reference to an otherwise GC-able value during the next channel receive.
@@ -271,11 +265,10 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                if v1 != nil {
                        if v2 != nil {
                                // v1, v2 = hv1t, hv2
-                               a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1t, hv2})
-                               body = append(body, a)
+                               body = append(body, rangeAssign2(nrange, hv1t, hv2))
                        } else {
                                // v1 = hv1t
-                               body = append(body, ir.NewAssignStmt(base.Pos, v1, hv1t))
+                               body = append(body, rangeAssign(nrange, hv1t))
                        }
                }
        }
@@ -310,6 +303,20 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
        return n
 }
 
+// rangeAssign returns "n.Key = key".
+func rangeAssign(n *ir.RangeStmt, key ir.Node) ir.Node {
+       // TODO(mdempsky): Implicit conversions for test/typeparam/mdempsky/17.go.
+       return ir.NewAssignStmt(n.Pos(), n.Key, key)
+}
+
+// rangeAssign2 returns "n.Key, n.Value = key, value".
+func rangeAssign2(n *ir.RangeStmt, key, value ir.Node) ir.Node {
+       // Use OAS2 to correctly handle assignments
+       // of the form "v1, a[v1] = range".
+       // TODO(mdempsky): Implicit conversions for test/typeparam/mdempsky/17.go.
+       return ir.NewAssignListStmt(n.Pos(), ir.OAS2, []ir.Node{n.Key, n.Value}, []ir.Node{key, value})
+}
+
 // isMapClear checks if n is of the form:
 //
 //     for k := range m {