diff --git a/src/cmd/compile/internal/escape/expr.go b/src/cmd/compile/internal/escape/expr.go index 60b44fe0aa..b7423e114a 100644 --- a/src/cmd/compile/internal/escape/expr.go +++ b/src/cmd/compile/internal/escape/expr.go @@ -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) diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index 09d6d87f06..86323e6b8f 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -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 } } diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go index e8dd9df69d..3c5a928590 100644 --- a/src/cmd/compile/internal/ir/fmt.go +++ b/src/cmd/compile/internal/ir/fmt.go @@ -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, diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go index f6eae58b04..0fbc867c1d 100644 --- a/src/cmd/compile/internal/ir/node.go +++ b/src/cmd/compile/internal/ir/node.go @@ -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) diff --git a/src/cmd/compile/internal/ir/op_string.go b/src/cmd/compile/internal/ir/op_string.go index 05a37a60b1..0235d5eab3 100644 --- a/src/cmd/compile/internal/ir/op_string.go +++ b/src/cmd/compile/internal/ir/op_string.go @@ -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) { diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index 85538f590d..e308dd7a05 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -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 } diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index 875d53b3cc..7eba5fb41e 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -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 diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go index b054c73ad8..25a0bfbb3a 100644 --- a/src/cmd/compile/internal/typecheck/iexport.go +++ b/src/cmd/compile/internal/typecheck/iexport.go @@ -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()) diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go index 9bef07b636..b389c7fcb0 100644 --- a/src/cmd/compile/internal/typecheck/iimport.go +++ b/src/cmd/compile/internal/typecheck/iimport.go @@ -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 diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go index 6d697a53ae..d4c1aafdc1 100644 --- a/src/cmd/compile/internal/walk/assign.go +++ b/src/cmd/compile/internal/walk/assign.go @@ -429,6 +429,7 @@ func readsMemory(n ir.Node) bool { ir.OBITNOT, ir.OCONV, ir.OCONVIFACE, + ir.OCONVIDATA, ir.OCONVNOP, ir.ODIV, ir.ODOT, diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go index e659ee59f1..d15575f643 100644 --- a/src/cmd/compile/internal/walk/convert.go +++ b/src/cmd/compile/internal/walk/convert.go @@ -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) } diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go index eed6ef86c2..f0d37198d3 100644 --- a/src/cmd/compile/internal/walk/expr.go +++ b/src/cmd/compile/internal/walk/expr.go @@ -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) diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go index cd2bbcb73b..fe6ae3fda0 100644 --- a/src/cmd/compile/internal/walk/order.go +++ b/src/cmd/compile/internal/walk/order.go @@ -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