]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile/internal/walk: RType fields for range assignments
authorMatthew Dempsky <mdempsky@google.com>
Thu, 30 Jun 2022 21:49:28 +0000 (14:49 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 1 Jul 2022 15:12:15 +0000 (15:12 +0000)
This CL adds extra fields to RangeStmt that can be used when
desugaring into primitive assignment statements. This will allow the
frontend to wire up all of the RTTI necessary, pulling from
dictionaries as necessary.

Updates #53328.

Change-Id: Iab0e3029ff18c947782ff24f71ef20b2b5cb8305
Reviewed-on: https://go-review.googlesource.com/c/go/+/415518
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ir/stmt.go
src/cmd/compile/internal/walk/range.go

index 10f8b5e3942be3c02cf81f474b3a0a410f8db549..cae773b722716bb2679d2fb7002cfb208f867273 100644 (file)
@@ -350,6 +350,14 @@ type RangeStmt struct {
        Body     Nodes
        HasBreak bool
        Prealloc *Name
+
+       // When desugaring the RangeStmt during walk, the assignments to Key
+       // and Value may require OCONVIFACE operations. If so, these fields
+       // will be copied to their respective ConvExpr fields.
+       KeyTypeWord   Node `mknode:"-"`
+       KeySrcRType   Node `mknode:"-"`
+       ValueTypeWord Node `mknode:"-"`
+       ValueSrcRType Node `mknode:"-"`
 }
 
 func NewRangeStmt(pos src.XPos, key, value, x Node, body []Node) *RangeStmt {
index 60eec25bcf1b8d7e42db0fa634ac4de33304ffbf..b697c243c7c26067ec8dc10bee6d7bc55f58d573 100644 (file)
@@ -305,7 +305,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
 
 // 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.
+       key = rangeConvert(n, n.Key.Type(), key, n.KeyTypeWord, n.KeySrcRType)
        return ir.NewAssignStmt(n.Pos(), n.Key, key)
 }
 
@@ -313,10 +313,26 @@ func rangeAssign(n *ir.RangeStmt, key ir.Node) ir.Node {
 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.
+       key = rangeConvert(n, n.Key.Type(), key, n.KeyTypeWord, n.KeySrcRType)
+       value = rangeConvert(n, n.Value.Type(), value, n.ValueTypeWord, n.ValueSrcRType)
        return ir.NewAssignListStmt(n.Pos(), ir.OAS2, []ir.Node{n.Key, n.Value}, []ir.Node{key, value})
 }
 
+// rangeConvert returns src, converted to dst if necessary. If a
+// conversion is necessary, then typeWord and srcRType are copied to
+// their respective ConvExpr fields.
+func rangeConvert(nrange *ir.RangeStmt, dst *types.Type, src, typeWord, srcRType ir.Node) ir.Node {
+       src = typecheck.Expr(src)
+       if dst.Kind() == types.TBLANK || types.Identical(dst, src.Type()) {
+               return src
+       }
+
+       n := ir.NewConvExpr(nrange.Pos(), ir.OCONV, dst, src)
+       n.TypeWord = typeWord
+       n.SrcRType = srcRType
+       return typecheck.Expr(n)
+}
+
 // isMapClear checks if n is of the form:
 //
 //     for k := range m {