deferargs

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2025 License: MIT Imports: 5 Imported by: 0

README

deferargs

deferargs is a static analysis tool to detect defer statements that call a function with variable arguments.
Since arguments in defer calls are evaluated immediately, passing variables may lead to unexpected behavior if their values change afterward.

Problem

In Go, the arguments to a defer call are evaluated at the point of the defer statement, not when the deferred function is executed.
This can cause subtle bugs when passing a variable whose value is expected to change later.

For example:

func fn() (err error) {
    defer dump(err) // ❗️ evaluated now (likely nil), not at the end
    err = errors.New("something failed")
    return
}

The call to dump(err) will receive nil, because err is evaluated at the point of the defer, before err is set.

Recommendation

To avoid this issue, wrap the call in a closure:

func f() (err error) {
    defer func() {
        dump(err) // ✅ evaluated at the time of execution
    }()
    err = errors.New("something failed")
    return
}

Detected Code

This tool reports defer statements where:

  • The deferred function is not an anonymous function (func() { ... })
  • At least one argument is a variable reference (x, obj.Field, etc.)
Reported:
defer fn(err)
defer close(ch)
defer logf("fail: %v", err)
Not Reported:
defer fn()                           // no arguments
defer fn(errors.New("boom"))        // function call
defer fn(nil)                       // literal
defer func() { fn(err) }()          // wrapped in closure

Installation

go install github.com/tkdn/deferargs/cmd/deferargs@latest

Usage

As go vet plugin (with staticcheck.io):
go vet -vettool=$(which deferargs) ./...
Standalone
deferargs ./...

License

MIT

Documentation

Index

Constants

View Source
const Version = "0.1.0"

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:     "deferargs",
	Doc:      "reports defer calls whose arguments are variable references (immediately evaluated)",
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
deferargs command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL