Skip to content

Commit 1379c52

Browse files
committed
Only check if a document has been modified while loading diagnostics during publishDiagnostics
I was seeing some of these errors in VS Code, which uses the pull diagnostics request even though I couldn’t see any concurrent modifications to the document. Move the check up to `publishDiagnostics`, where it belongs, and log the version of the old and new document version so we can investiage what’s causing the issue.
1 parent 015e486 commit 1379c52

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

Sources/SourceKitLSP/Swift/DiagnosticReportManager.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,6 @@ actor DiagnosticReportManager {
110110
let dict = try await self.sourcekitd.send(skreq, fileContents: snapshot.text)
111111

112112
try Task.checkCancellation()
113-
guard (try? documentManager.latestSnapshot(snapshot.uri).id) == snapshot.id else {
114-
// Check that the document wasn't modified while we were getting diagnostics. This could happen because we are
115-
// calling `fullDocumentDiagnosticReport` from `publishDiagnosticsIfNeeded` outside of `messageHandlingQueue`
116-
// and thus a concurrent edit is possible while we are waiting for the sourcekitd request to return a result.
117-
throw ResponseError.unknown("Document was modified while loading diagnostics")
118-
}
119113

120114
let diagnostics: [Diagnostic] =
121115
dict[keys.diagnostics]?.compactMap({ diag in

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,20 @@ extension SwiftLanguageServer {
417417
for: snapshot,
418418
buildSettings: buildSettings
419419
)
420+
let latestSnapshotID = try? await documentManager.latestSnapshot(snapshot.uri).id
421+
if latestSnapshotID != snapshot.id {
422+
// Check that the document wasn't modified while we were getting diagnostics. This could happen because we are
423+
// calling `publishDiagnosticsIfNeeded` outside of `messageHandlingQueue` and thus a concurrent edit is
424+
// possible while we are waiting for the sourcekitd request to return a result.
425+
logger.log(
426+
"""
427+
Document was modified while loading diagnostics. \
428+
Loaded diagnostics for \(snapshot.id.version, privacy: .public), \
429+
latest snapshot is \((latestSnapshotID?.version).map(String.init) ?? "<nil>", privacy: .public)
430+
"""
431+
)
432+
throw CancellationError()
433+
}
420434

421435
await sourceKitServer.sendNotificationToClient(
422436
PublishDiagnosticsNotification(

0 commit comments

Comments
 (0)