Skip to content

Commit

Permalink
[dev.unified] cmd/compile/internal/walk: RType fields for range assig…
Browse files Browse the repository at this point in the history
…nments

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>
  • Loading branch information
mdempsky authored and gopherbot committed Jul 1, 2022
1 parent 1b838e9 commit d667be8
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/cmd/compile/internal/ir/stmt.go
Expand Up @@ -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 {
Expand Down
20 changes: 18 additions & 2 deletions src/cmd/compile/internal/walk/range.go
Expand Up @@ -305,18 +305,34 @@ 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)
}

// 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.
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 {
Expand Down

0 comments on commit d667be8

Please sign in to comment.