diff options
-rw-r--r-- | src/cmd/compile/internal/noder/stencil.go | 36 | ||||
-rw-r--r-- | src/cmd/compile/internal/reflectdata/reflect.go | 12 |
2 files changed, 28 insertions, 20 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index e308dd7a05..f1de1152c5 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -855,13 +855,9 @@ type subster struct { ts typecheck.Tsubster info *instInfo // Place to put extra info in the instantiation - // Which type parameter the shape type came from. - shape2param map[*types.Type]*types.Type - // unshapeify maps from shape types to the concrete types they represent. // TODO: remove when we no longer need it. - unshapify typecheck.Tsubster - concretify typecheck.Tsubster + unshapify typecheck.Tsubster // TODO: some sort of map from <shape type, interface type> to index in the // dictionary where a *runtime.itab for the corresponding <concrete type, @@ -920,23 +916,11 @@ func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, shapes, targs Targs: shapes, Vars: make(map[*ir.Name]*ir.Name), }, - shape2param: map[*types.Type]*types.Type{}, unshapify: typecheck.Tsubster{ Tparams: shapes, Targs: targs, Vars: make(map[*ir.Name]*ir.Name), }, - concretify: typecheck.Tsubster{ - Tparams: tparams, - Targs: targs, - Vars: make(map[*ir.Name]*ir.Name), - }, - } - for i := range shapes { - if !shapes[i].IsShape() { - panic("must be a shape type") - } - subst.shape2param[shapes[i]] = tparams[i] } newf.Dcl = make([]*ir.Name, 0, len(gf.Dcl)+1) @@ -992,7 +976,6 @@ func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, shapes, targs // g.instTypeList. g.instTypeList = append(g.instTypeList, subst.ts.InstTypeList...) g.instTypeList = append(g.instTypeList, subst.unshapify.InstTypeList...) - g.instTypeList = append(g.instTypeList, subst.concretify.InstTypeList...) if doubleCheck { okConvs := map[ir.Node]bool{} @@ -1258,7 +1241,10 @@ func (subst *subster) node(n ir.Node) ir.Node { // 1) convert x to the bound interface // 2) call M on that interface gsrc := x.(*ir.SelectorExpr).X.Type() - dst := subst.concretify.Typ(gsrc.Bound()) + dst := gsrc.Bound() + if dst.HasTParam() { + dst = subst.ts.Typ(dst) + } mse.X = subst.convertUsingDictionary(m.Pos(), mse.X, x, dst, gsrc) } } @@ -1714,6 +1700,18 @@ func (g *irgen) finalizeSyms() { se := n.(*ir.SelectorExpr) srctype = subst.Typ(se.X.Type()) dsttype = subst.Typ(se.X.Type().Bound()) + found := false + for i, m := range dsttype.AllMethods().Slice() { + if se.Sel == m.Sym { + // Mark that this method se.Sel is + // used for the dsttype interface, so + // it won't get deadcoded. + reflectdata.MarkUsedIfaceMethodIndex(lsym, dsttype, i) + found = true + break + } + } + assert(found) } else { assert(n.Op() == ir.OCONVIFACE) srctype = subst.Typ(n.(*ir.ConvExpr).X.Type()) diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index 7eba5fb41e..3bf248a7ad 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -2006,13 +2006,23 @@ func MarkUsedIfaceMethod(n *ir.CallExpr) { tsym := TypeLinksym(ityp) r := obj.Addrel(ir.CurFunc.LSym) r.Sym = tsym - // dot.Xoffset is the method index * PtrSize (the offset of code pointer + // dot.Offset() is the method index * PtrSize (the offset of code pointer // in itab). midx := dot.Offset() / int64(types.PtrSize) r.Add = InterfaceMethodOffset(ityp, midx) r.Type = objabi.R_USEIFACEMETHOD } +// MarkUsedIfaceMethodIndex marks that that method number ix (in the AllMethods list) +// of interface type ityp is used, and should be attached to lsym. +func MarkUsedIfaceMethodIndex(lsym *obj.LSym, ityp *types.Type, ix int) { + tsym := TypeLinksym(ityp) + r := obj.Addrel(lsym) + r.Sym = tsym + r.Add = InterfaceMethodOffset(ityp, int64(ix)) + r.Type = objabi.R_USEIFACEMETHOD +} + // getDictionary returns the dictionary for the given named generic function // or method, with the given type arguments. func getDictionary(gf *types.Sym, targs []*types.Type) ir.Node { |