@@ -560,6 +560,49 @@ impl GlobalState {
560
560
fn send ( & self , message : lsp_server:: Message ) {
561
561
self . sender . send ( message) . unwrap ( )
562
562
}
563
+
564
+ pub ( crate ) fn publish_diagnostics (
565
+ & mut self ,
566
+ uri : Url ,
567
+ version : Option < i32 > ,
568
+ mut diagnostics : Vec < lsp_types:: Diagnostic > ,
569
+ ) {
570
+ // We put this on a separate thread to avoid blocking the main thread with serialization work
571
+ self . task_pool . handle . spawn_with_sender ( stdx:: thread:: ThreadIntent :: Worker , {
572
+ let sender = self . sender . clone ( ) ;
573
+ move |_| {
574
+ // VSCode assumes diagnostic messages to be non-empty strings, so we need to patch
575
+ // empty diagnostics. Neither the docs of VSCode nor the LSP spec say whether
576
+ // diagnostic messages are actually allowed to be empty or not and patching this
577
+ // in the VSCode client does not work as the assertion happens in the protocol
578
+ // conversion. So this hack is here to stay, and will be considered a hack
579
+ // until the LSP decides to state that empty messages are allowed.
580
+
581
+ // See https://github.com/rust-lang/rust-analyzer/issues/11404
582
+ // See https://github.com/rust-lang/rust-analyzer/issues/13130
583
+ let patch_empty = |message : & mut String | {
584
+ if message. is_empty ( ) {
585
+ " " . clone_into ( message) ;
586
+ }
587
+ } ;
588
+
589
+ for d in & mut diagnostics {
590
+ patch_empty ( & mut d. message ) ;
591
+ if let Some ( dri) = & mut d. related_information {
592
+ for dri in dri {
593
+ patch_empty ( & mut dri. message ) ;
594
+ }
595
+ }
596
+ }
597
+
598
+ let not = lsp_server:: Notification :: new (
599
+ <lsp_types:: notification:: PublishDiagnostics as lsp_types:: notification:: Notification >:: METHOD . to_owned ( ) ,
600
+ lsp_types:: PublishDiagnosticsParams { uri, diagnostics, version } ,
601
+ ) ;
602
+ _ = sender. send ( not. into ( ) ) ;
603
+ }
604
+ } ) ;
605
+ }
563
606
}
564
607
565
608
impl Drop for GlobalState {
0 commit comments