Skip to content

fix: panic with defer inside for loop#50

Open
ldez wants to merge 1 commit intoryanrolds:mainfrom
golangci:fix/panic-unreachable
Open

fix: panic with defer inside for loop#50
ldez wants to merge 1 commit intoryanrolds:mainfrom
golangci:fix/panic-unreachable

Conversation

@ldez
Copy link
Copy Markdown

@ldez ldez commented Mar 29, 2026

$ sqlclosecheck ./...
panic: unreachable

goroutine 802 [running]:
go/types.(*comparer).identical(0x2413e9282af6, {0x866530?, 0xb31df0?}, {0x865e28?, 0x2413f1724080?}, 0x0)
        /usr/lib/go/src/go/types/predicates.go:497 +0x805
go/types.(*comparer).identical(0x2413e9282af6, {0x865e00?, 0xb31de0?}, {0x865e00?, 0x2413effb8e20?}, 0x0)
        /usr/lib/go/src/go/types/predicates.go:311 +0x6ff
go/types.Identical(...)
        /usr/lib/go/src/go/types/api_predicates.go:90
github.com/ryanrolds/sqlclosecheck/pkg/analyzer.getTargetTypesValues(0x2413effba880?, 0xb3bb20?, {0x2413edbb40c0, 0x3, 0x48341e?})
        sqlclosecheck/pkg/analyzer/defer_only.go:189 +0x1c5
github.com/ryanrolds/sqlclosecheck/pkg/analyzer.(*deferOnlyAnalyzer).Run(0x800200?, 0x2413ed9dbc00)
        sqlclosecheck/pkg/analyzer/defer_only.go:69 +0x19e
github.com/ryanrolds/sqlclosecheck/pkg/analyzer.run(0x7d78e0?)
        sqlclosecheck/pkg/analyzer/analyzer.go:19 +0x1b
golang.org/x/tools/go/analysis/checker.(*Action).execOnce.func3(...)
        sqlclosecheck/vendor/golang.org/x/tools/go/analysis/checker/checker.go:359
golang.org/x/tools/go/analysis/checker.(*Action).execOnce(0x2413f16a81e0)
        sqlclosecheck/vendor/golang.org/x/tools/go/analysis/checker/checker.go:380 +0xb9c
sync.(*Once).doSlow(0x2413f1a26900?, 0x6e1ee0?)
        /usr/lib/go/src/sync/once.go:78 +0xac
sync.(*Once).Do(...)
        /usr/lib/go/src/sync/once.go:69
golang.org/x/tools/go/analysis/checker.(*Action).exec(...)
        sqlclosecheck/vendor/golang.org/x/tools/go/analysis/checker/checker.go:258
golang.org/x/tools/go/analysis/checker.execAll.func1(0x2413ef7da798?)
        sqlclosecheck/vendor/golang.org/x/tools/go/analysis/checker/checker.go:246 +0x45
created by golang.org/x/tools/go/analysis/checker.execAll in goroutine 1
        sqlclosecheck/vendor/golang.org/x/tools/go/analysis/checker/checker.go:252 +0x147
Example
package main

import (
	"context"
	"database/sql"
	"fmt"
	"iter"
	"sync"
)

type db struct {
	mu      sync.Mutex
	remotes map[string]*sql.DB
}

func (db *db) All() iter.Seq2[string, *sql.DB] {
	return func(yield func(string, *sql.DB) bool) {
		db.mu.Lock()
		defer db.mu.Unlock()
		for addr, r := range db.remotes {
			if !yield(addr, r) {
				return
			}
		}
	}
}

func (db *db) Foo(ctx context.Context) error {
	for addr, rem := range db.All() {
		rconn, err := rem.Conn(context.Background())
		if err != nil {
			return err
		}
		defer rconn.Close()

		rows, err := rconn.QueryContext(ctx, `SELECT * FROM foo`)
		if err != nil {
			return err
		}
		defer rows.Close()
		for rows.Next() {
			fmt.Println(rows.ColumnTypes())
		}
		if err := rows.Err(); err != nil {
			return err
		}
		fmt.Println(addr, rconn.PingContext(context.Background()))
	}
	return nil
}

func main() {
	d := &db{remotes: make(map[string]*sql.DB)}
	fmt.Println(d.Foo(context.Background()))
}

Related to golangci/golangci-lint#6467

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant