]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile: start setting RType fields for Unified IR
authorMatthew Dempsky <mdempsky@google.com>
Tue, 21 Jun 2022 07:57:18 +0000 (00:57 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 23 Jun 2022 21:52:45 +0000 (21:52 +0000)
This CL switches the GOEXPERIMENT=unified frontend to set RType fields
in the simpler cases, and to make it fatal if they're missing.

Subsequent CLs will handle the remaining more complex cases (e.g.,
expressions from later desugaring, and implicit conversions to
interface type).

Change-Id: If6257dcb3916905afd9b8371ea64b85f108ebbfb
Reviewed-on: https://go-review.googlesource.com/c/go/+/413359
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/reflectdata/helpers.go

index 5ebc776605f5783421e71cfd5188db9197f51f00..7588e52d96032178f53b840c86d9085efc4e0a46 100644 (file)
@@ -1390,6 +1390,9 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
                r.closeAnotherScope()
 
                rang := ir.NewRangeStmt(pos, nil, nil, x, body)
+               if x.Type().IsMap() {
+                       rang.RType = reflectdata.TypePtrAt(pos, x.Type())
+               }
                if len(lhs) >= 1 {
                        rang.Key = lhs[0]
                        if len(lhs) >= 2 {
@@ -1632,7 +1635,13 @@ func (r *reader) expr() (res ir.Node) {
                x := r.expr()
                pos := r.pos()
                index := r.expr()
-               return typecheck.Expr(ir.NewIndexExpr(pos, x, index))
+               n := typecheck.Expr(ir.NewIndexExpr(pos, x, index))
+               switch n.Op() {
+               case ir.OINDEXMAP:
+                       n := n.(*ir.IndexExpr)
+                       n.RType = reflectdata.TypePtrAt(pos, x.Type())
+               }
+               return n
 
        case exprSlice:
                x := r.expr()
@@ -1654,6 +1663,7 @@ func (r *reader) expr() (res ir.Node) {
 
                if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
                        assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
+                       assert.SrcRType = reflectdata.TypePtrAt(pos, x.Type())
                        assert.ITab = typ.ITab
                        return typed(typ.Type(), assert)
                }
@@ -1682,7 +1692,19 @@ func (r *reader) expr() (res ir.Node) {
                case ir.OANDAND, ir.OOROR:
                        return typecheck.Expr(ir.NewLogicalExpr(pos, op, x, y))
                }
-               return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
+               n := typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
+               switch n.Op() {
+               case ir.OEQ, ir.ONE:
+                       n := n.(*ir.BinaryExpr)
+                       if n.X.Type().IsInterface() != n.Y.Type().IsInterface() {
+                               typ := n.X.Type()
+                               if typ.IsInterface() {
+                                       typ = n.Y.Type()
+                               }
+                               n.RType = reflectdata.TypePtrAt(pos, typ)
+                       }
+               }
+               return n
 
        case exprCall:
                fun := r.expr()
@@ -1694,13 +1716,37 @@ func (r *reader) expr() (res ir.Node) {
                pos := r.pos()
                args := r.exprs()
                dots := r.Bool()
-               return typecheck.Call(pos, fun, args, dots)
+               n := typecheck.Call(pos, fun, args, dots)
+               switch n.Op() {
+               case ir.OAPPEND:
+                       n := n.(*ir.CallExpr)
+                       n.RType = reflectdata.TypePtrAt(pos, n.Type().Elem())
+               case ir.OCOPY:
+                       n := n.(*ir.BinaryExpr)
+                       n.RType = reflectdata.TypePtrAt(pos, n.X.Type().Elem())
+               case ir.ODELETE:
+                       n := n.(*ir.CallExpr)
+                       n.RType = reflectdata.TypePtrAt(pos, n.Args[0].Type())
+               case ir.OUNSAFESLICE:
+                       n := n.(*ir.BinaryExpr)
+                       n.RType = reflectdata.TypePtrAt(pos, n.Type().Elem())
+               }
+               return n
 
        case exprMake:
                pos := r.pos()
                typ := r.exprType(false)
                extra := r.exprs()
-               return typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...)))
+               n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
+               switch n.Op() {
+               case ir.OMAKECHAN:
+                       n.RType = reflectdata.TypePtrAt(pos, typ.Type())
+               case ir.OMAKEMAP:
+                       n.RType = reflectdata.TypePtrAt(pos, typ.Type())
+               case ir.OMAKESLICE:
+                       n.RType = reflectdata.TypePtrAt(pos, typ.Type().Elem())
+               }
+               return n
 
        case exprNew:
                pos := r.pos()
index 4d85dea74daa9a184b79576d04ea723054294230..22431a2bcb4c2fb1f29bca431366d59fe3e54c89 100644 (file)
@@ -71,7 +71,7 @@ func concreteRType(pos src.XPos, typ *types.Type) ir.Node {
 // representing the result slice type's element type.
 func AppendElemRType(pos src.XPos, n *ir.CallExpr) ir.Node {
        assertOp(n, ir.OAPPEND)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return sliceElemRType(pos, n.Type())
@@ -84,6 +84,8 @@ func AppendElemRType(pos src.XPos, n *ir.CallExpr) ir.Node {
 func CompareRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
        assertOp2(n, ir.OEQ, ir.ONE)
        base.AssertfAt(n.X.Type().IsInterface() != n.Y.Type().IsInterface(), n.Pos(), "expect mixed interface and non-interface, have %L and %L", n.X, n.Y)
+       // TODO(mdempsky): Need to propagate RType from OSWITCH/OCASE
+       // clauses to emitted OEQ nodes.
        if haveRType(n, n.RType, "RType", false) {
                return n.RType
        }
@@ -105,6 +107,7 @@ func ConvIfaceTypeWord(pos src.XPos, n *ir.ConvExpr) ir.Node {
        assertOp(n, ir.OCONVIFACE)
        src, dst := n.X.Type(), n.Type()
        base.AssertfAt(dst.IsInterface(), n.Pos(), "want interface type, have %L", n)
+       // TODO(mdempsky): Need to handle implicit interface conversions.
        if haveRType(n, n.TypeWord, "TypeWord", false) {
                return n.TypeWord
        }
@@ -123,6 +126,7 @@ func ConvIfaceTypeWord(pos src.XPos, n *ir.ConvExpr) ir.Node {
 // the convertee value to the heap.
 func ConvIfaceSrcRType(pos src.XPos, n *ir.ConvExpr) ir.Node {
        assertOp2(n, ir.OCONVIFACE, ir.OCONVIDATA)
+       // TODO(mdempsky): Need to handle implicit interface conversions.
        if haveRType(n, n.SrcRType, "SrcRType", false) {
                return n.SrcRType
        }
@@ -134,7 +138,7 @@ func ConvIfaceSrcRType(pos src.XPos, n *ir.ConvExpr) ir.Node {
 // destination slice type's element type.
 func CopyElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
        assertOp(n, ir.OCOPY)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return sliceElemRType(pos, n.X.Type())
@@ -145,7 +149,7 @@ func CopyElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
 // map type.
 func DeleteMapRType(pos src.XPos, n *ir.CallExpr) ir.Node {
        assertOp(n, ir.ODELETE)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return mapRType(pos, n.Args[0].Type())
@@ -156,6 +160,8 @@ func DeleteMapRType(pos src.XPos, n *ir.CallExpr) ir.Node {
 // map type.
 func IndexMapRType(pos src.XPos, n *ir.IndexExpr) ir.Node {
        assertOp(n, ir.OINDEXMAP)
+       // TODO(mdempsky): Need to propagate RType from OMAPLIT nodes to
+       // emitted OINDEXMAP nodes.
        if haveRType(n, n.RType, "RType", false) {
                return n.RType
        }
@@ -167,7 +173,7 @@ func IndexMapRType(pos src.XPos, n *ir.IndexExpr) ir.Node {
 // value representing that channel type.
 func MakeChanRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
        assertOp(n, ir.OMAKECHAN)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return chanRType(pos, n.Type())
@@ -178,6 +184,8 @@ func MakeChanRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
 // representing that map type.
 func MakeMapRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
        assertOp(n, ir.OMAKEMAP)
+       // TODO(mdempsky): Need to propagate RType from OMAPLIT nodes to
+       // emitted OMAKEMAP nodes.
        if haveRType(n, n.RType, "RType", false) {
                return n.RType
        }
@@ -189,7 +197,7 @@ func MakeMapRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
 // value representing that slice type's element type.
 func MakeSliceElemRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
        assertOp2(n, ir.OMAKESLICE, ir.OMAKESLICECOPY)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return sliceElemRType(pos, n.Type())
@@ -200,7 +208,7 @@ func MakeSliceElemRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
 // representing that map type.
 func RangeMapRType(pos src.XPos, n *ir.RangeStmt) ir.Node {
        assertOp(n, ir.ORANGE)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return mapRType(pos, n.X.Type())
@@ -211,7 +219,7 @@ func RangeMapRType(pos src.XPos, n *ir.RangeStmt) ir.Node {
 // representing the result slice type's element type.
 func UnsafeSliceElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
        assertOp(n, ir.OUNSAFESLICE)
-       if haveRType(n, n.RType, "RType", false) {
+       if haveRType(n, n.RType, "RType", true) {
                return n.RType
        }
        return sliceElemRType(pos, n.Type())