mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user