diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-06-30 17:58:47 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2022-07-19 23:07:20 +0000 |
| commit | e376746e54aae4fb519f50bbe42656a2d34df285 (patch) | |
| tree | f4a9c1355444fe909df2cd174324fd9a7d6d486b /src/cmd/compile/internal/noder/reader.go | |
| parent | c846fd8e136dce06b213cae1cf3b9ada423c078a (diff) | |
| download | go-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.go | 75 |
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 } |
