diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-09 16:32:03 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-09 16:32:03 +0000 |
commit | 243ba330dd962f2d65cf1c8321e5e7d8ba01f03a (patch) | |
tree | 2c01572399f17d37851f67595e5271b2e25afc14 | |
parent | 99118eeccdf6564876bbe6ec0672b04ffcbe3442 (diff) | |
parent | 6857989f6f5c399857cddd54598eb2c8cb427e26 (diff) |
Merge #6785
6785: Fix "no value set for FileTextQuery(FileId(..))" r=jonas-schievink a=jonas-schievink
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6622
Let's hope I got it right this time, but I feel like I slowly begin to understand the main loop logic.
bors r+
Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r-- | crates/rust-analyzer/src/cli/load_cargo.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 16 | ||||
-rw-r--r-- | crates/vfs/src/lib.rs | 9 |
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 a3be579a7..9cf2afd33 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs | |||
@@ -103,18 +103,19 @@ impl Vfs { | |||
103 | (file_id, path) | 103 | (file_id, path) |
104 | }) | 104 | }) |
105 | } | 105 | } |
106 | pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) { | 106 | pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool { |
107 | let file_id = self.alloc_file_id(path); | 107 | let file_id = self.alloc_file_id(path); |
108 | let change_kind = match (&self.get(file_id), &contents) { | 108 | let change_kind = match (&self.get(file_id), &contents) { |
109 | (None, None) => return, | 109 | (None, None) => return false, |
110 | (None, Some(_)) => ChangeKind::Create, | 110 | (None, Some(_)) => ChangeKind::Create, |
111 | (Some(_), None) => ChangeKind::Delete, | 111 | (Some(_), None) => ChangeKind::Delete, |
112 | (Some(old), Some(new)) if old == new => return, | 112 | (Some(old), Some(new)) if old == new => return false, |
113 | (Some(_), Some(_)) => ChangeKind::Modify, | 113 | (Some(_), Some(_)) => ChangeKind::Modify, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | *self.get_mut(file_id) = contents; | 116 | *self.get_mut(file_id) = contents; |
117 | self.changes.push(ChangedFile { file_id, change_kind }) | 117 | self.changes.push(ChangedFile { file_id, change_kind }); |
118 | true | ||
118 | } | 119 | } |
119 | pub fn has_changes(&self) -> bool { | 120 | pub fn has_changes(&self) -> bool { |
120 | !self.changes.is_empty() | 121 | !self.changes.is_empty() |