For example, internal/abi.(*SwissMapType).NeedKeyUpdate. It has a 3-instruction body and gets inlined everywhere. There is no reference to it from any code. But it still exists in the binary. Probably this is because it is exported (starts with a capital letter), and the type *SwissMapType is reachable somehow.

Kind of anecdotal at the moment, but this may be the cause of part of the binary size increase since 1.23.

@cherrymui

A few other examples:

internal/chacha8rand.(*State).Next
sync.(*noCopy).Lock

Comment From: thanm

Interesting problem. Output from "-ldflags=-dumpdep" seems to say

type:*internal/abi.SwissMapType <UsedInIface> -> internal/abi.(*SwissMapType).NeedKeyUpdate

I wonder if we need a new "only exported within the runtime" flavor of "exported".

Comment From: rsc

It would be easy to change cmd/compile/internal/noder/lex.go to respect //go:nointerface in runtime packages, and then mark the methods with //go:nointerface.

Comment From: rsc

(Or we could try to figure out why SwissMapType is used in an interface.)

Comment From: randall77

It would be easy to change cmd/compile/internal/noder/lex.go to respect //go:nointerface in runtime packages, and then mark the methods with //go:nointerface.

Sure, I just worry that

  • There might be a lot of them
  • People will forget to add that annotation as new methods/types are added

Comment From: rsc

We could also try making all the runtime packages nointerface by default and see what breaks. :-)

Comment From: nightlyone

Or turn it from method into a function if it never needs to satisfy any interface.