Skip to content

Commit 4e31bde

Browse files
committed
internal/lsp/cache: avoid panic in mod diags with redundant requires
modfile.File.SetRequire panics on duplicate requires with conflicting versions. Avoid the panic by returning an error in this case. Skip directness diagnostics that run into this error, rather than invalidating all diagnostics. Fixes golang/go#50425 Change-Id: Ic6379ecc48581e7fd7b470ed295e449833c351dd Reviewed-on: https://go-review.googlesource.com/c/tools/+/376394 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent a222cdb commit 4e31bde

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

internal/lsp/cache/mod_tidy.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,11 @@ func modTidyDiagnostics(ctx context.Context, snapshot source.Snapshot, pm *sourc
212212
// vice versa.
213213
srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.View().Options().ComputeEdits)
214214
if err != nil {
215-
return nil, err
215+
// We're probably in a bad state if we can't compute a
216+
// directnessDiagnostic, but try to keep going so as to not suppress
217+
// other, valid diagnostics.
218+
event.Error(ctx, "computing directness diagnostic", err)
219+
continue
216220
}
217221
diagnostics = append(diagnostics, srcDiag)
218222
}
@@ -428,7 +432,14 @@ func switchDirectness(req *modfile.Require, m *protocol.ColumnMapper, computeEdi
428432
// Change the directness in the matching require statement. To avoid
429433
// reordering the require statements, rewrite all of them.
430434
var requires []*modfile.Require
435+
seenVersions := make(map[string]string)
431436
for _, r := range copied.Require {
437+
if seen := seenVersions[r.Mod.Path]; seen != "" && seen != r.Mod.Version {
438+
// Avoid a panic in SetRequire below, which panics on conflicting
439+
// versions.
440+
return nil, fmt.Errorf("%q has conflicting versions: %q and %q", r.Mod.Path, seen, r.Mod.Version)
441+
}
442+
seenVersions[r.Mod.Path] = r.Mod.Version
432443
if r.Mod.Path == req.Mod.Path {
433444
requires = append(requires, &modfile.Require{
434445
Mod: r.Mod,

0 commit comments

Comments
 (0)