@@ -210,7 +210,7 @@ impl GlobalState {
210
210
let vfs = & mut self . vfs . write ( ) . 0 ;
211
211
for ( path, contents) in files {
212
212
let path = VfsPath :: from ( path) ;
213
- if !self . mem_docs . contains ( & path) {
213
+ if !self . mem_docs . contains_key ( & path) {
214
214
vfs. set_file_contents ( path, contents)
215
215
}
216
216
}
@@ -299,7 +299,7 @@ impl GlobalState {
299
299
if self . status == Status :: Ready && ( state_changed || prev_status == Status :: Loading ) {
300
300
let subscriptions = self
301
301
. mem_docs
302
- . iter ( )
302
+ . keys ( )
303
303
. map ( |path| self . vfs . read ( ) . 0 . file_id ( & path) . unwrap ( ) )
304
304
. collect :: < Vec < _ > > ( ) ;
305
305
@@ -310,8 +310,12 @@ impl GlobalState {
310
310
for file_id in diagnostic_changes {
311
311
let url = file_id_to_url ( & self . vfs . read ( ) . 0 , file_id) ;
312
312
let diagnostics = self . diagnostics . diagnostics_for ( file_id) . cloned ( ) . collect ( ) ;
313
+ let version = from_proto:: vfs_path ( & url)
314
+ . map ( |path| self . mem_docs . get ( & path) . copied ( ) . flatten ( ) )
315
+ . unwrap_or_default ( ) ;
316
+
313
317
self . send_notification :: < lsp_types:: notification:: PublishDiagnostics > (
314
- lsp_types:: PublishDiagnosticsParams { uri : url, diagnostics, version : None } ,
318
+ lsp_types:: PublishDiagnosticsParams { uri : url, diagnostics, version } ,
315
319
) ;
316
320
}
317
321
}
@@ -400,7 +404,11 @@ impl GlobalState {
400
404
} ) ?
401
405
. on :: < lsp_types:: notification:: DidOpenTextDocument > ( |this, params| {
402
406
if let Ok ( path) = from_proto:: vfs_path ( & params. text_document . uri ) {
403
- if !this. mem_docs . insert ( path. clone ( ) ) {
407
+ if this
408
+ . mem_docs
409
+ . insert ( path. clone ( ) , Some ( params. text_document . version ) )
410
+ . is_some ( )
411
+ {
404
412
log:: error!( "duplicate DidOpenTextDocument: {}" , path)
405
413
}
406
414
this. vfs
@@ -412,29 +420,38 @@ impl GlobalState {
412
420
} ) ?
413
421
. on :: < lsp_types:: notification:: DidChangeTextDocument > ( |this, params| {
414
422
if let Ok ( path) = from_proto:: vfs_path ( & params. text_document . uri ) {
415
- assert ! ( this. mem_docs. contains ( & path) ) ;
423
+ * this. mem_docs . get_mut ( & path) . unwrap ( ) = params . text_document . version ;
416
424
let vfs = & mut this. vfs . write ( ) . 0 ;
417
425
let file_id = vfs. file_id ( & path) . unwrap ( ) ;
418
426
let mut text = String :: from_utf8 ( vfs. file_contents ( file_id) . to_vec ( ) ) . unwrap ( ) ;
419
427
apply_document_changes ( & mut text, params. content_changes ) ;
420
- vfs. set_file_contents ( path, Some ( text. into_bytes ( ) ) )
428
+ vfs. set_file_contents ( path. clone ( ) , Some ( text. into_bytes ( ) ) ) ;
429
+
430
+ this. mem_docs . insert ( path, params. text_document . version ) ;
421
431
}
422
432
Ok ( ( ) )
423
433
} ) ?
424
434
. on :: < lsp_types:: notification:: DidCloseTextDocument > ( |this, params| {
435
+ let mut version = None ;
425
436
if let Ok ( path) = from_proto:: vfs_path ( & params. text_document . uri ) {
426
- if !this. mem_docs . remove ( & path) {
427
- log:: error!( "orphan DidCloseTextDocument: {}" , path)
437
+ match this. mem_docs . remove ( & path) {
438
+ Some ( entry) => version = entry,
439
+ None => log:: error!( "orphan DidCloseTextDocument: {}" , path) ,
428
440
}
441
+
429
442
if let Some ( path) = path. as_path ( ) {
430
443
this. loader . handle . invalidate ( path. to_path_buf ( ) ) ;
431
444
}
432
445
}
446
+
447
+ // Clear the diagnostics for the previously known version of the file.
448
+ // This prevents stale "cargo check" diagnostics if the file is
449
+ // closed, "cargo check" is run and then the file is reopened.
433
450
this. send_notification :: < lsp_types:: notification:: PublishDiagnostics > (
434
451
lsp_types:: PublishDiagnosticsParams {
435
452
uri : params. text_document . uri ,
436
453
diagnostics : Vec :: new ( ) ,
437
- version : None ,
454
+ version,
438
455
} ,
439
456
) ;
440
457
Ok ( ( ) )
0 commit comments