go:S1186 "Functions should not be empty": allow self-documented exceptions

I have a small request for this rule - which seems to have a high false-positive rate for various use cases (anecdotal ~90% IME); in this image below it’s a fallback interface-maintaining definition:

Could the rule account for standard naming idioms that already signal intent - e.g. a function prefixed noop/Noop (as in noopAttemptDone above), or a method on a receiver whose type is prefixed Unimplemented?


I know we can also disable the rule, but I’d rather not - that would also hide the occasional real case where someone forgets to implement or document an empty function.

Hello @andy-super

Welcome to the community and thank you for your report!

Could you provide us a few real life examples where you need to implement no-op functions, please? We would like to understand your cases better and provide more accurate solution based on your cases. In Go there is no standard way how to define/mark no-op functions so we need more context here.

Best
Marcin Stachniuk

We use this pattern across several Go interfaces: a type prefixed Noop/noop (also Fake, Disabled in a few places) implements an interface where each method body is intentionally empty. The empty body is the implementation, not a stub someone forgot to fill in.

Some examples:

type noopMonitor struct{}

func (noopMonitor) OnOperation(string) func(error) {
      return func(error) {}
}

func (noopMonitor) OnAuthToken(string) func(error) {
      return func(error) {}
}

func (NoopEmitter) Emit(context.Context, Recipe) {}

func (DisabledSyncer) UpdateSchedule(_ context.Context, _ contract.RetailShop) error {
      return nil
}

func (t *fakeTicker) Stop() {}

We also have some examples where a comment was added purely to satisfy this rule:

// Sonar requires explicit acknowledgement that the empty body is deliberate.
func (noopLogger) Debug(string, map[string]any) { /* no-op */ }
func (noopLogger) Info(string, map[string]any)  { /* no-op */ }
func (noopLogger) Warn(string, map[string]any)  { /* no-op */ }
func (noopLogger) Error(string, map[string]any) { /* no-op */ }

The type name already says everything the comment would say.

It’d help if the rule recognized receiver/type names matching a common “intentionally empty” convention (Noop/NoOp/no_op, Fake, Disabled, Stub, etc.) as self-documenting, or let a project configure such a naming pattern as an exemption, rather than forcing an ignore-comment on every occurrence.