Skip to content

cmd/fix: go fix inline producing conflicting var names #78432

@thaJeztah

Description

@thaJeztah

Go version

go version go1.26.1 darwin/arm64

Output of go env in your module/workspace:

not relevant

What did you do?

🙈 writing an example to show //go:fix inline and seeing that it ... didn't work as planned

Using this file;

package foo

type Opt func()

func WithFoo(any) Opt { return func() {} }
func WithBar(any) Opt { return func() {} }
func WithBaz(any) Opt { return func() {} }

//go:fix inline
func OldFunc1(one string, two int, three int, opts ...Opt) {
	opts = append([]Opt{WithFoo(two), WithBar(three)}, opts...)
	NewFunc(one, opts...)
}

//go:fix inline
func OldFunc2(one string, two int, three int, opts ...Opt) {
	opts = append(opts, WithFoo(two), WithBar(three))
	NewFunc(one, opts...)
}

//go:fix inline
func OldFunc3(one string, two int, three int, opts ...Opt) {
	opt := append(opts, WithFoo(two), WithBar(three))
	NewFunc(one, opt...)
}

//go:fix inline
func OldFunc4(one string, two int, three int, opts ...Opt) {
	opt := append(opts, WithFoo(two), WithBar(three))
	NewFunc(one, opt...)
}

//go:fix inline
func OldFunc5(one string, two int, three int, opts ...Opt) {
	NewFunc(one, append(opts, WithFoo(two), WithBar(three))...)
}

func NewFunc(one string, opts ...Opt) {}

func Something() {
	OldFunc1("hello", 1, 2, WithBaz("world"))
	OldFunc2("hello", 1, 2, WithBaz("world"))
	OldFunc3("hello", 1, 2, WithBaz("world"))
	OldFunc4("hello", 1, 2, WithBaz("world"))
	OldFunc5("hello", 1, 2, WithBaz("world"))
}

What did you see happen?

Running go fix . correctly inlines the code, but doesn't account for conflicting variable names;

package foo

// omitted for brevity

func Something() {
	var opts []Opt = []Opt{WithBaz("world")}
	opts = append([]Opt{WithFoo(1), WithBar(2)}, opts...)
	NewFunc("hello", opts...)
	var opts []Opt = []Opt{WithBaz("world")}
	opts = append(opts, WithFoo(1), WithBar(2))
	NewFunc("hello", opts...)
	opt := append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))
	NewFunc("hello", opt...)
	opt := append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))
	NewFunc("hello", opt...)
	NewFunc("hello", append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))...)
}

What did you expect to see?

I expected it to detect the conflict and either bail out, or enumerate variables to assign unique names;

package foo

// omitted for brevity

func Something() {
	var opts []Opt = []Opt{WithBaz("world")}
	opts = append([]Opt{WithFoo(1), WithBar(2)}, opts...)
	NewFunc("hello", opts...)
	var optsb []Opt = []Opt{WithBaz("world")}
	optsb = append(optsb, WithFoo(1), WithBar(2))
	NewFunc("hello", optsb...)
	opt := append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))
	NewFunc("hello", opt...)
	optb := append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))
	NewFunc("hello", optb...)
	NewFunc("hello", append([]Opt{WithBaz("world")}, WithFoo(1), WithBar(2))...)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions