From 409c9c750a6db95f7a9cf9517945c0c3ecd2ed4a Mon Sep 17 00:00:00 2001 From: Peter Stace Date: Fri, 13 Feb 2026 17:03:13 +1100 Subject: [PATCH] Disable ireturn linter The ireturn linter flags functions that return interfaces, based on the principle "accept interfaces, return concrete types." However, every instance where it fires in this codebase is a false positive: - catch[T any] in geom/util.go returns a generic type parameter T, which is always instantiated with concrete types (Geometry, string, bool, PreparedGeometry) at call sites. - GetLeaf and Cast[T] in internal/jtsport/java/polymorphic.go return the Polymorphic interface or a type parameter constrained by it, which is inherent to their purpose as polymorphism infrastructure. The public API of the geom package has zero exported interfaces and all public functions already return concrete types, so ireturn provides no protection against the problem it's designed to catch. Meanwhile, as more generic code is added, the false positive rate will only grow. Also clean up the now-unnecessary //nolint:ireturn directives, and clarify the comment in the linter config about moving linters between the enable and disable sections. --- .golangci.yaml | 7 ++++--- geom/util.go | 2 +- internal/jtsport/java/polymorphic.go | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index e98abd69..b172f73f 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -40,8 +40,9 @@ linters-settings: - (*github.com/peterstace/simplefeatures/rtree.RTree).RangeSearch - (*github.com/peterstace/simplefeatures/rtree.RTree).PrioritySearch -# NOTE: every linter supported by golangci-lint is either explicitly included -# or excluded. +# NOTE: every linter supported by golangci-lint is either explicitly enabled +# or disabled. When adding or removing a linter, move it between the two +# sections rather than just deleting it. linters: enable: @@ -81,7 +82,6 @@ linters: - importas - ineffassign - intrange - - ireturn - loggercheck - makezero - mirror @@ -145,6 +145,7 @@ linters: - gomnd - inamedparam - interfacebloat + - ireturn - lll - maintidx - nestif diff --git a/geom/util.go b/geom/util.go index aea4c3fc..e3a8767f 100644 --- a/geom/util.go +++ b/geom/util.go @@ -141,7 +141,7 @@ func arbitraryControlPoint(g Geometry) Point { } } -func catch[T any](fn func() (T, error)) (result T, err error) { //nolint:ireturn +func catch[T any](fn func() (T, error)) (result T, err error) { // In Go 1.21+, panic(nil) causes recover() to return a *runtime.PanicNilError // rather than nil. In earlier versions, recover() returns nil for panic(nil), // making it indistinguishable from "no panic". We emulate the Go 1.21+ behavior diff --git a/internal/jtsport/java/polymorphic.go b/internal/jtsport/java/polymorphic.go index b6c88892..a12b4746 100644 --- a/internal/jtsport/java/polymorphic.go +++ b/internal/jtsport/java/polymorphic.go @@ -12,7 +12,7 @@ type Polymorphic interface { // GetLeaf walks the child chain to find the leaf (concrete) type. This is used // by dispatchers to find the most-derived implementation of a method. -func GetLeaf(obj Polymorphic) Polymorphic { //nolint:ireturn +func GetLeaf(obj Polymorphic) Polymorphic { for { child := obj.GetChild() if child == nil { @@ -77,7 +77,7 @@ func InstanceOf[T any](obj Polymorphic) bool { // // Panics with a descriptive message if obj cannot be cast to T (equivalent to // Java's ClassCastException). -func Cast[T Polymorphic](obj Polymorphic) T { //nolint:ireturn +func Cast[T Polymorphic](obj Polymorphic) T { var zero T if obj == nil { panic(fmt.Sprintf("cannot cast nil to %T", zero))