Open
Description
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:
- The validation fails even though the two fixes apply to different code locations (positions 100-105 vs 150-155)
- The current implementation uses only the message string for duplicate detection
- 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:
- Their TextEdit ranges don't overlap
- They target distinct positions
Technical Justification:
- Semantic Correctness: The SuggestedFix documentation doesn't prohibit same-message fixes for different locations
- Practical Need: Real-world analyzers like go vet need this for multi-location corrections (e.g., multiple %v→%w replacements in one diagnostic)
- 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
}
}