aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/main_loop.rs16
-rw-r--r--crates/vfs/src/lib.rs9
3 files changed, 19 insertions, 8 deletions
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index d51f4a93a..e5ab6c73b 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -73,7 +73,7 @@ fn load(
73 } 73 }
74 vfs::loader::Message::Loaded { files } => { 74 vfs::loader::Message::Loaded { files } => {
75 for (path, contents) in files { 75 for (path, contents) in files {
76 vfs.set_file_contents(path.into(), contents) 76 vfs.set_file_contents(path.into(), contents);
77 } 77 }
78 } 78 }
79 } 79 }
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 95be2ebd3..d7f8374af 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -255,7 +255,7 @@ impl GlobalState {
255 for (path, contents) in files { 255 for (path, contents) in files {
256 let path = VfsPath::from(path); 256 let path = VfsPath::from(path);
257 if !self.mem_docs.contains_key(&path) { 257 if !self.mem_docs.contains_key(&path) {
258 vfs.set_file_contents(path, contents) 258 vfs.set_file_contents(path, contents);
259 } 259 }
260 } 260 }
261 } 261 }
@@ -503,11 +503,21 @@ impl GlobalState {
503 { 503 {
504 log::error!("duplicate DidOpenTextDocument: {}", path) 504 log::error!("duplicate DidOpenTextDocument: {}", path)
505 } 505 }
506 this.vfs 506 let changed = this
507 .vfs
507 .write() 508 .write()
508 .0 509 .0
509 .set_file_contents(path, Some(params.text_document.text.into_bytes())); 510 .set_file_contents(path, Some(params.text_document.text.into_bytes()));
510 this.maybe_update_diagnostics(); 511
512 // If the VFS contents are unchanged, update diagnostics, since `handle_event`
513 // won't see any changes. This avoids missing diagnostics when opening a file.
514 //
515 // If the file *was* changed, `handle_event` will already recompute and send
516 // diagnostics. We can't do it here, since the *current* file contents might be
517 // unset in salsa, since the VFS change hasn't been applied to the database yet.
518 if !changed {
519 this.maybe_update_diagnostics();
520 }
511 } 521 }
512 Ok(()) 522 Ok(())
513 })? 523 })?
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs
index cdf6f1fd0..a2c6a3400 100644
--- a/crates/vfs/src/lib.rs
+++ b/crates/vfs/src/lib.rs
@@ -99,18 +99,19 @@ impl Vfs {
99 (file_id, path) 99 (file_id, path)
100 }) 100 })
101 } 101 }
102 pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) { 102 pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
103 let file_id = self.alloc_file_id(path); 103 let file_id = self.alloc_file_id(path);
104 let change_kind = match (&self.get(file_id), &contents) { 104 let change_kind = match (&self.get(file_id), &contents) {
105 (None, None) => return, 105 (None, None) => return false,
106 (None, Some(_)) => ChangeKind::Create, 106 (None, Some(_)) => ChangeKind::Create,
107 (Some(_), None) => ChangeKind::Delete, 107 (Some(_), None) => ChangeKind::Delete,
108 (Some(old), Some(new)) if old == new => return, 108 (Some(old), Some(new)) if old == new => return false,
109 (Some(_), Some(_)) => ChangeKind::Modify, 109 (Some(_), Some(_)) => ChangeKind::Modify,
110 }; 110 };
111 111
112 *self.get_mut(file_id) = contents; 112 *self.get_mut(file_id) = contents;
113 self.changes.push(ChangedFile { file_id, change_kind }) 113 self.changes.push(ChangedFile { file_id, change_kind });
114 true
114 } 115 }
115 pub fn has_changes(&self) -> bool { 116 pub fn has_changes(&self) -> bool {
116 !self.changes.is_empty() 117 !self.changes.is_empty()