Skip to content

False positive "result is never used" when caller is inside a nested closure and two other callers discard the result #93

Description

@twz123

In the program below, newInstance returns two values. The *recorder result is used, in the innermost closure, but unparam reports:

$ go run mvdan.cc/unparam@v0.0.0-20260823230713-2fa3d841b0c8 .
main.go:15:34: main$1 - result 1 (*example.com/unparamrepro.recorder) is never used
exit status 1
// Using module example.com/unparamrepro as module name
package main

import "fmt"

type widget struct{ n int }

type recorder struct{ entries []string }

func run(f func()) { f() }

func main() {
	// "result 1 (*example.com/unparamrepro.recorder) is never used"
	// Although the doubly-nested closure at the bottom uses it.
	newInstance := func() (*widget, *recorder) {
		return &widget{n: 1}, &recorder{}
	}

	// Deleting either one of the two discarding closures makes the warning disappear.
	run(func() {
		w, _ := newInstance()
		if w == nil {
			fmt.Println("nil widget")
		}
	})

	run(func() {
		w, _ := newInstance()
		if w == nil {
			fmt.Println("nil widget")
		}
	})

	// Removing one nesting level around the use makes the warning disappear as well.
	run(func() {
		run(func() {
			w, r := newInstance()
			if w == nil {
				fmt.Println("nil widget")
			}
			// This is the use that unparam fails to see.
			if len(r.entries) != 0 {
				fmt.Println("unexpected entries:", r.entries)
			}
		})
	})
}

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions