[tools] gopls/internal/cache: discard fixes that touch generated files

4 views
Skip to first unread message

Alan Donovan (Gerrit)

unread,
Nov 11, 2025, 1:58:51 PM (2 days ago) Nov 11
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Alan Donovan has uploaded the change for review

Commit message

gopls/internal/cache: discard fixes that touch generated files

This is the gopls counterpart of CL 718505 to the other drivers.

+ integration test and marker test (long story).

Fixes golang/go#75948
Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33

Change diff

diff --git a/gopls/internal/cache/analysis.go b/gopls/internal/cache/analysis.go
index 93df623..2b39fc9 100644
--- a/gopls/internal/cache/analysis.go
+++ b/gopls/internal/cache/analysis.go
@@ -1016,12 +1016,21 @@
factFilter[reflect.TypeOf(f)] = true
}

+ // Tabulate generated files.
+ fset := apkg.pkg.FileSet()
+ generated := make(map[*token.File]bool)
+ for _, file := range apkg.files {
+ if ast.IsGenerated(file) {
+ generated[fset.File(file.Pos())] = true
+ }
+ }
+
// Now run the (pkg, analyzer) action.
var diagnostics []gobDiagnostic

pass := &analysis.Pass{
Analyzer: analyzer,
- Fset: apkg.pkg.FileSet(),
+ Fset: fset,
Files: apkg.files,
OtherFiles: nil, // since gopls doesn't handle non-Go (e.g. asm) files
IgnoredFiles: nil, // zero-config gopls should analyze these files in another view
@@ -1036,10 +1045,21 @@
// ValidateFixes allows a fix.End to be slightly beyond
// EOF to avoid spurious assertions when reporting
// fixes as the end of truncated files; see #71659.
- if err := driverutil.ValidateFixes(apkg.pkg.FileSet(), analyzer, d.SuggestedFixes); err != nil {
+ if err := driverutil.ValidateFixes(fset, analyzer, d.SuggestedFixes); err != nil {
bug.Reportf("invalid SuggestedFixes: %v", err)
d.SuggestedFixes = nil
}
+
+ // Discard fixes that include edits to generated files (#75948).
+ d.SuggestedFixes = slices.DeleteFunc(d.SuggestedFixes, func(fix analysis.SuggestedFix) bool {
+ for _, edit := range fix.TextEdits {
+ if generated[fset.File(edit.Pos)] {
+ return true
+ }
+ }
+ return false
+ })
+
diagnostic, err := toGobDiagnostic(apkg.pkg, analyzer, d)
if err != nil {
// Don't bug.Report here: these errors all originate in
diff --git a/gopls/internal/cache/diagnostics.go b/gopls/internal/cache/diagnostics.go
index 05ff75c..5c8284f 100644
--- a/gopls/internal/cache/diagnostics.go
+++ b/gopls/internal/cache/diagnostics.go
@@ -96,9 +96,11 @@
return hash
}

+// ToProtocolDiagnostics converts Diagnostics to LSP form.
+// Beware: only command-based fixes are preserved; edit-based fixes are discarded!
func ToProtocolDiagnostics(diagnostics ...*Diagnostic) []protocol.Diagnostic {
// TODO(rfindley): support bundling edits, and bundle all suggested fixes here.
- // (see cache.bundleLazyFixes).
+ // (see [bundleLazyFixes]).

reports := []protocol.Diagnostic{}
for _, diag := range diagnostics {
diff --git a/gopls/internal/test/integration/misc/fix_test.go b/gopls/internal/test/integration/misc/fix_test.go
index 261b584..442b574 100644
--- a/gopls/internal/test/integration/misc/fix_test.go
+++ b/gopls/internal/test/integration/misc/fix_test.go
@@ -161,3 +161,55 @@
// yay, no panic
})
}
+
+func TestNoFixesInGeneratedFiles(t *testing.T) {
+ // (see issue #75948)
+ const src = `
+-- go.mod --
+module example.com
+go 1.21
+
+-- a/a1.go --
+package a
+
+var _ interface{}
+
+-- a/a2.go --
+// Code generated by hand. DO NOT EDIT.
+
+package a
+
+var _ interface{}
+`
+ Run(t, src, func(t *testing.T, env *Env) {
+ for _, test := range []struct {
+ filename string
+ wantFixes int
+ }{
+ {"a/a1.go", 1},
+ {"a/a2.go", 0},
+ } {
+ env.OpenFile(test.filename)
+
+ // Expect a diagnostic from the 'any' modernizer.
+ var d protocol.PublishDiagnosticsParams
+ env.AfterChange(
+ Diagnostics(
+ env.AtRegexp(test.filename, `interface{}`),
+ WithMessage("interface{} can be replaced by any")),
+ ReadDiagnostics(test.filename, &d),
+ )
+
+ // The diagnostic should carry a fix unless the file is generated.
+ var quickFixes []*protocol.CodeAction
+ for _, act := range env.CodeActionForFile(test.filename, d.Diagnostics) {
+ if act.Kind == protocol.QuickFix {
+ quickFixes = append(quickFixes, &act)
+ }
+ }
+ if len(quickFixes) != test.wantFixes {
+ t.Fatalf("got %d quickfixes, want %d", len(quickFixes), test.wantFixes)
+ }
+ }
+ })
+}

Change information

Files:
  • M gopls/internal/cache/analysis.go
  • M gopls/internal/cache/diagnostics.go
  • M gopls/internal/test/integration/misc/fix_test.go
Change size: M
Delta: 3 files changed, 77 insertions(+), 3 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
Gerrit-Change-Number: 719720
Gerrit-PatchSet: 1
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Nov 11, 2025, 1:59:04 PM (2 days ago) Nov 11
to goph...@pubsubhelper.golang.org, Robert Findley, Go LUCI, golang-co...@googlegroups.com
Attention needed from Robert Findley

Alan Donovan voted Auto-Submit+1

Auto-Submit+1
Open in Gerrit

Related details

Attention is currently required from:
  • Robert Findley
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
Gerrit-Change-Number: 719720
Gerrit-PatchSet: 1
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Attention: Robert Findley <rfin...@google.com>
Gerrit-Comment-Date: Tue, 11 Nov 2025 18:59:01 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Nov 11, 2025, 1:59:25 PM (2 days ago) Nov 11
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Alan Donovan and Robert Findley

Alan Donovan uploaded new patchset

Alan Donovan uploaded patch set #2 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
  • Robert Findley
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newpatchset
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
Gerrit-Change-Number: 719720
Gerrit-PatchSet: 2
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
Gerrit-Attention: Robert Findley <rfin...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Robert Findley (Gerrit)

unread,
Nov 11, 2025, 4:52:42 PM (2 days ago) Nov 11
to Alan Donovan, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
Attention needed from Alan Donovan

Robert Findley added 1 comment

Patchset-level comments
File-level comment, Patchset 2 (Latest):
Robert Findley . unresolved

Sorry, I didn't understand the goal when we discussed earlier.

Why do we want to discard *fixes* in an interactive environment? Doesn't the user ultimately decide whether to apply a fix?

I thought we'd suppress the analyses altogether.

Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
    Gerrit-Change-Number: 719720
    Gerrit-PatchSet: 2
    Gerrit-Owner: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Robert Findley <rfin...@google.com>
    Gerrit-Attention: Alan Donovan <adon...@google.com>
    Gerrit-Comment-Date: Tue, 11 Nov 2025 21:52:37 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Alan Donovan (Gerrit)

    unread,
    Nov 11, 2025, 10:29:13 PM (2 days ago) Nov 11
    to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
    Attention needed from Robert Findley

    Alan Donovan added 1 comment

    Patchset-level comments
    Robert Findley . unresolved

    Sorry, I didn't understand the goal when we discussed earlier.

    Why do we want to discard *fixes* in an interactive environment? Doesn't the user ultimately decide whether to apply a fix?

    I thought we'd suppress the analyses altogether.

    Alan Donovan

    Why do we want to discard fixes in an interactive environment?


    Doesn't the user ultimately decide whether to apply a fix?

    Yes, the user decides, so we could leave things as is, though it may be a distracting nuisance to be offered fixes in generated code. There may also be some marginal value in consistency across drivers, but I agree that the interactive setting is potentially significantly different.


    > I thought we'd suppress the analyses altogether.

    Do you here mean: suppress these analyzer's diagnostics in generated files? There may be value in knowing that the generated code is suboptimal. Of course, the action in that case is not to apply the fix, but to fix the generator. If the diagnostic is only hint-level, it may not be worth the effort, but that's why hint-level diagnostics are pretty discrete even for ordinary hand-written source.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Robert Findley
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
    Gerrit-Change-Number: 719720
    Gerrit-PatchSet: 2
    Gerrit-Owner: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Robert Findley <rfin...@google.com>
    Gerrit-Attention: Robert Findley <rfin...@google.com>
    Gerrit-Comment-Date: Wed, 12 Nov 2025 03:29:07 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Robert Findley <rfin...@google.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Robert Findley (Gerrit)

    unread,
    Nov 12, 2025, 3:42:19 PM (11 hours ago) Nov 12
    to Alan Donovan, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
    Attention needed from Alan Donovan

    Robert Findley added 1 comment

    Patchset-level comments
    Robert Findley . unresolved

    Sorry, I didn't understand the goal when we discussed earlier.

    Why do we want to discard *fixes* in an interactive environment? Doesn't the user ultimately decide whether to apply a fix?

    I thought we'd suppress the analyses altogether.

    Alan Donovan

    Why do we want to discard fixes in an interactive environment?
    Doesn't the user ultimately decide whether to apply a fix?

    Yes, the user decides, so we could leave things as is, though it may be a distracting nuisance to be offered fixes in generated code. There may also be some marginal value in consistency across drivers, but I agree that the interactive setting is potentially significantly different.

    > I thought we'd suppress the analyses altogether.

    Do you here mean: suppress these analyzer's diagnostics in generated files? There may be value in knowing that the generated code is suboptimal. Of course, the action in that case is not to apply the fix, but to fix the generator. If the diagnostic is only hint-level, it may not be worth the effort, but that's why hint-level diagnostics are pretty discrete even for ordinary hand-written source.

    Robert Findley

    I don't see any value in suppressing the fix if we're showing the diagnostic. The fix is ~0 cost in the UI.

    Perhaps we should suppress diagnostics in generated files unless they're open (IIRC, we already do this for 'hint' level diagnostics).

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Alan Donovan
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
    Gerrit-Change-Number: 719720
    Gerrit-PatchSet: 2
    Gerrit-Owner: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Robert Findley <rfin...@google.com>
    Gerrit-Attention: Alan Donovan <adon...@google.com>
    Gerrit-Comment-Date: Wed, 12 Nov 2025 20:42:15 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alan Donovan <adon...@google.com>
    Comment-In-Reply-To: Robert Findley <rfin...@google.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Alan Donovan (Gerrit)

    unread,
    Nov 12, 2025, 4:26:28 PM (10 hours ago) Nov 12
    to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com
    Attention needed from Robert Findley

    Alan Donovan added 1 comment

    Patchset-level comments
    Robert Findley . resolved

    Sorry, I didn't understand the goal when we discussed earlier.

    Why do we want to discard *fixes* in an interactive environment? Doesn't the user ultimately decide whether to apply a fix?

    I thought we'd suppress the analyses altogether.

    Alan Donovan

    Why do we want to discard fixes in an interactive environment?
    Doesn't the user ultimately decide whether to apply a fix?

    Yes, the user decides, so we could leave things as is, though it may be a distracting nuisance to be offered fixes in generated code. There may also be some marginal value in consistency across drivers, but I agree that the interactive setting is potentially significantly different.

    > I thought we'd suppress the analyses altogether.

    Do you here mean: suppress these analyzer's diagnostics in generated files? There may be value in knowing that the generated code is suboptimal. Of course, the action in that case is not to apply the fix, but to fix the generator. If the diagnostic is only hint-level, it may not be worth the effort, but that's why hint-level diagnostics are pretty discrete even for ordinary hand-written source.

    Robert Findley

    I don't see any value in suppressing the fix if we're showing the diagnostic. The fix is ~0 cost in the UI.

    Perhaps we should suppress diagnostics in generated files unless they're open (IIRC, we already do this for 'hint' level diagnostics).

    Alan Donovan

    I don't see any value in suppressing the fix if we're showing the diagnostic. The fix is ~0 cost in the UI.

    I was vaguely thinking about what might happen if the CLI was used to apply a batch of fixes en masse, but that's not a supported interface.

    Perhaps we should suppress diagnostics in generated files unless they're open.

    This issue was about discarding fixes, not suppressing diagnostics. As you point out, we already make hint-level diagnostics very subtle, and I don't see any reason not to keep displaying them even in generated files (so that you can opt to fix the generator if you wish).

    I'll revert the change.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Robert Findley
    Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: I142f76c7aa41e53927942158dc287f9b4d0ceb33
      Gerrit-Change-Number: 719720
      Gerrit-PatchSet: 2
      Gerrit-Owner: Alan Donovan <adon...@google.com>
      Gerrit-Reviewer: Alan Donovan <adon...@google.com>
      Gerrit-Reviewer: Robert Findley <rfin...@google.com>
      Gerrit-Attention: Robert Findley <rfin...@google.com>
      Gerrit-Comment-Date: Wed, 12 Nov 2025 21:26:23 +0000
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy

      Alan Donovan (Gerrit)

      unread,
      Nov 12, 2025, 4:26:44 PM (10 hours ago) Nov 12
      to goph...@pubsubhelper.golang.org, Go LUCI, Robert Findley, golang-co...@googlegroups.com

      Alan Donovan abandoned this change

      Related details

      Attention set is empty
      Submit Requirements:
      • requirement is not satisfiedCode-Review
      • requirement satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      • requirement satisfiedTryBots-Pass
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: abandon
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy
      Reply all
      Reply to author
      Forward
      0 new messages