compiler: fix hasMethodSet to account for filtered generic methods

hasMethodSet was computed from the raw, unfiltered method set length
(ms.Len() != 0), before generic methods were excluded from numMethods
and the method set value. For a type whose only method is generic
(e.g. "func (t T) M[X int](n X) X"), this left hasMethodSet true even
though the actual (filtered) method set is empty, causing an
unnecessary empty method-set global and methodSet field to be emitted
for that type's type descriptor.

Compute hasMethodSet from the same filtered loop that produces
numMethods, so it's true only when at least one non-generic method
exists.
This commit is contained in:
Damian Gryski
2026-07-22 13:19:55 -07:00
committed by Ron Evans
parent 4fcf03414c
commit 1e3baff966
+5 -4
View File
@@ -155,25 +155,26 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
typ = types.Unalias(typ)
ms := c.program.MethodSets.MethodSet(typ)
hasMethodSet := ms.Len() != 0
_, isInterface := typ.Underlying().(*types.Interface)
if isInterface {
hasMethodSet = false
}
// As defined in https://pkg.go.dev/reflect#Type:
// NumMethod returns the number of methods accessible using Method.
// For a non-interface type, it returns the number of exported methods.
// For an interface type, it returns the number of exported and unexported methods.
var numMethods int
var hasMethodSet bool
for method := range ms.Methods() {
if isGenericMethod(method.Obj().(*types.Func)) {
continue
}
hasMethodSet = true
if isInterface || method.Obj().Exported() {
numMethods++
}
}
if isInterface {
hasMethodSet = false
}
// Short-circuit all the global pointer logic here for pointers to pointers.
if typ, ok := typ.(*types.Pointer); ok {