]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: introduce OCONVIDATA op
authorKeith Randall <khr@golang.org>
Sat, 24 Jul 2021 01:10:58 +0000 (18:10 -0700)
committerKeith Randall <khr@golang.org>
Sat, 24 Jul 2021 15:57:01 +0000 (15:57 +0000)
This operation computes just the data field needed to put its argument
into an interface. Used by generics because we produce the type field
of an interface using dictionaries (instead of statically).

With this operation defined, we can now assert that shape types
are never marked as used in interfaces (the only previous use
was IDATA(CONVIFACE(t))).

Change-Id: Idb1eb5f3b238285cb99413d382599c0621b7681a
Reviewed-on: https://go-review.googlesource.com/c/go/+/337109
Trust: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
13 files changed:
src/cmd/compile/internal/escape/expr.go
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/fmt.go
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/ir/op_string.go
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/typecheck/iexport.go
src/cmd/compile/internal/typecheck/iimport.go
src/cmd/compile/internal/walk/assign.go
src/cmd/compile/internal/walk/convert.go
src/cmd/compile/internal/walk/expr.go
src/cmd/compile/internal/walk/order.go

index 60b44fe0aa6437a588205b1100743fd9b667e5c5..b7423e114ade7c5aac28baf86b4d24a101b6a9b6 100644 (file)
@@ -109,7 +109,7 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
                } else {
                        e.expr(k, n.X)
                }
-       case ir.OCONVIFACE:
+       case ir.OCONVIFACE, ir.OCONVIDATA:
                n := n.(*ir.ConvExpr)
                if !n.X.Type().IsInterface() && !types.IsDirectIface(n.X.Type()) {
                        k = e.spill(k, n)
index 09d6d87f0603943fdb191e250678460ff57fac65..86323e6b8f86e0d92ce1d21701da39cf44ace939 100644 (file)
@@ -270,7 +270,7 @@ func (n *ConvExpr) SetOp(op Op) {
        switch op {
        default:
                panic(n.no("SetOp " + op.String()))
-       case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
+       case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
                n.op = op
        }
 }
index e8dd9df69d04a6fa48d284dd081e7e52beb09a73..3c5a928590f2a54f5751cf5b7ba152e838f1d659 100644 (file)
@@ -185,6 +185,7 @@ var OpPrec = []int{
        OCLOSE:         8,
        OCOMPLIT:       8,
        OCONVIFACE:     8,
+       OCONVIDATA:     8,
        OCONVNOP:       8,
        OCONV:          8,
        OCOPY:          8,
@@ -546,7 +547,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
                                n = nn.X
                                continue
                        }
-               case OCONV, OCONVNOP, OCONVIFACE:
+               case OCONV, OCONVNOP, OCONVIFACE, OCONVIDATA:
                        nn := nn.(*ConvExpr)
                        if nn.Implicit() {
                                n = nn.X
@@ -813,6 +814,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
 
        case OCONV,
                OCONVIFACE,
+               OCONVIDATA,
                OCONVNOP,
                OBYTES2STR,
                ORUNES2STR,
index f6eae58b040c7e0b2db9be8a6f49e4ba2b99595b..0fbc867c1d93206a830825668b4e477123e331e8 100644 (file)
@@ -170,6 +170,7 @@ const (
        OPTRLIT    // &X (X is composite literal)
        OCONV      // Type(X) (type conversion)
        OCONVIFACE // Type(X) (type conversion, to interface)
+       OCONVIDATA // Builds a data word to store X in an interface. Equivalent to IDATA(CONVIFACE(X)). Is an ir.ConvExpr.
        OCONVNOP   // Type(X) (type conversion, no effect)
        OCOPY      // copy(X, Y)
        ODCL       // var X (declares X of type X.Type)
index 05a37a60b1d853a1648d63ee4cf0bca0356ef9f2..0235d5eab39a6c870a7bab425ca1eb6b134cb797 100644 (file)
@@ -52,125 +52,126 @@ func _() {
        _ = x[OPTRLIT-41]
        _ = x[OCONV-42]
        _ = x[OCONVIFACE-43]
-       _ = x[OCONVNOP-44]
-       _ = x[OCOPY-45]
-       _ = x[ODCL-46]
-       _ = x[ODCLFUNC-47]
-       _ = x[ODCLCONST-48]
-       _ = x[ODCLTYPE-49]
-       _ = x[ODELETE-50]
-       _ = x[ODOT-51]
-       _ = x[ODOTPTR-52]
-       _ = x[ODOTMETH-53]
-       _ = x[ODOTINTER-54]
-       _ = x[OXDOT-55]
-       _ = x[ODOTTYPE-56]
-       _ = x[ODOTTYPE2-57]
-       _ = x[OEQ-58]
-       _ = x[ONE-59]
-       _ = x[OLT-60]
-       _ = x[OLE-61]
-       _ = x[OGE-62]
-       _ = x[OGT-63]
-       _ = x[ODEREF-64]
-       _ = x[OINDEX-65]
-       _ = x[OINDEXMAP-66]
-       _ = x[OKEY-67]
-       _ = x[OSTRUCTKEY-68]
-       _ = x[OLEN-69]
-       _ = x[OMAKE-70]
-       _ = x[OMAKECHAN-71]
-       _ = x[OMAKEMAP-72]
-       _ = x[OMAKESLICE-73]
-       _ = x[OMAKESLICECOPY-74]
-       _ = x[OMUL-75]
-       _ = x[ODIV-76]
-       _ = x[OMOD-77]
-       _ = x[OLSH-78]
-       _ = x[ORSH-79]
-       _ = x[OAND-80]
-       _ = x[OANDNOT-81]
-       _ = x[ONEW-82]
-       _ = x[ONOT-83]
-       _ = x[OBITNOT-84]
-       _ = x[OPLUS-85]
-       _ = x[ONEG-86]
-       _ = x[OOROR-87]
-       _ = x[OPANIC-88]
-       _ = x[OPRINT-89]
-       _ = x[OPRINTN-90]
-       _ = x[OPAREN-91]
-       _ = x[OSEND-92]
-       _ = x[OSLICE-93]
-       _ = x[OSLICEARR-94]
-       _ = x[OSLICESTR-95]
-       _ = x[OSLICE3-96]
-       _ = x[OSLICE3ARR-97]
-       _ = x[OSLICEHEADER-98]
-       _ = x[ORECOVER-99]
-       _ = x[ORECOVERFP-100]
-       _ = x[ORECV-101]
-       _ = x[ORUNESTR-102]
-       _ = x[OSELRECV2-103]
-       _ = x[OIOTA-104]
-       _ = x[OREAL-105]
-       _ = x[OIMAG-106]
-       _ = x[OCOMPLEX-107]
-       _ = x[OALIGNOF-108]
-       _ = x[OOFFSETOF-109]
-       _ = x[OSIZEOF-110]
-       _ = x[OUNSAFEADD-111]
-       _ = x[OUNSAFESLICE-112]
-       _ = x[OMETHEXPR-113]
-       _ = x[OMETHVALUE-114]
-       _ = x[OBLOCK-115]
-       _ = x[OBREAK-116]
-       _ = x[OCASE-117]
-       _ = x[OCONTINUE-118]
-       _ = x[ODEFER-119]
-       _ = x[OFALL-120]
-       _ = x[OFOR-121]
-       _ = x[OFORUNTIL-122]
-       _ = x[OGOTO-123]
-       _ = x[OIF-124]
-       _ = x[OLABEL-125]
-       _ = x[OGO-126]
-       _ = x[ORANGE-127]
-       _ = x[ORETURN-128]
-       _ = x[OSELECT-129]
-       _ = x[OSWITCH-130]
-       _ = x[OTYPESW-131]
-       _ = x[OFUNCINST-132]
-       _ = x[OTCHAN-133]
-       _ = x[OTMAP-134]
-       _ = x[OTSTRUCT-135]
-       _ = x[OTINTER-136]
-       _ = x[OTFUNC-137]
-       _ = x[OTARRAY-138]
-       _ = x[OTSLICE-139]
-       _ = x[OINLCALL-140]
-       _ = x[OEFACE-141]
-       _ = x[OITAB-142]
-       _ = x[OIDATA-143]
-       _ = x[OSPTR-144]
-       _ = x[OCFUNC-145]
-       _ = x[OCHECKNIL-146]
-       _ = x[OVARDEF-147]
-       _ = x[OVARKILL-148]
-       _ = x[OVARLIVE-149]
-       _ = x[ORESULT-150]
-       _ = x[OINLMARK-151]
-       _ = x[OLINKSYMOFFSET-152]
-       _ = x[OTAILCALL-153]
-       _ = x[OGETG-154]
-       _ = x[OGETCALLERPC-155]
-       _ = x[OGETCALLERSP-156]
-       _ = x[OEND-157]
+       _ = x[OCONVIDATA-44]
+       _ = x[OCONVNOP-45]
+       _ = x[OCOPY-46]
+       _ = x[ODCL-47]
+       _ = x[ODCLFUNC-48]
+       _ = x[ODCLCONST-49]
+       _ = x[ODCLTYPE-50]
+       _ = x[ODELETE-51]
+       _ = x[ODOT-52]
+       _ = x[ODOTPTR-53]
+       _ = x[ODOTMETH-54]
+       _ = x[ODOTINTER-55]
+       _ = x[OXDOT-56]
+       _ = x[ODOTTYPE-57]
+       _ = x[ODOTTYPE2-58]
+       _ = x[OEQ-59]
+       _ = x[ONE-60]
+       _ = x[OLT-61]
+       _ = x[OLE-62]
+       _ = x[OGE-63]
+       _ = x[OGT-64]
+       _ = x[ODEREF-65]
+       _ = x[OINDEX-66]
+       _ = x[OINDEXMAP-67]
+       _ = x[OKEY-68]
+       _ = x[OSTRUCTKEY-69]
+       _ = x[OLEN-70]
+       _ = x[OMAKE-71]
+       _ = x[OMAKECHAN-72]
+       _ = x[OMAKEMAP-73]
+       _ = x[OMAKESLICE-74]
+       _ = x[OMAKESLICECOPY-75]
+       _ = x[OMUL-76]
+       _ = x[ODIV-77]
+       _ = x[OMOD-78]
+       _ = x[OLSH-79]
+       _ = x[ORSH-80]
+       _ = x[OAND-81]
+       _ = x[OANDNOT-82]
+       _ = x[ONEW-83]
+       _ = x[ONOT-84]
+       _ = x[OBITNOT-85]
+       _ = x[OPLUS-86]
+       _ = x[ONEG-87]
+       _ = x[OOROR-88]
+       _ = x[OPANIC-89]
+       _ = x[OPRINT-90]
+       _ = x[OPRINTN-91]
+       _ = x[OPAREN-92]
+       _ = x[OSEND-93]
+       _ = x[OSLICE-94]
+       _ = x[OSLICEARR-95]
+       _ = x[OSLICESTR-96]
+       _ = x[OSLICE3-97]
+       _ = x[OSLICE3ARR-98]
+       _ = x[OSLICEHEADER-99]
+       _ = x[ORECOVER-100]
+       _ = x[ORECOVERFP-101]
+       _ = x[ORECV-102]
+       _ = x[ORUNESTR-103]
+       _ = x[OSELRECV2-104]
+       _ = x[OIOTA-105]
+       _ = x[OREAL-106]
+       _ = x[OIMAG-107]
+       _ = x[OCOMPLEX-108]
+       _ = x[OALIGNOF-109]
+       _ = x[OOFFSETOF-110]
+       _ = x[OSIZEOF-111]
+       _ = x[OUNSAFEADD-112]
+       _ = x[OUNSAFESLICE-113]
+       _ = x[OMETHEXPR-114]
+       _ = x[OMETHVALUE-115]
+       _ = x[OBLOCK-116]
+       _ = x[OBREAK-117]
+       _ = x[OCASE-118]
+       _ = x[OCONTINUE-119]
+       _ = x[ODEFER-120]
+       _ = x[OFALL-121]
+       _ = x[OFOR-122]
+       _ = x[OFORUNTIL-123]
+       _ = x[OGOTO-124]
+       _ = x[OIF-125]
+       _ = x[OLABEL-126]
+       _ = x[OGO-127]
+       _ = x[ORANGE-128]
+       _ = x[ORETURN-129]
+       _ = x[OSELECT-130]
+       _ = x[OSWITCH-131]
+       _ = x[OTYPESW-132]
+       _ = x[OFUNCINST-133]
+       _ = x[OTCHAN-134]
+       _ = x[OTMAP-135]
+       _ = x[OTSTRUCT-136]
+       _ = x[OTINTER-137]
+       _ = x[OTFUNC-138]
+       _ = x[OTARRAY-139]
+       _ = x[OTSLICE-140]
+       _ = x[OINLCALL-141]
+       _ = x[OEFACE-142]
+       _ = x[OITAB-143]
+       _ = x[OIDATA-144]
+       _ = x[OSPTR-145]
+       _ = x[OCFUNC-146]
+       _ = x[OCHECKNIL-147]
+       _ = x[OVARDEF-148]
+       _ = x[OVARKILL-149]
+       _ = x[OVARLIVE-150]
+       _ = x[ORESULT-151]
+       _ = x[OINLMARK-152]
+       _ = x[OLINKSYMOFFSET-153]
+       _ = x[OTAILCALL-154]
+       _ = x[OGETG-155]
+       _ = x[OGETCALLERPC-156]
+       _ = x[OGETCALLERSP-157]
+       _ = x[OEND-158]
 }
 
-const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGGETCALLERPCGETCALLERSPEND"
+const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGGETCALLERPCGETCALLERSPEND"
 
-var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 136, 138, 141, 151, 158, 165, 172, 176, 180, 188, 196, 205, 208, 213, 220, 227, 233, 242, 250, 258, 264, 268, 277, 284, 288, 291, 298, 306, 313, 319, 322, 328, 335, 343, 347, 354, 362, 364, 366, 368, 370, 372, 374, 379, 384, 392, 395, 404, 407, 411, 419, 426, 435, 448, 451, 454, 457, 460, 463, 466, 472, 475, 478, 484, 488, 491, 495, 500, 505, 511, 516, 520, 525, 533, 541, 547, 556, 567, 574, 583, 587, 594, 602, 606, 610, 614, 621, 628, 636, 642, 651, 662, 670, 679, 684, 689, 693, 701, 706, 710, 713, 721, 725, 727, 732, 734, 739, 745, 751, 757, 763, 771, 776, 780, 787, 793, 798, 804, 810, 817, 822, 826, 831, 835, 840, 848, 854, 861, 868, 874, 881, 894, 902, 906, 917, 928, 931}
+var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 136, 138, 141, 151, 158, 165, 172, 176, 180, 188, 196, 205, 208, 213, 220, 227, 233, 242, 250, 258, 264, 268, 277, 286, 293, 297, 300, 307, 315, 322, 328, 331, 337, 344, 352, 356, 363, 371, 373, 375, 377, 379, 381, 383, 388, 393, 401, 404, 413, 416, 420, 428, 435, 444, 457, 460, 463, 466, 469, 472, 475, 481, 484, 487, 493, 497, 500, 504, 509, 514, 520, 525, 529, 534, 542, 550, 556, 565, 576, 583, 592, 596, 603, 611, 615, 619, 623, 630, 637, 645, 651, 660, 671, 679, 688, 693, 698, 702, 710, 715, 719, 722, 730, 734, 736, 741, 743, 748, 754, 760, 766, 772, 780, 785, 789, 796, 802, 807, 813, 819, 826, 831, 835, 840, 844, 849, 857, 863, 870, 877, 883, 890, 903, 911, 915, 926, 937, 940}
 
 func (i Op) String() string {
        if i >= Op(len(_Op_index)-1) {
index 85538f590dcf8ba0c8075595d9ea9d5a5d1a580e..e308dd7a05b788be6202b6d5fbb9daa130574a0c 100644 (file)
@@ -1461,24 +1461,18 @@ func (subst *subster) convertUsingDictionary(pos src.XPos, v ir.Node, gn ir.Node
                rt = subst.getDictionaryType(pos, ix)
        }
 
-       // Convert value to an interface type, so the data field is what we want.
-       if !v.Type().IsInterface() {
-               v = ir.NewConvExpr(v.Pos(), ir.OCONVIFACE, nil, v)
-               typed(types.NewInterface(types.LocalPkg, nil), v)
+       // Figure out what the data field of the interface will be.
+       var data ir.Node
+       if v.Type().IsInterface() {
+               data = ir.NewUnaryExpr(pos, ir.OIDATA, v)
+       } else {
+               data = ir.NewConvExpr(pos, ir.OCONVIDATA, nil, v)
        }
-
-       // At this point, v is an interface type with a data word we want.
-       // But the type word represents a gcshape type, which we don't want.
-       // Replace with the instantiated type loaded from the dictionary.
-       data := ir.NewUnaryExpr(pos, ir.OIDATA, v)
        typed(types.Types[types.TUNSAFEPTR], data)
+
+       // Build an interface from the type and data parts.
        var i ir.Node = ir.NewBinaryExpr(pos, ir.OEFACE, rt, data)
        typed(dst, i)
-       // TODO: we're throwing away the type word of the original version
-       // of m here (it would be OITAB(m)), which probably took some
-       // work to generate. Can we avoid generating it at all?
-       // (The linker will throw them away if not needed, so it would just
-       // save toolchain work, not binary size.)
        return i
 
 }
index 875d53b3cca4c1486119f8bcbfc24bc5c681ee8a..7eba5fb41e47cf984be2e93051eeb1b8d4c2efbb 100644 (file)
@@ -1983,10 +1983,8 @@ var ZeroSize int64
 // This information is used in the linker in dead method elimination.
 func MarkTypeUsedInInterface(t *types.Type, from *obj.LSym) {
        if t.HasShape() {
-               // TODO: shape types shouldn't be put in interfaces, so we shouldn't ever get here.
-               // We don't from ../noder/stencil.go, but we do from ../walk/walk.go when we let
-               // shape types become the types of interfaces.
-               //base.Fatalf("shape types have no methods %+v", t)
+               // Shape types shouldn't be put in interfaces, so we shouldn't ever get here.
+               base.Fatalf("shape types have no methods %+v", t)
        }
        tsym := TypeLinksym(t)
        // Emit a marker relocation. The linker will know the type is converted
index b054c73ad806cfd20596760e7e029505772a8a83..25a0bfbb3a4b0847c13ba922021d40deeb399bf0 100644 (file)
@@ -1873,7 +1873,7 @@ func (w *exportWriter) expr(n ir.Node) {
                        w.op(ir.OEND)
                }
 
-       case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
+       case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
                n := n.(*ir.ConvExpr)
                if go117ExportTypes {
                        w.op(n.Op())
index 9bef07b6365fbc8d1baae5e9ba574fae79d85a17..b389c7fcb079b3c2ee2497594206545d29147d6f 100644 (file)
@@ -1446,7 +1446,7 @@ func (r *importReader) node() ir.Node {
                }
                return n
 
-       case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
+       case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
                if !go117ExportTypes && op != ir.OCONV {
                        //      unreachable - mapped to OCONV case by exporter
                        goto error
index 6d697a53ae3aaa14442a21f9f4e15880bbfe75c2..d4c1aafdc121dcbb9226341618e94c0f1c6bc67f 100644 (file)
@@ -429,6 +429,7 @@ func readsMemory(n ir.Node) bool {
                ir.OBITNOT,
                ir.OCONV,
                ir.OCONVIFACE,
+               ir.OCONVIDATA,
                ir.OCONVNOP,
                ir.ODIV,
                ir.ODOT,
index e659ee59f1471a9d72d444821b256668ad1c5492..d15575f643c0d53a81aa6accedb2efd3b163fe41 100644 (file)
@@ -39,14 +39,22 @@ func walkConv(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
        return typecheck.Conv(mkcall(fn, types.Types[result], init, typecheck.Conv(n.X, types.Types[param])), n.Type())
 }
 
-// walkConvInterface walks an OCONVIFACE node.
+// walkConvInterface walks an OCONVIFACE or OCONVIDATA node.
 func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+
        n.X = walkExpr(n.X, init)
 
        fromType := n.X.Type()
        toType := n.Type()
-
-       if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _())
+       if n.Op() == ir.OCONVIDATA {
+               // Just convert to empty interface, to make it easy.
+               // The caller throws away the type word.
+               toType = types.NewInterface(types.LocalPkg, nil)
+               // Note: don't pass fromType to MarkTypeUsedInInterface because it is likely
+               // a shape type. The appropriate call to MarkTypeUsedInInterface will come
+               // when building the dictionary (from which the matching type word will come).
+       } else if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) {
+               // skip unnamed functions (func _())
                reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
        }
 
index eed6ef86c23eb173f20f86a05ef93e5a2b5b51ee..f0d37198d37278e677d7bd848d156f9b8fc3da5d 100644 (file)
@@ -206,6 +206,13 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
                n := n.(*ir.ConvExpr)
                return walkConvInterface(n, init)
 
+       case ir.OCONVIDATA:
+               n := n.(*ir.ConvExpr)
+               r := ir.NewUnaryExpr(n.Pos(), ir.OIDATA, walkConvInterface(n, init))
+               r.SetType(types.Types[types.TUNSAFEPTR])
+               r.SetTypecheck(1)
+               return r
+
        case ir.OCONV, ir.OCONVNOP:
                n := n.(*ir.ConvExpr)
                return walkConv(n, init)
index cd2bbcb73ba3381339b9edc3c190cfe8cec2e197..fe6ae3fda00982b5b6fec166b87712e0e1ec502e 100644 (file)
@@ -1156,16 +1156,20 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
 
        // concrete type (not interface) argument might need an addressable
        // temporary to pass to the runtime conversion routine.
-       case ir.OCONVIFACE:
+       case ir.OCONVIFACE, ir.OCONVIDATA:
                n := n.(*ir.ConvExpr)
                n.X = o.expr(n.X, nil)
                if n.X.Type().IsInterface() {
                        return n
                }
-               if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
+               to := n.Type()
+               if n.Op() == ir.OCONVIDATA {
+                       to = types.NewInterface(types.LocalPkg, nil)
+               }
+               if _, _, needsaddr := convFuncName(n.X.Type(), to); needsaddr || isStaticCompositeLiteral(n.X) {
                        // Need a temp if we need to pass the address to the conversion function.
                        // We also process static composite literal node here, making a named static global
-                       // whose address we can put directly in an interface (see OCONVIFACE case in walk).
+                       // whose address we can put directly in an interface (see OCONVIFACE/OCONVIDATA case in walk).
                        n.X = o.addrTemp(n.X)
                }
                return n