return t
}
+// markTypeUsed marks type t as used in order to help avoid dead-code elimination of
+// needed methods.
+func markTypeUsed(t *types.Type, lsym *obj.LSym) {
+ if t.IsInterface() {
+ // Mark all the methods of the interface as used.
+ // TODO: we should really only mark the interface methods
+ // that are actually called in the application.
+ for i, _ := range t.AllMethods().Slice() {
+ reflectdata.MarkUsedIfaceMethodIndex(lsym, t, i)
+ }
+ } else {
+ // TODO: This is somewhat overkill, we really only need it
+ // for types that are put into interfaces.
+ reflectdata.MarkTypeUsedInInterface(t, lsym)
+ }
+}
+
// getDictionarySym returns the dictionary for the named generic function gf, which
// is instantiated with the type arguments targs.
func (g *irgen) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool) *types.Sym {
infoPrint(" * %v\n", t)
s := reflectdata.TypeLinksym(t)
off = objw.SymPtr(lsym, off, s, 0)
- // Ensure that methods on t don't get deadcode eliminated
- // by the linker.
- // TODO: This is somewhat overkill, we really only need it
- // for types that are put into interfaces.
- reflectdata.MarkTypeUsedInInterface(t, lsym)
+ markTypeUsed(t, lsym)
}
subst := typecheck.Tsubster{
Tparams: info.tparams,
infoPrint(" - %v\n", ts)
s := reflectdata.TypeLinksym(ts)
off = objw.SymPtr(lsym, off, s, 0)
- reflectdata.MarkTypeUsedInInterface(ts, lsym)
+ markTypeUsed(ts, lsym)
}
// Emit an entry for each subdictionary (after substituting targs)
for _, n := range info.subDictCalls {
"fixedbugs/issue30862.go", // -G=3 doesn't handle //go:nointerface
- "typeparam/cons.go", // causes an unreachable method
"typeparam/nested.go", // -G=3 doesn't support function-local types with generics
"typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops