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,
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)
// 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{}
// 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)
}
}
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())
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 {