Skip to content

x/tools/internal/analysisinternal: document need for alternative SuggestedFixes to have distinct Messages #72105

Open
@yuhua2000

Description

@yuhua2000

Go version

go version go1.22.0 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHEPROG=''
GODEBUG=''
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3973945400=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPRIVATE=''
GOPROXY='https://goproxy.cn,direct'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOVCS=''
GOVERSION='go1.24.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Invoked analysisutil.ValidateFixes with ‌multiple non-overlapping SuggestedFix entries sharing identical messages but distinct code positions‌, triggering a false validation error.

‌Validation Logic‌: ValidateFixes

func ValidateFixes(fset *token.FileSet, a *analysis.Analyzer, fixes []analysis.SuggestedFix) error {
	fixMessages := make(map[string]bool)
	for i := range fixes {
		fix := &fixes[i]
		if fixMessages[fix.Message] {
			return fmt.Errorf("analyzer %q suggests two fixes with same Message (%s)", a.Name, fix.Message)
		}
		fixMessages[fix.Message] = true
		if err := validateFix(fset, fix); err != nil {
			return fmt.Errorf("analyzer %q suggests invalid fix (%s): %v", a.Name, fix.Message, err)
		}
	}
	return nil
}

Trigger Condition‌:

SuggestedFix{
    Message:   "Fix example",  // Same message
    TextEdits: []TextEdit{{Pos: 100, End: 105}},  // Position A
},
SuggestedFix{
    Message:   "Fix example",  // Same message
    TextEdits: []TextEdit{{Pos: 200, End: 205}},  // Position B (non-overlapping)
}

Observed Error:

analyzer "demo" suggests two fixes with same Message ("Fix example")

What did you see happen?

Actual Output:‌

analyzer "demo" suggests two fixes with same Message (“Fix example”)

Key Observations:‌

  1. The validation fails even though the two fixes apply to different code locations (positions 100-105 vs 150-155)
  2. The current implementation uses only the message string for duplicate detection
  3. Legitimate multi-location fixes (common in bulk codebase repairs) get incorrectly blocked

What did you expect to see?

‌Expected Behavior:‌

Validation should accept multiple fixes with identical messages when:

  1. Their TextEdit ranges don't overlap
  2. ‌They target distinct positions

Technical Justification:‌

  1. Semantic Correctness:‌ The SuggestedFix documentation doesn't prohibit same-message fixes for different locations‌
  2. Practical Need:‌ Real-world analyzers like go vet need this for multi-location corrections (e.g., multiple %v→%w replacements in one diagnostic)‌
  3. Safety Preservation:‌ The existing position validation (validateFix) already prevents overlapping editsProposed Fix:‌
// Modified validation logic pseudocode
fixKeys := make(map[string]bool)
for _, fix := range fixes {
	for _, edit := range fix.TextEdits {
		key := fmt.Sprintf("%s-%d-%d", fix.Message, edit.Pos, edit.End)
		if fixKeys[key] {
			return error
		}
		fixKeys[key] = true
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.DocumentationIssues describing a change to documentation.NeedsFixThe path to resolution is known, but the work has not been done.ToolsThis label describes issues relating to any tools in the x/tools repository.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions