aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/reader.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-06-30 17:58:47 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-07-19 23:07:20 +0000
commite376746e54aae4fb519f50bbe42656a2d34df285 (patch)
treef4a9c1355444fe909df2cd174324fd9a7d6d486b /src/cmd/compile/internal/noder/reader.go
parentc846fd8e136dce06b213cae1cf3b9ada423c078a (diff)
downloadgo-e376746e54aae4fb519f50bbe42656a2d34df285.tar.xz
[dev.unified] cmd/compile/internal/noder: wire RTTI for implicit conversions
This CL updates Unified IR to set the TypeWord and SrcRType fields on interface conversions, which will be necessary for dictionary support shortly. Change-Id: I9486b417f514ba4ec2ee8036194aa9ae3ad0ad93 Reviewed-on: https://go-review.googlesource.com/c/go/+/415575 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
-rw-r--r--src/cmd/compile/internal/noder/reader.go75
1 files changed, 70 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index d93859f6ef..6b47c11749 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -1399,6 +1399,18 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
}
rang.Def = r.initDefn(rang, names)
rang.Label = label
+
+ {
+ keyType, valueType := rangeTypes(pos, x.Type())
+
+ if rang.Key != nil {
+ rang.KeyTypeWord, rang.KeySrcRType = convRTTI(pos, rang.Key.Type(), keyType)
+ }
+ if rang.Value != nil {
+ rang.ValueTypeWord, rang.ValueSrcRType = convRTTI(pos, rang.Value.Type(), valueType)
+ }
+ }
+
return rang
}
@@ -1414,6 +1426,28 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
return stmt
}
+// rangeTypes returns the types of values produced by ranging over a
+// value of type typ.
+func rangeTypes(pos src.XPos, typ *types.Type) (key, value *types.Type) {
+ switch typ.Kind() {
+ default:
+ base.FatalfAt(pos, "unexpected range type: %v", typ)
+ panic("unreachable")
+ case types.TPTR: // must be pointer to array
+ typ = typ.Elem()
+ base.AssertfAt(typ.Kind() == types.TARRAY, pos, "want array type, have %v", typ)
+ fallthrough
+ case types.TARRAY, types.TSLICE:
+ return types.Types[types.TINT], typ.Elem()
+ case types.TSTRING:
+ return types.Types[types.TINT], types.RuneType
+ case types.TMAP:
+ return typ.Key(), typ.Elem()
+ case types.TCHAN:
+ return typ.Elem(), nil
+ }
+}
+
func (r *reader) ifStmt() ir.Node {
r.Sync(pkgbits.SyncIfStmt)
r.openScope()
@@ -1803,14 +1837,42 @@ func (r *reader) expr() (res ir.Node) {
base.ErrorExit() // harsh, but prevents constructing invalid IR
}
- n := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONV, typ, x))
- if implicit && n.Op() != ir.OLITERAL {
- n.(ImplicitNode).SetImplicit(true)
+ n := ir.NewConvExpr(pos, ir.OCONV, typ, x)
+ n.TypeWord, n.SrcRType = convRTTI(pos, typ, x.Type())
+ if implicit {
+ n.SetImplicit(true)
}
- return n
+ return typecheck.Expr(n)
}
}
+// convRTTI returns the TypeWord and SrcRType expressions appropriate
+// for a conversion from src to dst.
+func convRTTI(pos src.XPos, dst, src *types.Type) (typeWord, srcRType ir.Node) {
+ if !dst.IsInterface() {
+ return
+ }
+
+ // See reflectdata.ConvIfaceTypeWord.
+ switch {
+ case dst.IsEmptyInterface():
+ if !src.IsInterface() {
+ typeWord = reflectdata.TypePtrAt(pos, src) // direct eface construction
+ }
+ case !src.IsInterface():
+ typeWord = reflectdata.ITabAddrAt(pos, src, dst) // direct iface construction
+ default:
+ typeWord = reflectdata.TypePtrAt(pos, dst) // convI2I
+ }
+
+ // See reflectdata.ConvIfaceSrcRType.
+ if !src.IsInterface() {
+ srcRType = reflectdata.TypePtrAt(pos, src)
+ }
+
+ return
+}
+
func (r *reader) optExpr() ir.Node {
if r.Bool() {
return r.expr()
@@ -1841,7 +1903,10 @@ func (r *reader) multiExpr() []ir.Node {
res := ir.Node(tmp)
if r.Bool() {
- res = typecheck.Expr(Implicit(ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)))
+ n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
+ n.TypeWord, n.SrcRType = convRTTI(pos, n.Type(), n.X.Type())
+ n.SetImplicit(true)
+ res = typecheck.Expr(n)
}
results[i] = res
}